# 
# archive-cache-revision.sh - store a revision in whole-source form
################################################################
# Copyright (C) 2001, 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 "cache a full source tree in an archive\\n"
                printf "usage: archive-cache-revision [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 "Extract REVISION from an archive, creating a scratch project tree.\\n"
                printf "Create a tar file of the project tree tree and store that back\\n"
                printf "on the archive.  This speeds up subsequent check-outs of that revision.\\n"
                printf "\\n"
                printf "If REVISION is not specified, but the command is run from within\\n"
                printf "a project tree, cache the latest revision in the default version\\n"
                printf "of that tree.\\n"
                printf "\\n"
                printf "Also see \"larch archive-uncache-revision --help\"\\n"
                printf "\\n"
                exit 0
                ;;

      *)
                ;;
    esac
  done
fi

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

archroot=
archive=
cache_dir=

__restart=

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

while test $# -ne 0 ; do

  case "$1" in 

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

    --no-lint)  shift
                no_lint=--no-lint
                ;;

    --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 "archive-cache-revision: debugging output enabled\\n"
                set -x
                debug_opt=--debug
                ;;


    -R|--root)          shift
                        if test $# -eq 0 ; then
                          printf "archive-cache-revision: -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 "archive-cache-revision: -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 "archive-cache-revision: --cache requires an argument\\n" 1>&2
                          printf "try --help\\n" 1>&2
                          exit 1
                        fi
                        cache_dir="$1"
                        shift
                        ;;

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

    *)                  break
                        ;;
  esac

done



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

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

if test $# -ne 0 ; then
  rvnspec="$1"
  shift
else
  rvsnspec=
fi


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

here="`pwd`"
tmpdir="$here/,,cache-revision.$$/"

if test -z "$cache_dir" ; then
  if larch tree-root > /dev/null 2>&1 ; then
    wdroot="`larch tree-root`"
    cache_dir="`dirname \"$wdroot\"`"
  else
    cache_dir="$here"
  fi
fi

if test -z "$rvnspec" ; then
  rvnspec="`larch tree-version`"
fi

larch valid-package-name --tolerant "$rvnspec"

archive="`larch parse-package-name -R \"$archroot\" -A \"$archive\" --arch \"$rvnspec\"`"
revision_spec="`larch parse-package-name -R \"$archroot\" -A \"$archive\" --non-arch \"$rvnspec\"`"

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

if test "(" -z "$__restart" -a ! -z "$quiet" ")" -o ! -z "$report" ; then
  larch heading "archive-cache-revision\\n"
  printf "arguments: %s\\n"  "$command_line" | fold -w 60 | larch body-indent
  larch heading --sub "archive-cache-revision start time: %s\\n" "`date`"
  larch heading --sub "archive: %s\\n" "$archive"
  larch heading --sub "revision spec: %s\\n" "$revision_spec"
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 archive-cache-revision --cache "$cache_dir" \
                                    $silent_opt $quiet_opt $report_opt $verbose_opt $debug_opt \
                                    ----restart \
                                    "$archive/$revision_spec"

fi

################################################################
# Which Revision are We Caching?
# 

archive_revision="`larch indicated-revision -e archive-cache-revision \"$archive/$revision_spec\"`"
revision="`larch parse-package-name --non-arch \"$archive_revision\"`"

if test ! -z "$quiet" ; then
  larch heading --sub "revision: %s\\n" "$revision" 
fi

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

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

trap "printf \"archive-cache-revision: interrupted -- cleaning up\\n\" 1>&2 ; bail" INT

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



################################################################
# Get the Revision
# 

if test ! -z "$quiet" ; then
  larch heading --sub "getting a pristine copy of the revision\\n"
fi

cd "$tmpdir"
mkdir ,,pristine
cd ,,pristine

if ! larch nested --sub \
        larch build-revision --cache "$cache_dir" \
                            $silent_opt $quiet_opt $report_opt $verbose_opt $debug_opt \
                            "$archive/$revision" \
; then
  printf "archive-cache-revision: unable to get revision\\n" 1>&2
  printf "  archive: %s\\n" "$archive" 1>&2
  printf "  revision: %s\\n" "$revision" 1>&2
  printf "\\n"
  bail
fi

cd "$tmpdir"
mv ,,pristine "$revision"

################################################################
# Make a Tar File of the Revision
# 

if test ! -z "$quiet" ; then
  larch heading --sub "creating tar file of revision\\n" 
fi

cd "$tmpdir"
tar -zcf "$revision.tar.gz" "$revision"

################################################################
# Store it In the Archive
# 

category=`larch parse-package-name --basename $revision`
branch=`larch parse-package-name --package $revision`
vsn=`larch parse-package-name --vsn $revision`
lvl=`larch parse-package-name --lvl $revision`

wftp-home
wftp-cd $category/$branch/$branch--$vsn/$lvl

archtmp=",,cache.`larch my-id -u`"

bail2()
{
  wftp-delete $archtmp || true
  bail
}

if test ! -z "$quiet" ; then
  larch heading --sub "transfering tar file to archive\\n" 
fi

if ! wftp-put $archtmp < $revision.tar.gz ; then

  printf "archive-cache-revision: error writing to archive\\n" 1>&2
  printf "\\n" 1>&2
  bail2

fi

wftp-delete $revision.tar.gz 2> /dev/null || true

if ! wftp-rename $archtmp $revision.tar.gz ; then

  printf "archive-cache-revision: error installing on archive\\n" 1>&2
  printf "\\n" 1>&2
  bail2

fi

if test ! -z "$quiet" ; then
  larch heading --sub "cached version installed...cleaning up\\n" 
fi

cd "$here"
rm -rf "$tmpdir"

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


exit 0
