#!/bin/sh
# tla-copy-changes -- Copy and commit arch changesets from another branch
# Usage: tla-copy-changes [OPTION...] SOURCE_VERSION_OR_REVISION...
#
#  Copyright (C) 2003, 2004  Miles Bader <miles@gnu.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Written by Miles Bader <miles@gnu.org>
#
#-
#       --skip-present  Skip changesets containing any patch logs already
#                       present in this tree
#
#   -A, --archive       Override `my-default-archive'
#   -d, --dir DIR       Use project tree in DIR
#
#   -h, --help          Display a help message and exit
#   -V, --version       Display a release identifier string and exit
#
# If SOURCE_VERSION_OR_REVISION is a version, find all changesets in it
# that aren't present in the current project tree, and apply them
# one-by-one, committing them as they are applied.
# 
# If SOURCE_VERSION_OR_REVISION is a revision, then simply apply it, and
# commit it with an appropriate log message.
# 
# Multiple arguments are applied sequentially (until one fails).
# 
# The log-message used for each commit is that of the source changeset,
# so except for the patch-log information, it's as if the changes
# happened in the current version.  Before commiting, the log message is
# placed into a normal tla log file (generated via `tla make-log'), so
# if commiting fails, the commit may be continued by simply using `tla
# commit' once the problems are fixed.
# 
# The project tree is used as a staging area for applying the changes, and
# so must be unmodified when this command is run.

# (---- beginning of hdr.shpp ----)
# hdr.shpp

me=`basename $0`

bindir='/usr/bin'
AWK='/usr/bin/nawk'; export AWK
TLA='tla'; export TLA
SED='/bin/sed'; export SED
UUIDGEN='uuidgen'; export UUIDGEN

# (---- TLA_TOOLS_VERSION defined from ,tla-tools-version ----)
TLA_TOOLS_VERSION='srivasta@debian.org--etch/tla-tools--devo--0--patch-4
'
# (---- end of TLA_TOOLS_VERSION defined from ,tla-tools-version ----)

TLA_TOOL_PFX="${bindir+$bindir/}"
export TLA_TOOL_PFX

TLA_ESCAPE='yes'

if test "$TLA_ESCAPE" = yes; then
  TLA_UNESCAPED_OPT='--unescaped'
else
  TLA_UNESCAPED_OPT=''
fi

# Some tools get completely confused in stupid ways by non-default
# settings of LANG (like gawk, which fucks up regexp character ranges).
LANG=C; export LANG

# (---- end of hdr.shpp ----)
# (---- beginning of cmd-line.shpp ----)
# cmd-line.shpp -- Command-line helper functions for shell scripts

script="$0"
case "$script" in
  */*) ;;
  *)   script="${TLA_TOOL_PFX}$script";;
esac

usage ()
{
  $SED -n -e '/^\([^#]\|#-* *$\)/{s@.*@Usage: '"$me"' [--help|--version]@p;q;}'	\
         -e '/^# *Usage:/,/^# *$/{s/^# //p;q;}'				\
     < "$script"
}

short_help ()
{
  $SED -n -e '/^\([^#]\|-*# *$\|# *Usage:\)/q'				\
	 -e '/^#!/d;s/^.*-- */# /;s/^#[ 	]*//p'			\
     < "$script" | fmt
}

help_body ()
{
  $SED -n '/^ *$/q;/^#-/,/^[^#]/s/^#\( \|$\)//p' < "$script"
}

help ()
{
  usage
  short_help
  echo ''
  help_body
}

version ()
{
  local no_nl_vers=`echo "$TLA_TOOLS_VERSION"`
  echo "$me (tla-tools) $no_nl_vers"
  $SED -n '/^[^#]/q;/^#-/q;s/^# *\(Written by\)/\
\1/p' < "$script"
  $SED -n '/^[^#]/q;/^#-/q;s/^# *\(Copyright\)/\
\1/p' < "$script"
}

