]> scripts.mit.edu Git - wizard.git/commitdiff
Add interactive upgrade mode, suggested by Nelson Elhage.
authorEdward Z. Yang <ezyang@mit.edu>
Tue, 22 Dec 2009 19:53:22 +0000 (14:53 -0500)
committerEdward Z. Yang <ezyang@mit.edu>
Tue, 22 Dec 2009 19:53:22 +0000 (14:53 -0500)
Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
TODO
tests/mediawiki-continue-upgrade-test.sh
tests/mediawiki-interactive-continue-upgrade.sh [new file with mode: 0755]
wizard/command/mass_upgrade.py
wizard/command/upgrade.py

diff --git a/TODO b/TODO
index 5845f56495e83c4a7c144fe7f4ddc4111d2b4809..9b1995765d2ac51d114f5b1d113bdd5b5cdac744 100644 (file)
--- a/TODO
+++ b/TODO
@@ -6,7 +6,10 @@ TODO NOW:
   the sql.cnf file. This sucks.
 - Make an awesome wizard subcommand that you can point at a file that is DOS
   when the source wants it to be UNIX, or the other way around, and it will
-  redo the merge on that file correctly.
+  redo the merge on that file correctly.  Alternatively, just make wizard
+  sufficiently awesome to detect line-ending mismatch and fix it w/o any
+  prompting.
+- Use diff3 conflictstyle
 
 - wizard install wordpress should ask for password.  One problem with this is that
   Wordpress will still send mail with the wrong username and password, so Wordpress
index 3d37a6a50bf4653324c513966bbaaf365b38c820..6c1f7191c5af9ed7b0419a4406b858668f01f455 100755 (executable)
@@ -12,7 +12,7 @@ mv "$TESTDIR/$FROB" "$TESTDIR/$FROB.bak"
 echo "this is a bad file" > "$TESTDIR/$FROB"
 
 # attempt an upgrade, this will fail
-RESULT=`! wizard upgrade "$TESTDIR" --log-file=/tmp/testboo`
+RESULT=`! wizard upgrade "$TESTDIR" --non-interactive`
 TMPTESTDIR=`echo "$RESULT" | awk '{print $2}'`
 
 # resolve the upgrade
diff --git a/tests/mediawiki-interactive-continue-upgrade.sh b/tests/mediawiki-interactive-continue-upgrade.sh
new file mode 100755 (executable)
index 0000000..da432e6
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/bash -e
+cd `dirname $0`
+
+TESTNAME="mediawiki_interactive_continue_upgrade"
+source ./setup
+
+source ./mediawiki-install
+
+# nuke the install
+FROB="RELEASE-NOTES"
+mv "$TESTDIR/$FROB" "$TESTDIR/$FROB.bak"
+echo "this is a bad file" > "$TESTDIR/$FROB"
+
+# attempt upgrade, and kick us in
+wizard upgrade "$TESTDIR"
index 5119eef689f3f892966d74cf5c66812bbe2b3ca3..2d66359131c2983177326cded5ea51cd78b496e6 100644 (file)
@@ -44,6 +44,7 @@ def main(argv, baton):
             # `seen` makes this mostly not a problem
             logging.info("[%04d] Processing %s" % (i, d.location))
             child_args = list(base_args)
+            child.args.append("--non-interactive")
             # calculate the log file, if a log dir was specified
             if options.log_dir:
                 log_file = command.calculate_log_name(options.log_dir, i)
index 2a0e6067c594a83709a5851741066ec401f1d0bc..2dec1475f9e1455916a53abb7e7fdba24af1b28d 100644 (file)
@@ -92,7 +92,8 @@ def main(argv, baton):
                 open(".git/WIZARD_SIZE", "w").write(str(scripts.get_disk_usage()))
                 if options.log_file:
                     open(".git/WIZARD_LOG_FILE", "w").write(options.log_file)
