chiark / gitweb /
@@ -1,3 +1,10 @@ debian_version_4_0_99_0_12
authorianmdlvl <ianmdlvl>
Fri, 31 Dec 2004 15:50:48 +0000 (15:50 +0000)
committerianmdlvl <ianmdlvl>
Fri, 31 Dec 2004 15:50:48 +0000 (15:50 +0000)
+chiark-utils (4.0.99.0.12) unstable; urgency=low
+
+  * New `cvs-adjustroot' and `cvs-repomove' scripts (no documentation).
+  * Mention cvs-* and palm-datebook-reminders in debian/control.
+
+ -- Ian Jackson <ian@davenant.greenend.org.uk>  Fri, 31 Dec 2004 15:50:44 +0000
+
 chiark-utils (4.0.99.0.10) unstable; urgency=low

   * New `random-word' script (no documentation).

debian/changelog
debian/control
scripts/Makefile
scripts/cvs-adjustroot [new file with mode: 0755]
scripts/cvs-repomove [new file with mode: 0755]

index 4772eb9b5167359da780e7a15309778e8babde43..5dd01bd54aa99bc069d39e66322634f7b5d84b29 100644 (file)
@@ -1,3 +1,10 @@
+chiark-utils (4.0.99.0.12) unstable; urgency=low
+
+  * New `cvs-adjustroot' and `cvs-repomove' scripts (no documentation).
+  * Mention cvs-* and palm-datebook-reminders in debian/control.
+
+ -- Ian Jackson <ian@davenant.greenend.org.uk>  Fri, 31 Dec 2004 15:50:44 +0000
+
 chiark-utils (4.0.99.0.10) unstable; urgency=low
 
   * New `random-word' script (no documentation).
index 21fdbb1f56663685595bcc8e0364b4195c46433b..5d9214e67654eb7c17ce11c4da223b782eba66b5 100644 (file)
@@ -40,6 +40,12 @@ Description: chiark system administration scripts
  systems and installing it locally.  It is flexible and reasonably
  straightforward, but lacks integration with other distributed
  databases such as NIS.
+ .
+ cvs-repomove and cvs-adjustroot: tools for moving CVS repositories
+ and adjusting working trees.
+ .
+ palm-datebook-reminders: a program which emails mails you reminders
+ about the appointments in your Palm's Datebook.
 
 Package: chiark-rwbuffer
 Section: utils
index a3d371f0f09c3765dacc3272afd0ca6487c8fe16..41d1d89f7010cbc1af2a5bd1d7d85b96ca1e60d8 100644 (file)
@@ -22,7 +22,8 @@
 include ../settings.make
 
 SCRIPTS=       palm-datebook-reminders random-word \
-               genspic2gnuplot gnucap2genspic ngspice2genspic
+               genspic2gnuplot gnucap2genspic ngspice2genspic \
+               cvs-repomove cvs-adjustroot
 MANPAGES1=     palm-datebook-reminders
 
 CSCRIPTS=      named-conf
diff --git a/scripts/cvs-adjustroot b/scripts/cvs-adjustroot
new file mode 100755 (executable)
index 0000000..5418f1c
--- /dev/null
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+set -e
+
+usage () { echo >&2 'usage: cvs-adjustroot OLD NEW'; exit 1; }
+
+case "$#.$1" in
+4.--reinvoke)  reinvoke=true; shift    ;;
+*.-*)          usage                   ;;
+2.*)           reinvoke=false          ;;
+1.*)           usage                   ;;
+0.*)           usage                   ;;
+*)             usage                   ;;
+esac
+
+old="$1"; shift
+new="$1"; shift
+
+if $reinvoke; then
+       filename="$1";
+       cmp -- "$filename" <(printf "%s\n" "$old")
+       printf "%s\n" "$new" >"$filename".new
+       mv -f -- "$filename".new "$filename"
+       exit 0
+fi
+
+find -path '*/CVS/Root' -exec cvs-adjustroot --reinvoke "$old" "$new" '{}' ';'
diff --git a/scripts/cvs-repomove b/scripts/cvs-repomove
new file mode 100755 (executable)
index 0000000..a0890af
--- /dev/null
@@ -0,0 +1,229 @@
+#!/bin/bash
+set -e
+print_usage () { cat <<'END'
+usage:
+  in repository directory
+    cvs-repomove --move local-repo module hostname remote-repo
+  in working directory
+    cvs-repomove                automatically update **/CVS/Root
+END
+}
+
+# We do things in the following order:
+#                                              src             dst
+#  0. Check things                             @/..moving-to   none/..moved-to
+#  1. Rename src repo to prevent commits etc.  ..moving-to     none/..moved-to
+#  2. Make temporary copy at destination       ..moving-to     ..tmp
+#  3. Install temporary copy at destination    ..moving-to     @
+#  4. Move aside src repo                      ..moved-to      @
+
+fail () { echo >&2 "error: $1"; exit 8; }
+bad_usage () { echo >&2 "bad usage: $1"; print_usage >&2; exit 12; }
+
+move=false
+
+while [ $# -gt 0 ]; do
+       case "$1" in
+       --move)         move=true ;;
+       --help)         print_usage; exit 0 ;;
+       --)             ;;
+       -*)             bad_usage "unknown option $1" ;;
+       *)              break ;;
+       esac
+       shift
+done
+
+mn () { echo " $1"; }
+
+check_module () {
+       case "$module" in
+       *..*)           fail \
+ "moving a module with \`..' in its name is not supported" ;;
+       */*)            fail \
+ "moving a subdirectory is not supported" ;;
+       -*)             fail \
+ "moving a module whose name starts with \`-' is not supported" ;;
+       esac
+}
+
+check_remote_host () {
+       case "$1" in
+       /*|.*|-*)       fail "bad hostname $dsthost" ;;
+       esac
+}
+
+check_remote_path () {
+       case "$1" in
+       *[^0-9a-zA-Z/._+,-]*) fail \
+               "remote pathname may not contain metacharacters, sorry" ;;
+       esac
+}
+
+do_move () {
+       check_module
+       check_remote_host "$dsthost"
+       check_remote_path "$dstrepo/$module"
+
+       case "$dstrepo" in
+       /*)     ;;
+       *)      bad_usage "destination repo path must be absolute" ;;
+       esac
+
+       printf "moving module %s from %s to %s:%s\n" \
+               "$module" "$srcrepo" "$dsthost" "$dstrepo"
+
+       mn "checking existing repository"
+       ls -d -- "$srcrepo/CVSROOT" >/dev/null
+
+       dstrepotrans="$(printf "%s" "$dstrepo" | tr / :)"
+       movingto="moving-to-$dsthost:$dstrepotrans"
+       if test -d "$srcrepo/$module..$movingto"; then
+               echo "    resuming previous attempt at a move"
+               resume=true
+               if test -d "$srcrepo/$module"; then
+                       fail "but $srcrepo/$module exists too"
+               fi
+       else
+               resume=false
+               ls -d -- "$srcrepo/$module" >/dev/null
+       fi
+
+       set +e
+       previously="$(ls -d -- "$srcrepo/$module..moved-to-"* 2>/dev/null)"
+       set -e
+       if [ "x$previously" != x ]; then
+               echo "    btw, module was once before moved away from here"
+               mv -- "$previously" \
+ "${previously/..moved-to-/..previously-$(date +%s)-moved-to-}"
+       fi
+
+       mn "checking dst repository"
+       "$CVS_RSH" "$dsthost" bash -ec "'
+               cd $dstrepo
+               ls -d CVSROOT >/dev/null
+               if test -d $dstrepo/$module; then
+                       echo >&2 module already exists in destination repo
+                       exit 1
+               fi
+               for f in $module..*; do
+ case \"\$f\" in
+ *..moved-to-*) echo \"    btw, module was previously at destn repo\" ;;
+ *..previously-*) ;;
+ *..tmp-*) echo \"    nb: possibly-stale temp/partial copy \$f\" ;;
+ *..\*) ;;
+ *) echo >&2 \"error: found unexpected subdir \$f\"; exit 8;;
+ esac
+               done
+       '"
+
+       if ! $resume; then
+               mv -- "$srcrepo/$module" "$srcrepo/$module..$movingto"
+       fi
+
+       mn "transferring repo data"
+       tmpid="tmp-$(uname -n).$(date +%s)"
+       tar -c -C "$srcrepo/$module..$movingto" -f - . | \
+        "$CVS_RSH" "$dsthost" bash -ec "'
+               cd $dstrepo
+               mkdir $module..$tmpid
+               cd $module..$tmpid
+               tar --no-same-owner -xf -
+       '"
+       test "${PIPESTATUS[*]}" = "0 0"
+
+       mn "confirming move at destination repo"
+       "$CVS_RSH" "$dsthost" bash -ec "'
+               cd $dstrepo
+               mv $module..$tmpid $module
+       '"
+
+       mn "confirming move at local repo"
+       mv -- "$srcrepo/$module..$movingto" \
+               "$srcrepo/$module..moved-to-$dsthost:$dstrepotrans"
+       echo "module moved successfully"
+}
+
+compute_fqdn_data () {
+       fqdn_data="$(adnshost -s - "$1" 2>/dev/null || true)"
+}
+
+do_furtle () {
+       module="$(cat CVS/Repository)"
+       oldroot="$(cat CVS/Root)"
+       goose="$oldroot"
+       check_module
+       printf "checking/updating repo for %s\n" "$module"
+       compute_fqdn_data "$(uname -n)"
+       our_fqdn_data="$fqdn_data"
+       searching=true
+       while $searching; do
+               mn "chasing geese at $goose"
+               case "$goose" in
+               *[0-9a-zA-Z]:/*)
+                       remotehost="${goose%%:*}"
+                       path="${goose#*:}"
+                       check_remote_host "$remotehost"
+                       check_remote_path "$remotepath/$module"
+                       isremote=true
+                       compute_fqdn_data "$remotehost"
+                       if [ "x$fqdn_data" = "x$our_fqdn_data" -a \
+                               "x$fqdn_data" != x ]; then
+                               isremote=false
+                               goose="$path"
+                       fi
+                       ;;
+               *:*)
+                       fail "unknown remote repository string $goose"
+                       ;;
+               /*)
+                       isremote=false
+                       path="$goose"
+                       ;;
+               *)
+                       fail "unknown repository string $goose"
+                       ;;
+               esac
+               check="
+ cd $path
+ if test -d $module; then echo good; exit 0; fi
+ if ls -d $module..moved-to-* 2>/dev/null; then exit 0; fi
+ echo bad
+"
+               if $isremote; then
+                       new_goose_info="$("$CVS_RSH" "$remotehost" \
+                                       bash -ec "'$check'")"
+               else
+                       new_goose_info="$(      bash -ec "$check")"
+               fi
+               case "$new_goose_info" in
+               good)
+                       searching=false
+                       ;;
+               bad)
+                       echo >&2 "trail went cold at $goose"
+                       exit 4
+                       ;;
+               *..moved-to-*)
+                       goose="$(printf "%s" \
+                               "${new_goose_info#*..moved-to-}" | \
+                               tr : / | sed -e 's,/,:,')"
+                       ;;
+               esac
+       done
+       if [ "x$goose" = "x$oldroot" ]; then
+               echo 'repo has not moved - nothing to do'
+               exit 0
+       fi
+       mn "found new repo, adjusting working tree"
+       cvs-adjustroot "$oldroot" "$goose"
+       echo 'working tree adjustment completed'
+}
+
+if $move; then
+       [ "$#" = 4 ] || bad_usage "--move needs hostname and path"
+       srcrepo="$1"; module="$2"; dsthost="$3"; dstrepo="$4"
+       do_move
+else
+       [ "$#" = 0 ] || bad_usage "without --move, give no arguments"
+       do_furtle
+fi