unrec_opt ()
{
  echo 1>&2 "$me: unrecognized option "\`"$1'"
  echo 1>&2 "Try "\`"$me --help' for more information."
}

cmd_line_err ()
{
  usage 1>&2
  echo 1>&2 "Try "\`"$me --help' for more information."
}

long_opt_val ()
{
  echo "$1" | $SED 's/^[^=]*=//'
}

short_opt_val ()
{
  echo "$1" | $SED 's/^-.//'
}

# (---- end of cmd-line.shpp ----)

DIR='.'
DEFAULT_ARCHIVE=''

REPLAY_VERSION_OPTS=''

# Parse command-line options
while :; do
  case "$1" in
    --skip-present)
      REPLAY_VERSION_OPTS="$REPLAY_VERSION_OPTS $1"; shift;;
    -A|--archive)
      DEFAULT_ARCHIVE="$2"; shift 2;;
    --archive=*)
      DEFAULT_ARCHIVE=`long_opt_val "$1"`; shift;;
    -A*)
      DEFAULT_ARCHIVE=`short_opt_val "$1"`; shift;;
    -d|--dir)
      DIR="$2"; shift 2;;
    --dir=*)
      DIR=`long_opt_val "$1"`; shift;;
    -d*)
      DIR=`short_opt_val "$1"`; shift;;
    --help|-h|-H)
      help; exit 0;;
    --version|-V)
      version; exit 0;;
    -[!-]?*)
      # split concatenated single-letter options apart
      FIRST="$1"; shift
      set -- `echo $FIRST | $SED 's/-\(.\)\(.*\)/-\1 -\2/'` "$@"
      ;;
    -*)
      unrec_opt "$1"; exit 1;;
    *)
      break;
  esac
done

test $# -gt 0 || { cmd_line_err; exit 1; }

$TLA changes -q -d"$DIR" || { echo 1>&2 "$me: Uncommitted changes in $DIR"; exit 2; }

CUR_VERSION=`$TLA tree-version "$DIR"`

if test x"$DEFAULT_ARCHIVE" = x; then
  DEFAULT_ARCHIVE=`echo "$CUR_VERSION" | $SED 's@/.*@@'`
fi

# We ignore the possibility of an existing log file, as we know there
# are no source changes in the tree.
LOG=`$TLA make-log 2>/dev/null`
rm -f "$LOG"

TMP_PFX="/tmp/,,tla-copy-changes.$$"
TMP_MISSING="$TMP_PFX.missing"
trap "rm -f $TMP_PFX* \"$LOG.orig\"" 0 1 2 3 11 15

# sed script to turn old log into new one
LOG_FILTER='/^Summary:/p;/^Keywords: *[^ ].*/p;/^$/,$p'

copy ()
{
  echo "* copying changeset $1"

  $TLA replay -A"$DEFAULT_ARCHIVE" -d"$DIR" "$1"
  replay_status=$?

  $TLA cat-log -A"$DEFAULT_ARCHIVE" -d"$DIR" "$1" > "$LOG.orig" || exit 4
  $SED -n "$LOG_FILTER" < "$LOG.orig" > "$LOG"

  test $replay_status = 0 || exit 3

  echo "* committing changeset"
  $TLA commit -d"$DIR" || exit 5
}

for SOURCE_VERSION_OR_REVISION; do
  case "$SOURCE_VERSION_OR_REVISION" in
    *--*--*--*)
      # revision
      copy "$SOURCE_VERSION_OR_REVISION"
      ;;
    *--*--*)
      # version
      if $TLA missing -f $REPLAY_VERSION_OPTS		\
	              -A"$DEFAULT_ARCHIVE" -d"$DIR"	\
		      "$SOURCE_VERSION_OR_REVISION" > "$TMP_MISSING"
      then
	while read REV; do
	  case "$REV" in
	    */*--*--*--*patch-*)
	      # Only apply patches
	      copy "$REV"
	  esac
	done < "$TMP_MISSING"
      fi
      ;;
    *)
      echo 1>&2 "$me: $SOURCE_VERSION_OR_REVISION: invalid version/revision"
      exit 7
  esac
done

