fancyopts: Parse options that occur after arguments.
authorAugie Fackler <durin42@gmail.com>
Tue, 10 Feb 2009 13:26:00 -0600
changeset 7772 88887054d277
parent 7771 09d0fe02988d
child 7773 607de5bd3578
fancyopts: Parse options that occur after arguments. This changes the behavior of qguard in the case of setting negative guards, as -- will now always be required. Fixes issue1402. Doc fixes for mq by mpm.
hgext/mq.py
mercurial/dispatch.py
mercurial/fancyopts.py
tests/test-mq-guards
--- a/hgext/mq.py	Tue Feb 10 16:31:52 2009 -0600
+++ b/hgext/mq.py	Tue Feb 10 13:26:00 2009 -0600
@@ -1993,13 +1993,10 @@
 
     With no arguments, print the currently active guards.
     With arguments, set guards for the named patch.
-
-    To set a negative guard "-foo" on topmost patch ("--" is needed so
-    hg will not interpret "-foo" as an option):
-      hg qguard -- -foo
+    NOTE: Specifying negative guards now requires '--'.
 
     To set guards on another patch:
-      hg qguard other.patch +2.6.17 -stable
+      hg qguard -- other.patch +2.6.17 -stable
     '''
     def status(idx):
         guards = q.series_guards[idx] or ['unguarded']
@@ -2499,7 +2496,7 @@
         (guard,
          [('l', 'list', None, _('list all patches and guards')),
           ('n', 'none', None, _('drop all guards'))],
-         _('hg qguard [-l] [-n] [PATCH] [+GUARD]... [-GUARD]...')),
+         _('hg qguard [-l] [-n] -- [PATCH] [+GUARD]... [-GUARD]...')),
     'qheader': (header, [], _('hg qheader [PATCH]')),
     "^qimport":
         (qimport,
--- a/mercurial/dispatch.py	Tue Feb 10 16:31:52 2009 -0600
+++ b/mercurial/dispatch.py	Tue Feb 10 13:26:00 2009 -0600
@@ -184,7 +184,7 @@
         c.append((o[0], o[1], options[o[1]], o[3]))
 
     try:
-        args = fancyopts.fancyopts(args, c, cmdoptions)
+        args = fancyopts.fancyopts(args, c, cmdoptions, True)
     except fancyopts.getopt.GetoptError, inst:
         raise error.ParseError(cmd, inst)
 
--- a/mercurial/fancyopts.py	Tue Feb 10 16:31:52 2009 -0600
+++ b/mercurial/fancyopts.py	Tue Feb 10 13:26:00 2009 -0600
@@ -1,6 +1,32 @@
 import getopt
 
-def fancyopts(args, options, state):
+def gnugetopt(args, options, longoptions):
+    """Parse options mostly like getopt.gnu_getopt.
+
+    This is different from getopt.gnu_getopt in that an argument of - will
+    become an argument of - instead of vanishing completely.
+    """
+    extraargs = []
+    if '--' in args:
+        stopindex = args.index('--')
+        extraargs = args[stopindex+1:]
+        args = args[:stopindex]
+    opts, parseargs = getopt.getopt(args, options, longoptions)
+    args = []
+    while parseargs:
+        arg = parseargs.pop(0)
+        if arg and arg[0] == '-' and len(arg) > 1:
+            parseargs.insert(0, arg)
+            topts, newparseargs = getopt.getopt(parseargs, options, longoptions)
+            opts = opts + topts
+            parseargs = newparseargs
+        else:
+            args.append(arg)
+    args.extend(extraargs)
+    return opts, args
+
+
+def fancyopts(args, options, state, gnu=False):
     """
     read args, parse options, and store options in state
 
@@ -52,7 +78,11 @@
             namelist.append(oname)
 
     # parse arguments
-    opts, args = getopt.getopt(args, shortlist, namelist)
+    if gnu:
+        parse = gnugetopt
+    else:
+        parse = getopt.getopt
+    opts, args = parse(args, shortlist, namelist)
 
     # transfer result to state
     for opt, val in opts:
--- a/tests/test-mq-guards	Tue Feb 10 16:31:52 2009 -0600
+++ b/tests/test-mq-guards	Tue Feb 10 13:26:00 2009 -0600
@@ -53,7 +53,7 @@
 echo % should push a.patch
 hg qpush
 
-hg qguard c.patch -a
+hg qguard -- c.patch -a
 echo % should print -a
 hg qguard c.patch
 
@@ -95,7 +95,7 @@
 hg qpush
 hg qpop -a
 
-hg qguard a.patch +1 +2 -3
+hg qguard -- a.patch +1 +2 -3
 hg qselect 1 2 3
 echo % list patches and guards
 hg qguard -l