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).
 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.
  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
 
 Package: chiark-rwbuffer
 Section: utils
index a3d371f0f09c3765dacc3272afd0ca6487c8fe16..41d1d89f7010cbc1af2a5bd1d7d85b96ca1e60d8 100644 (file)
@@ -22,7 +22,8 @@
 include ../settings.make
 
 SCRIPTS=       palm-datebook-reminders random-word \
 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
 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