-                perform_merge(sh, repo, d, wc, version, use_shm, kib_limit and kib_limit - kib_usage or None)
+                temp_wc_dir = perform_merge(sh, repo, d, wc, version, use_shm, kib_limit and kib_limit - kib_usage or None, options.non_interactive)
+                wc.location = temp_wc_dir
         # variables: version, user_commit, next_commit, temp_wc_dir
         with util.ChangeDirectory(temp_wc_dir):
             try:
@@ -153,6 +154,8 @@ def main(argv, baton):
     finally:
         if use_shm and temp_dir and os.path.exists(temp_dir):
             shutil.rmtree(temp_dir)
+    if not options.non_interactive:
+        print "Upgrade complete"
 
 def perform_restore(d, backup):
     # You don't want d.restore() because it doesn't perform
@@ -205,7 +208,7 @@ def perform_tmp_clone(sh, use_shm):
     sh.call("git", "clone", "-q", "--shared", ".", temp_wc_dir)
     return temp_dir, temp_wc_dir
 
-def perform_merge(sh, repo, d, wc, version, use_shm, kib_avail):
+def perform_merge(sh, repo, d, wc, version, use_shm, kib_avail, non_interactive):
     # Note: avail_quota == None means unlimited
     # naive merge algorithm:
     # sh.call("git", "merge", "-m", message, "scripts/master")
@@ -247,12 +250,50 @@ def perform_merge(sh, repo, d, wc, version, use_shm, kib_avail):
         if wc.resolveConflicts():
             logging.info("Resolved conflicts with application specific knowledge")
             sh.call("git", "commit", "-a", "-m", "merge")
-            return
+            return os.getcwd()
         # XXX: Maybe should recalculate conflicts
         logging.info("Conflict info:\n" + sh.eval("git", "diff"))
         curdir = mv_shm_to_tmp(curdir, use_shm)
-        print "%d %s" % (conflicts, curdir)
-        raise MergeFailed
+        os.chdir(curdir)
+        open(os.path.join(d.location, ".scripts/pending"), "w").write(curdir)
+        if non_interactive:
+            print "%d %s" % (conflicts, curdir)
+            raise MergeFailed
+        else:
+            user_shell = os.getenv("SHELL")
+            if not user_shell: user_shell = "/bin/bash"
+            while 1:
+                print
+                print "ERROR: The merge failed with %d conflicts in these files:" % conflicts
+                print
+                outlines = sh.eval("git", "ls-files", "--unmerged").splitlines()
+                files = set()
+                for line in outlines:
+                    _, _, _, name = line.split(None, 3)
+                    files.add(name)
+                for file in sorted(files):
+                    print "  * %s" % file
+                print
+                print "Please resolve these conflicts (edit and then `git add`), and"
+                print "then type 'exit'."
+                sh.call(user_shell, "-i", interactive=True)
+                if sh.eval("git", "ls-files", "--unmerged").strip():
+                    print
+                    print "WARNING: There are still unmerged files."
+                    out = raw_input("Continue editing? [y/N]: ")
+                    if out == "y" or out == "Y":
+                        continue
+                    else:
+                        print "Aborting.  The conflicted working copy can be found at:"
+                        print
+                        print "    %s" % os.getcwd()
+                        print
+                        print "and you can resume the upgrade process by running in that directory:"
+                        print
+                        print "    wizard upgrade --continue"
+                        sys.exit(1)
+                break
+    return os.getcwd()
 
 def mv_shm_to_tmp(curdir, use_shm):
     if not use_shm: return curdir
@@ -284,6 +325,8 @@ of the conflicted working tree to stdout, separated by a space."""
             "resolved using the current working directory as the resolved copy.")
     parser.add_option("--force", dest="force", action="store_true",
             default=False, help="Force running upgrade even if it's already at latest version.")
+    parser.add_option("--non-interactive", dest="non_interactive", action="store_true",
+            default=False, help="Don't drop to shell in event of conflict.")
     baton.push(parser, "srv_path")
     options, args = parser.parse_all(argv)
     if len(args) > 1: