histedit: move all arguments checks to the beginning of the command
authorPierre-Yves David <pierre-yves.david@logilab.fr>
Tue, 16 Apr 2013 21:17:13 +0200
changeset 19020 12c06686d371
parent 19019 53060cc1b601
child 19021 26b41a902195
histedit: move all arguments checks to the beginning of the command This changeset move all checks and raises related to arguments validation to the top of the file. This gathers all the logic in one place and clarifies the code doing actual work. This paves the way for splitting this gigantic function in separated functions. A `goal` variable is introduced in the process. It holds the action to be done by this invocation (new, continue or abort). An invalid invocation is found in the process (the new code is a bit stricter).
hgext/histedit.py
tests/test-histedit-non-commute.t
--- a/hgext/histedit.py	Tue Apr 16 21:57:25 2013 -0500
+++ b/hgext/histedit.py	Tue Apr 16 21:17:13 2013 +0200
@@ -428,7 +428,7 @@
       _('force outgoing even for unrelated repositories')),
      ('r', 'rev', [], _('first revision to be edited'))],
      _("[PARENT]"))
-def histedit(ui, repo, *parent, **opts):
+def histedit(ui, repo, *freeargs, **opts):
     """interactively edit changeset history
     """
     # TODO only abort if we try and histedit mq patches, not just
@@ -437,13 +437,43 @@
     if mq and mq.applied:
         raise util.Abort(_('source has mq patches applied'))
 
-    parent = list(parent) + opts.get('rev', [])
+    # basic argument incompatibility processing
+    outg = opts.get('outgoing')
+    cont = opts.get('continue')
+    abort = opts.get('abort')
+    force = opts.get('force')
+    rules = opts.get('commands', '')
+    revs = opts.get('rev', [])
+    goal = 'new' # This invocation goal, in new, continue, abort
+    if force and not outg:
+        raise util.Abort(_('--force only allowed with --outgoing'))
+    if cont:
+        if util.any((outg, abort, revs, freeargs, rules)):
+            raise util.Abort(_('no arguments allowed with --continue'))
+        goal = 'continue'
+    elif abort:
+        if util.any((outg, revs, freeargs, rules)):
+            raise util.Abort(_('no arguments allowed with --abort'))
+        goal = 'abort'
+    else:
+        if os.path.exists(os.path.join(repo.path, 'histedit-state')):
+            raise util.Abort(_('history edit already in progress, try '
+                               '--continue or --abort'))
+        if outg:
+            if revs:
+                raise util.Abort(_('no revisions allowed with --outgoing'))
+            if len(freeargs) > 1:
+                raise util.Abort(
+                    _('only one repo argument allowed with --outgoing'))
+        else:
+            parent = list(freeargs) + opts.get('rev', [])
+            if len(parent) != 1:
+                raise util.Abort(
+                    _('histedit requires exactly one parent revision'))
+
     if opts.get('outgoing'):
-        if len(parent) > 1:
-            raise util.Abort(
-                _('only one repo argument allowed with --outgoing'))
-        elif parent:
-            parent = parent[0]
+        if freeargs:
+            parent = freeargs[0]
 
         dest = ui.expandpath(parent or 'default-push', parent or 'default')
         dest, revs = hg.parseurl(dest, None)[:2]
@@ -460,22 +490,17 @@
         # contains special revset characters like ":" the revset
         # parser can choke.
         parent = [node.hex(n) for n in discovery.findcommonoutgoing(
-            repo, other, revs, force=opts.get('force')).missing[0:1]]
-    else:
-        if opts.get('force'):
-            raise util.Abort(_('--force only allowed with --outgoing'))
+            repo, other, revs, force=force).missing[0:1]]
+        if not parent:
+            raise util.Abort(_('no outgoing ancestors'))
 
-    if opts.get('continue', False):
-        if len(parent) != 0:
-            raise util.Abort(_('no arguments allowed with --continue'))
+    if goal == 'continue':
         (parentctxnode, rules, keep, topmost, replacements) = readstate(repo)
         currentparent, wantnull = repo.dirstate.parents()
         parentctx = repo[parentctxnode]
         parentctx, repl = bootstrapcontinue(ui, repo, parentctx, rules, opts)
         replacements.extend(repl)
-    elif opts.get('abort', False):
-        if len(parent) != 0:
-            raise util.Abort(_('no arguments allowed with --abort'))
+    elif goal == 'abort':
         (parentctxnode, rules, keep, topmost, replacements) = readstate(repo)
         mapping, tmpnodes, leafs, _ntm = processreplacement(repo, replacements)
         ui.debug('restore wc to old parent %s\n' % node.short(topmost))
@@ -486,14 +511,9 @@
         return
     else:
         cmdutil.bailifchanged(repo)
-        if os.path.exists(os.path.join(repo.path, 'histedit-state')):
-            raise util.Abort(_('history edit already in progress, try '
-                               '--continue or --abort'))
 
         topmost, empty = repo.dirstate.parents()
 
-        if len(parent) != 1:
-            raise util.Abort(_('histedit requires exactly one parent revision'))
         parent = scmutil.revsingle(repo, parent[0]).node()
 
         keep = opts.get('keep', False)
@@ -503,7 +523,6 @@
                              node.short(parent))
 
         ctxs = [repo[r] for r in revs]
-        rules = opts.get('commands', '')
         if not rules:
             rules = '\n'.join([makedesc(c) for c in ctxs])
             rules += '\n\n'
--- a/tests/test-histedit-non-commute.t	Tue Apr 16 21:57:25 2013 -0500
+++ b/tests/test-histedit-non-commute.t	Tue Apr 16 21:17:13 2013 +0200
@@ -240,7 +240,7 @@
 
   $ echo 'I can haz no commute' > e
   $ hg resolve --mark e
-  $ hg histedit --commands $EDITED --continue 2>&1 | fixbundle
+  $ hg histedit --continue 2>&1 | fixbundle
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   merging e
   warning: conflicts during merge.