# library-add.sh: add a revision to a revision library
# 
################################################################
# Copyright (C) 2002 Tom Lord
# 
# See the file "COPYING" for further information about
# the copyright and warranty status of this work.
# 

set -e 
command_line="$*"

################################################################
# special options
# 
# Some options are special:
# 
#       --version | -V
#       --help | -h
# 
if test $# -ne 0 ; then

  for opt in "$@" ; do
    case $opt in

      --version|-V) exec larch --version
                    ;;


      --help|-h)
                printf "add a revision to a revision library\\n"
                printf "usage: library-add [options] [archive/]revision\\n"
                printf "\\n"
                printf " -V --version                  print version info\\n"
                printf " -h --help                     display help\\n"
                printf "\\n"
                printf " -R --root root                specify the local archive root\\n"
                printf " -A --archive archive          specify the archive name\\n"
                printf "  --cache DIR                  cache directory for locally cached\\n"
                printf "                                 revisions\\n"
                printf "\\n"
                printf " --silent                      no output (except odd errors)\\n"
                printf " --quiet                       brief output\\n"
                printf " --report                      default output\\n"
                printf " --verbose                     maximal output\\n"
                printf " --debug                       debugging output\\n"
                printf "\\n"
                printf " --ignore-extra-args           ignore extra argyments\\n"
                printf " --skip-readmes                don't update readme files\\n"
                printf "\\n"
                printf "Add REVISION to your revision library.  This recursively\\n"
                printf "adds all direct ancestor revisions from the same archive.\\n"
                printf "\\n"
                printf "This command has no effect and exits with status 0 if the\\n"
                printf "indicated revision is already in the library.\\n"
                printf "\\n"
                printf "The flag \"--ignore-extra-args\" makes this command\\n"
                printf "especially useful as an \"larch notify\" action for\\n"
                printf "new revisions.\\n"
                printf "\\n"
                exit 0
                ;;

      *)
                ;;
    esac
  done
fi

################################################################
# Ordinary Options
# 
# 

skip_readmes=

archroot=
archive=
cache_dir=
ignore_extra_args=

quiet=--quiet
report=--report
verbose=
silent_opt=
quiet_opt=
report_opt=
verbose_opt=
debug_opt=
__restart=

while test $# -ne 0 ; do

  case "$1" in 

    --skip-readmes)             shift
                                skip_readmes=--skip-readmes
                                ;;

    --ignore-extra-args)        shift
                                ignore_extra_args=--ignore-extra-args
                                ;;

    ----restart) shift
                __restart=----restart
                ;;


    --silent)   shift
                quiet=
                report=
                verbose=
                silent_opt=--silent
                quiet_opt=
                report_opt=
                verbose_opt=
                ;;

    --quiet)    shift
                quiet=--quiet
                report=
                verbose=
                silent_opt=
                quiet_opt=--quiet
                report_opt=
                verbose_opt=
                ;;

    --report)   shift
                quiet=--quiet
                report=--report
                verbose=
                silent_opt=
                quiet_opt=
                report_opt=--report
                verbose_opt=
                ;;

    --verbose)  shift
                quiet=--quiet
                report=--report
                verbose=--verbose
                silent_opt=
                quiet_opt=
                report_opt=
                verbose_opt=--verbose
                ;;

    --debug)    shift
                larch heading "library-add: debugging output enabled\\n"
                set -x
                debug_opt=--debug
                ;;


    -R|--root)          shift
                        if test $# -eq 0 ; then
                          printf "library-add: -R and --root require an argument\\n" 1>&2
                          printf "try --help\\n" 1>&2
                          exit 1
                        fi
                        archroot="$1"
                        shift
                        ;;

    -A|--archive)       shift
                        if test $# -eq 0 ; then
                          printf "library-add: -A and --archive require an argument\\n" 1>&2
                          printf "try --help\\n" 1>&2
                          exit 1
                        fi
                        archive="$1"
                        shift
                        ;;

    --cache)            shift
                        if test $# -eq 0 ; then
                          printf "library-add: --cache requires an argument\\n" 1>&2
                          printf "try --help\\n" 1>&2
                          exit 1
                        fi
                        cache_dir="$1"
                        shift
                        ;;

    -*)                 printf "library-add: unrecognized option (%s)\\n" "$1" 1>&2
                        printf "try --help\\n" 1>&2
                        exit 1
                        ;;

    *)                  break
                        ;;
  esac

