A bunch of parsing/help updates
authormpm@selenic.com
Sun, 03 Jul 2005 11:47:45 -0800
changeset 596 9a8daeff0ffa
parent 595 c2c2c6d617bd
child 597 e530637ea060
A bunch of parsing/help updates -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 A bunch of parsing/help updates more explanation of how to get non-basic commands shorten names of debug functions and add docstrings add undo long docstring promote anotate, export, and revert make the global opts array global refactor parsing kill two unused arguments to fancyopts update test-help manifest hash: 459ae2273aaf54f71b4576677a681dc53ab2908c -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) iD8DBQFCyEDhywK+sNU5EO8RAr0DAJ9LTu8Fc2quLRtuwLPTQzWqlOJWKwCbBpZk pnMkYnshsutVYljcil1P46I= =Sleg -----END PGP SIGNATURE-----
mercurial/commands.py
mercurial/fancyopts.py
tests/test-help
tests/test-help.out
--- a/mercurial/commands.py	Sun Jul 03 11:41:43 2005 -0800
+++ b/mercurial/commands.py	Sun Jul 03 11:47:45 2005 -0800
@@ -221,7 +221,7 @@
         if ui.verbose:
             ui.write('hg commands:\n\n')
         else:
-            ui.write('basic hg commands (use -v for long list):\n\n')
+            ui.write('basic hg commands (use "hg help -v" for more):\n\n')
 
         h = {}
         for c, e in table.items():
@@ -392,7 +392,8 @@
     """mark a file as copied or renamed for the next commit"""
     return repo.copy(*relpath(repo, (source, dest)))
 
-def debugcheckdirstate(ui, repo):
+def debugcheckstate(ui, repo):
+    """validate the correctness of the current dirstate"""
     parent1, parent2 = repo.dirstate.parents()
     repo.dirstate.read()
     dc = repo.dirstate.map
@@ -424,7 +425,8 @@
         ui.warn(".hg/dirstate inconsistent with current parent's manifest\n")
         sys.exit(1)
 
-def debugdumpdirstate(ui, repo):
+def debugstate(ui, repo):
+    """show the contents of the current dirstate"""
     repo.dirstate.read()
     dc = repo.dirstate.map
     keys = dc.keys()
@@ -433,6 +435,7 @@
         ui.write("%c %s\n" % (dc[file][0], file))
 
 def debugindex(ui, file):
+    """dump the contents of an index file"""
     r = hg.revlog(hg.opener(""), file, "")
     ui.write("   rev    offset  length   base linkrev" +
              " p1           p2           nodeid\n")
@@ -443,6 +446,7 @@
             hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5])))
 
 def debugindexdot(ui, file):
+    """dump an index DAG as a .dot file"""
     r = hg.revlog(hg.opener(""), file, "")
     ui.write("digraph G {\n")
     for i in range(r.count()):
@@ -858,7 +862,18 @@
     show_changeset(ui, repo, changenode=n)
 
 def undo(ui, repo):
-    """undo the last transaction"""
+    """undo the last commit or pull
+
+    Roll back the last pull or commit transaction on the
+    repository, restoring the project to its earlier state.
+
+    This command should be used with care. There is only one level of
+    undo and there is no redo.
+
+    This command is not intended for use on public repositories. Once
+    a change is visible for pull by other users, undoing it locally is
+    ineffective.
+    """
     repo.undo()
 
 def update(ui, repo, node=None, merge=False, clean=False):
@@ -886,7 +901,7 @@
 table = {
     "^add": (add, [], "hg add [files]"),
     "addremove": (addremove, [], "hg addremove [files]"),
-    "annotate": (annotate,
+    "^annotate": (annotate,
                      [('r', 'revision', '', 'revision'),
                       ('u', 'user', None, 'show user'),
                       ('n', 'number', None, 'show revision number'),
@@ -903,13 +918,13 @@
                    ('u', 'user', "", 'user')],
                   'hg commit [files]'),
     "copy": (copy, [], 'hg copy <source> <dest>'),
-    "debugcheckdirstate": (debugcheckdirstate, [], 'debugcheckdirstate'),
-    "debugdumpdirstate": (debugdumpdirstate, [], 'debugdumpdirstate'),
+    "debugcheckstate": (debugcheckstate, [], 'debugcheckstate'),
+    "debugstate": (debugstate, [], 'debugstate'),
     "debugindex": (debugindex, [], 'debugindex <file>'),
     "debugindexdot": (debugindexdot, [], 'debugindexdot <file>'),
     "^diff": (diff, [('r', 'rev', [], 'revision')],
              'hg diff [-r A] [-r B] [files]'),
-    "export": (export, [('o', 'output', "", 'output to file')],
+    "^export": (export, [('o', 'output', "", 'output to file')],
                "hg export [-o file] <changeset> ..."),
     "forget": (forget, [], "hg forget [files]"),
     "heads": (heads, [], 'hg heads'),
@@ -939,7 +954,7 @@
                   'hg rawcommit [options] [files]'),
     "recover": (recover, [], "hg recover"),
     "^remove|rm": (remove, [], "hg remove [files]"),
-    "revert": (revert,
+    "^revert": (revert,
                [("n", "nonrecursive", None, "don't recurse into subdirs"),
                 ("r", "rev", "", "revision")],
                "hg revert [files|dirs]"),
@@ -966,6 +981,16 @@
     "version": (show_version, [], 'hg version'),
     }
 
+globalopts = [('v', 'verbose', None, 'verbose'),
+              ('', 'debug', None, 'debug'),
+              ('q', 'quiet', None, 'quiet'),
+              ('', 'profile', None, 'profile'),
+              ('R', 'repository', "", 'repository root directory'),
+              ('', 'traceback', None, 'print traceback on exception'),
+              ('y', 'noninteractive', None, 'run non-interactively'),
+              ('', 'version', None, 'output version information and exit'),
+              ]
+
 norepo = "clone init version help debugindex debugindexdot"
 
 def find(cmd):
@@ -983,80 +1008,76 @@
 def run():
     sys.exit(dispatch(sys.argv[1:]))
 
-def dispatch(args):
-    signal.signal(signal.SIGTERM, catchterm)
+class ParseError(Exception): pass
 
-    def get_ui():
-        return ui.ui(options["verbose"], options["debug"], options["quiet"],
-                     not options["noninteractive"])
-
+def parse(args):
     options = {}
-    opts = [('v', 'verbose', None, 'verbose'),
-            ('', 'debug', None, 'debug'),
-            ('q', 'quiet', None, 'quiet'),
-            ('', 'profile', None, 'profile'),
-            ('R', 'repository', "", 'repository root directory'),
-            ('', 'traceback', None, 'print traceback on exception'),
-            ('y', 'noninteractive', None, 'run non-interactively'),
-            ('', 'version', None, 'output version information and exit'),
-            ]
+    cmdoptions = {}
 
     try:
-        args = fancyopts.fancyopts(args, opts, options,
-                                   'hg [options] <command> [options] [files]')
+        args = fancyopts.fancyopts(args, globalopts, options)
     except fancyopts.getopt.GetoptError, inst:
-        u = ui.ui()
-        u.warn("hg: %s\n" % (inst))
-        sys.exit(-1)
+        raise ParseError(cmd, inst)
 
-    if not args:
-        cmd = "help"
+    if options["version"]:
+        return ("version", show_version, [], options, cmdoptions)
+    elif not args:
+        return ("help", help, [], options, cmdoptions)
     else:
         cmd, args = args[0], args[1:]
 
-    if options["version"]:
-        show_version(get_ui())
-        sys.exit(0)
-
-    try:
-        i = find(cmd)
-    except UnknownCommand:
-        u = get_ui()
-        u.warn("hg: unknown command '%s'\n" % cmd)
-        help(u)
-        sys.exit(1)
+    i = find(cmd)
 
     # combine global options into local
     c = list(i[1])
     l = len(c)
-    for o in opts:
+    for o in globalopts:
         c.append((o[0], o[1], options[o[1]], o[3]))
 
-    cmdoptions = {}
     try:
-        args = fancyopts.fancyopts(args, c, cmdoptions, i[2])
+        args = fancyopts.fancyopts(args, c, cmdoptions)
     except fancyopts.getopt.GetoptError, inst:
-        u = get_ui()
-        u.warn("hg %s: %s\n" % (cmd, inst))
-        help(u, cmd)
-        sys.exit(-1)
+        raise ParseError(cmd, inst)
 
     # separate global options back out
-    for o in opts:
+    for o in globalopts:
         n = o[1]
         options[n] = cmdoptions[n]
         del cmdoptions[n]
 
-    u = get_ui()
+    return (cmd, i[0], args, options, cmdoptions)
+
+def dispatch(args):
+    signal.signal(signal.SIGTERM, catchterm)
+
+    try:
+        cmd, func, args, options, cmdoptions = parse(args)
+    except ParseError, inst:
+        u = ui.ui()
+        if inst.args[0]:
+            u.warn("hg %s: %s\n" % (inst.args[0], inst.args[1]))
+            help(u, inst.args[0])
+        else:
+            u.warn("hg: %s\n" % inst.args[1])
+            help(u)
+        sys.exit(-1)
+    except UnknownCommand, inst:
+        u = ui.ui()
+        u.warn("hg: unknown command '%s'\n" % inst.args[0])
+        help(u)
+        sys.exit(1)
+
+    u = ui.ui(options["verbose"], options["debug"], options["quiet"],
+                     not options["noninteractive"])
 
     try:
         try:
             if cmd not in norepo.split():
                 path = options["repository"] or ""
                 repo = hg.repository(ui=u, path=path)
-                d = lambda: i[0](u, repo, *args, **cmdoptions)
+                d = lambda: func(u, repo, *args, **cmdoptions)
             else:
-                d = lambda: i[0](u, *args, **cmdoptions)
+                d = lambda: func(u, *args, **cmdoptions)
 
             if options['profile']:
                 import hotshot, hotshot.stats
@@ -1102,7 +1123,7 @@
         if len(tb) > 2: # no
             raise
         u.debug(inst, "\n")
-        u.warn("%s: invalid arguments\n" % i[0].__name__)
+        u.warn("%s: invalid arguments\n" % cmd)
         help(u, cmd)
 
     sys.exit(-1)
--- a/mercurial/fancyopts.py	Sun Jul 03 11:41:43 2005 -0800
+++ b/mercurial/fancyopts.py	Sun Jul 03 11:47:45 2005 -0800
@@ -1,6 +1,6 @@
 import os, getopt
 
-def fancyopts(args, options, state, syntax='', minlen = 0):
+def fancyopts(args, options, state):
     long=[]
     short=''
     map={}
--- a/tests/test-help	Sun Jul 03 11:41:43 2005 -0800
+++ b/tests/test-help	Sun Jul 03 11:47:45 2005 -0800
@@ -1,9 +1,9 @@
 #!/bin/sh
 
-set -x
-
+hg help
 hg -q help
 hg add -h
+hg add --skjdfks
 hg help diff
 hg help foo
 hg -q commands
--- a/tests/test-help.out	Sun Jul 03 11:41:43 2005 -0800
+++ b/tests/test-help.out	Sun Jul 03 11:47:45 2005 -0800
@@ -1,46 +1,67 @@
-+ hg -q help
-basic hg commands (use -v for long list):
+basic hg commands (use "hg help -v" for more):
 
- add      add the specified files on the next commit
- clone    make a copy of an existing repository
- commit   commit the specified files or all outstanding changes
- diff     diff working directory (or selected files)
- init     create a new repository in the current directory
- log      show the revision history of the repository or a single file
- pull     pull changes from the specified source
- push     push changes to the specified destination
- remove   remove the specified files on the next commit
- serve    export the repository via HTTP
- status   show changed files in the working directory
- update   update or merge working directory
-+ hg add -h
+ add        add the specified files on the next commit
+ annotate   show changeset information per file line
+ clone      make a copy of an existing repository
+ commit     commit the specified files or all outstanding changes
+ diff       diff working directory (or selected files)
+ export     dump the header and diffs for one or more changesets
+ init       create a new repository in the current directory
+ log        show the revision history of the repository or a single file
+ pull       pull changes from the specified source
+ push       push changes to the specified destination
+ remove     remove the specified files on the next commit
+ revert     revert modified files or dirs back to their unmodified states
+ serve      export the repository via HTTP
+ status     show changed files in the working directory
+ update     update or merge working directory
+basic hg commands (use "hg help -v" for more):
+
+ add        add the specified files on the next commit
+ annotate   show changeset information per file line
+ clone      make a copy of an existing repository
+ commit     commit the specified files or all outstanding changes
+ diff       diff working directory (or selected files)
+ export     dump the header and diffs for one or more changesets
+ init       create a new repository in the current directory
+ log        show the revision history of the repository or a single file
+ pull       pull changes from the specified source
+ push       push changes to the specified destination
+ remove     remove the specified files on the next commit
+ revert     revert modified files or dirs back to their unmodified states
+ serve      export the repository via HTTP
+ status     show changed files in the working directory
+ update     update or merge working directory
 hg add: option -h not recognized
 hg add [files]
 
 add the specified files on the next commit
-+ hg help diff
+hg add: option --skjdfks not recognized
+hg add [files]
+
+add the specified files on the next commit
 hg diff [-r A] [-r B] [files]
 
  -r --rev 
    revision
 
 diff working directory (or selected files)
-+ hg help foo
 hg: unknown command foo
-+ hg -q commands
 hg: unknown command 'commands'
-basic hg commands (use -v for long list):
+basic hg commands (use "hg help -v" for more):
 
- add      add the specified files on the next commit
- clone    make a copy of an existing repository
- commit   commit the specified files or all outstanding changes
- diff     diff working directory (or selected files)
- init     create a new repository in the current directory
- log      show the revision history of the repository or a single file
- pull     pull changes from the specified source
- push     push changes to the specified destination
- remove   remove the specified files on the next commit
- serve    export the repository via HTTP
- status   show changed files in the working directory
- update   update or merge working directory
-+ exit 0
+ add        add the specified files on the next commit
+ annotate   show changeset information per file line
+ clone      make a copy of an existing repository
+ commit     commit the specified files or all outstanding changes
+ diff       diff working directory (or selected files)
+ export     dump the header and diffs for one or more changesets
+ init       create a new repository in the current directory
+ log        show the revision history of the repository or a single file
+ pull       pull changes from the specified source
+ push       push changes to the specified destination
+ remove     remove the specified files on the next commit
+ revert     revert modified files or dirs back to their unmodified states
+ serve      export the repository via HTTP
+ status     show changed files in the working directory
+ update     update or merge working directory