done



################################################################
# Ordinary Arguments
# 

if test -z "$ignore_extra_args" ; then
  cmp=-ne
else
  cmp=-lt
fi

if test $# $cmp 1 ; then
  printf "usage: library-add [options] [archive/]revision\\n" 1>&2
  printf "try --help\\n" 1>&2
  exit 1
fi

rvnspec="$1"
shift

################################################################
# Sanity Check and Process Defaults
# 

library="`larch my-revision-library -e library-add`"

archive_revision=`larch indicated-revision -e library-add -R "$archroot" -A "$archive" "$rvnspec"`

archive=${archive_revision%%/*}
revision=${archive_revision#*/}
category="`larch parse-package-name --basename \"$revision\"`"
branch="`larch parse-package-name \"$revision\"`"
version="`larch parse-package-name --package-version \"$revision\"`"
lvl="`larch parse-package-name --lvl \"$revision\"`"

tmpdir="$library/,,library-add.$$/"

if test -z "$cache_dir" ; then
  cache_dir="`pwd`"
fi

  
################################################################
# Greetings
# 

if test "(" -z "$__restart" -a ! -z "$quiet" ")" -o ! -z "$report" ; then
  larch heading "library-add\\n"
  printf "arguments: %s\\n"  "$command_line" | fold -w 60 | larch body-indent
  larch heading --sub "library-add start time: %s\\n" "`date`"
  larch heading --sub "library: %s\\n" "$library"
  larch heading --sub "archive: %s\\n" "$archive"
  larch heading --sub "revision: %s\\n" "$revision"
fi

################################################################
# Is the Revision Already in the Library?
# 

if test -d "$library/$archive/$category/$branch/$version/$revision" ; then

  if test ! -z "$quiet" ; then
    larch heading --sub "revision already in library\\n"
    larch heading --sub "library-add finish time: %s\\n" "`date`"
  fi

  exit 0

fi  


################################################################
# Ensure that We Have an Archive Connection 
# 

if test "$WITHARCHIVE" != "$archive" ; then

  if test ! -z "$quiet" ; then
    larch heading --sub "restarting with connection to archive\\n"
  fi

  exec larch with-archive -A "$archive"  \
        larch library-add --cache "$cache_dir" \
                          $silent_opt $quiet_opt $report_opt $verbose_opt $debug_opt \
                          ----restart \
                          $skip_readmes \
                          $ignore_extra_args \
                          "$archive/$revision"

fi

################################################################
# Make a Temp Dir
# 

bail()
{
  cd "$library"
  rm -rf "$tmpdir"
  exit 1
}

trap "printf \"library-add: interrupted -- cleaning up\\n\" 1>&2 ; bail" INT

rm -rf "$tmpdir"
mkdir "$tmpdir"
cd "$tmpdir"


################################################################
# What is the Previous Revision, If Any??
# 

if test "$lvl" = base-0 ; then

  wftp-home
  wftp-cd "$category/$branch/$version/$lvl"
  rm -f "$tmpdir/,,ls"
  wftp-ls > "$tmpdir/,,ls"

fi

# This bit of awkward code is to work around a bug in some older
# versions of bash.  In particular, ( ! foo ) didn't return the
# correct exit status.
# 

fresh_start=

if test "$lvl" = base-0 ; then
  if ! grep -s -E "^CONTINUATION$" "$tmpdir/,,ls" ; then
    fresh_start=yes
  fi
fi

if test ! -z "$fresh_start" ; then

  rm -f "$tmpdir/,,ls"
  fresh_start=yes

else

  rm -f "$tmpdir/,,ls"
  fresh_start=

  previous_archive_revision="`larch previous-patch-level \"$archive/$revision\"`"

  previous_category="`larch parse-package-name --basename \"$previous_archive_revision\"`"
  previous_branch="`larch parse-package-name \"$previous_archive_revision\"`"
  previous_version="`larch parse-package-name --package-version \"$previous_archive_revision\"`"
  previous_revision="`larch parse-package-name --non-arch \"$previous_archive_revision\"`"

  ################################################################
  # Is the Previous Revision from the Same Archive?
  # 
  # 

  prev_archive="`larch parse-package-name --arch \"$previous_archive_revision\"`"

  if test "$prev_archive" = "$archive" ; then

    prev_same_archive=yes

  else

    prev_same_archive=

  fi

fi

################################################################
# Make the Desired Revision
# 
# Two cases: if the previous revision is already in the library,
# then `copy-file-list --links' that revision and build the
# new revision with `replay'.  Otherwise, build the revision
# in the usual way.
# 
# Either way, ensure that the patch set for this revision is kept
# around.
# 

# after this conditional, the revision is in "$tmpdir/,,rev"
# 
if test -z "$fresh_start" -a "(" ! -z "$prev_same_archive" -o -d "$library/$prev_archive" ")" ; then

  if test ! -z "$quiet" ; then
    larch heading --sub "ensuring that preceeding revsion is in the library\\n"
  fi

  larch nested larch library-add --cache "$cache_dir" \
                    $silent_opt $quiet_opt $report_opt $verbose_opt $debug_opt \
                    ----restart \
                    --skip-readmes \
                    "$previous_archive_revision"

  mkdir "$tmpdir/,,rev"

  if test ! -z "$quiet" ; then
    larch heading --sub "copying preceeding revsion from the library\\n"
  fi

  ( cd "$library/$prev_archive/$previous_category/$previous_branch/$previous_version/$previous_revision" ; \
    find . ) \
  | copy-file-list --links -- -  "$library/$prev_archive/$previous_category/$previous_branch/$previous_version/$previous_revision" "$tmpdir/,,rev"

  cd "$tmpdir/,,rev"

  rm -rf ,,patch-set

  if test ! -z "$quiet" ; then
    larch heading --sub "patching to create new revision\\n"
    larch heading --sub --sub "revision: %s\\n" "$archive/$revision"
  fi

  larch get-patch "$archive/$revision" ,,patch-set

  larch nested larch dopatch --quiet $silent_opt $quiet_opt $report_opt $verbose_opt $debug_opt \
                             --delete-removed \
                             ,,patch-set .


else 

  if test ! -z "$quiet" ; then
    larch heading --sub "building revision from scratch\\n"
  fi

  mkdir "$tmpdir/,,rev"

  cd "$tmpdir/,,rev"

  larch nested larch build-revision --quiet $silent_opt $quiet_opt $report_opt $verbose_opt $debug_opt \
                                    "$archive/$revision"

  if test -z "$fresh_start" ; then
    larch get-patch "$archive/$revision" ,,patch-set
  fi

fi

cd "$tmpdir/,,rev"

mkdir -p ",,patch-set"

larch cat-log "$archive/$revision" > ,,patch-set/=log.txt

if test ! -z "$quiet" ; then
  larch heading --sub "computing index of new revision\\n"
fi

larch set-tree-version "$archive/$version"
rm -f ,,index-by-name
larch inventory --source --all --both --tags > ,,index-by-name
rm -f ,,index
sort -k 2 ,,index-by-name > ,,index


################################################################
# Store the Revision in the Library
# 
# 

if test ! -z "$quiet" ; then
  larch heading --sub "installing new revision in the library\\n"
fi

cd "$library"

mkdir -p "$archive/$category/$branch/$version"

if test -z "$skip_readmes" ; then

  if test ! -z "$quiet" ; then
    larch heading --sub "updating library =README files"
  fi

  cd "$archive"
  larch archive-readme "$archive" > "=README"
  cd "$category"
  larch category-readme "$archive/$category" > "=README"
  cd "$branch"
  larch branch-readme "$archive/$branch" > "=README"
  cd "$version"
  larch version-readme "$archive/$version" > "=README"

fi

cd "$tmpdir"

rm -rf "$library/$archive/$category/$branch/$version/$revision"

set +e
mv ,,rev "$library/$archive/$category/$branch/$version/$revision" 2> /dev/null
set -e

cd ..
rm -rf "$tmpdir"

if test ! -d  "$library/$archive/$category/$branch/$version/$revision" ; then
  printf "\\n" 1>&2
  printf "library-add: unable to install revision in library\\n" 1>&2
  printf "  archive: %s\\n" "$archive" 1>&2
  printf "  revision: %s\\n" "$revision" 1>&2
  printf "\\n" 1>&2
  exit 1
fi


################################################################
# Bye
# 

if test ! -z "$quiet" ; then
  larch heading --sub "library-add finish time: %s\\n" "`date`"
fi

# tag: Tom Lord Sat Jan 19 21:53:29 2002 (library/library-add.sh)
#
