From 33ff9cdd840cfe2780acc41d88d33c8c3bc2761e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Karl=20Hasselstr=C3=B6m?= Date: Sun, 21 Sep 2008 14:19:07 +0200 Subject: [PATCH] Generate command lists automatically MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Instead of hard-coding the list of stg subcommands everywhere, generate them automatically. That way, they never get outdated (like the list in stg.txt). In order to not make StGit slower, we cache the list of commands; run "make build" to update that cache (other make targets, such as "all" and "test", imply "build"). If the cache doesn't exist, the code falls back to importing all the command modules, which adds quite a bit of overhead to each stg command (about 100 ms on my laptop). Signed-off-by: Karl Hasselström --- Documentation/Makefile | 9 ++- Documentation/asciidoc.conf | 17 ++++++ Documentation/stg.txt | 136 +------------------------------------------- Makefile | 18 ++++-- stg-build | 15 ++++- stgit/commands/.gitignore | 1 + stgit/commands/__init__.py | 78 +++++++++++++++++++++++++ stgit/commands/branch.py | 1 + stgit/commands/clean.py | 1 + stgit/commands/clone.py | 1 + stgit/commands/coalesce.py | 1 + stgit/commands/commit.py | 1 + stgit/commands/delete.py | 1 + stgit/commands/diff.py | 1 + stgit/commands/edit.py | 1 + stgit/commands/export.py | 1 + stgit/commands/files.py | 1 + stgit/commands/float.py | 1 + stgit/commands/fold.py | 1 + stgit/commands/goto.py | 1 + stgit/commands/hide.py | 1 + stgit/commands/id.py | 1 + stgit/commands/imprt.py | 1 + stgit/commands/init.py | 1 + stgit/commands/log.py | 1 + stgit/commands/mail.py | 1 + stgit/commands/new.py | 1 + stgit/commands/patches.py | 1 + stgit/commands/pick.py | 1 + stgit/commands/pop.py | 1 + stgit/commands/pull.py | 1 + stgit/commands/push.py | 1 + stgit/commands/rebase.py | 1 + stgit/commands/refresh.py | 1 + stgit/commands/rename.py | 1 + stgit/commands/repair.py | 1 + stgit/commands/resolved.py | 1 + stgit/commands/series.py | 1 + stgit/commands/show.py | 1 + stgit/commands/sink.py | 1 + stgit/commands/status.py | 1 + stgit/commands/sync.py | 1 + stgit/commands/top.py | 1 + stgit/commands/uncommit.py | 1 + stgit/commands/unhide.py | 1 + stgit/main.py | 129 ++--------------------------------------- 46 files changed, 173 insertions(+), 268 deletions(-) create mode 100644 stgit/commands/.gitignore diff --git a/Documentation/Makefile b/Documentation/Makefile index 1c14fe3..85e9600 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -60,11 +60,16 @@ doc.dep : $(wildcard *.txt) build-docdep.perl -include doc.dep clean: - rm -f *.xml *.html *.pdf *.1 doc.dep $(COMMANDS_TXT) + rm -f *.xml *.html *.pdf *.1 doc.dep $(COMMANDS_TXT) stg-cmd-list.txt -$(COMMANDS_TXT): $(shell find .. -name '*.py') +ALL_PY = $(shell find ../stgit -name '*.py') + +$(COMMANDS_TXT): $(ALL_PY) ../stg-build --asciidoc $(basename $(subst stg-,,$@)) > $@ +stg-cmd-list.txt: $(ALL_PY) + ../stg-build --cmd-list > $@ + %.html : %.txt $(ASCIIDOC) -b xhtml11 -d manpage -f asciidoc.conf $(ASCIIDOC_EXTRA) $< diff --git a/Documentation/asciidoc.conf b/Documentation/asciidoc.conf index 69447ab..5f7a7af 100644 --- a/Documentation/asciidoc.conf +++ b/Documentation/asciidoc.conf @@ -84,3 +84,20 @@ ifdef::backend-xhtml11[] [stglink-inlinemacro] stg {target} endif::backend-xhtml11[] + +## stgsublink: macro +# +# Usage: stgsublink:command[] +# +# Show StGit link as: in man pages, stg in +# html. + +ifdef::backend-docbook[] +[stgsublink-inlinemacro] +{target} +endif::backend-docbook[] + +ifdef::backend-xhtml11[] +[stgsublink-inlinemacro] +{target} +endif::backend-xhtml11[] diff --git a/Documentation/stg.txt b/Documentation/stg.txt index a0b2176..b4184b2 100644 --- a/Documentation/stg.txt +++ b/Documentation/stg.txt @@ -105,141 +105,7 @@ description is available in individual command manpages. Those manpages are named 'stg-(1)'. endif::backend-docbook[] -Generic commands -~~~~~~~~~~~~~~~~ - -User-support commands not touching the repository. - -stg help:: - stgdesc:help[] -stg version:: - stgdesc:version[] -stg copyright:: - stgdesc:copyright[] - -Repository commands -~~~~~~~~~~~~~~~~~~~ - -stglink:clone[]:: - stgdesc:clone[] -stglink:id[]:: - stgdesc:id[] - -Stack commands -~~~~~~~~~~~~~~ - -Stack management -^^^^^^^^^^^^^^^^ - -stglink:branch[]:: - stgdesc:branch[] -stglink:init[]:: - stgdesc:init[] -stglink:clean[]:: - stgdesc:clean[] -stglink:pull[]:: - stgdesc:pull[] -stglink:rebase[]:: - stgdesc:rebase[] - -stglink:commit[]:: - stgdesc:commit[] -stglink:uncommit[]:: - stgdesc:uncommit[] -stglink:repair[]:: - stgdesc:repair[] - -Controlling what patches are applied -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -stglink:series[]:: - stgdesc:series[] -stglink:push[]:: - stgdesc:push[] -stglink:pop[]:: - stgdesc:pop[] -stglink:goto[]:: - stgdesc:goto[] -stglink:float[]:: - stgdesc:float[] -stglink:sink[]:: - stgdesc:sink[] -stglink:applied[]:: - stgdesc:applied[] -stglink:unapplied[]:: - stgdesc:unapplied[] -stglink:top[]:: - stgdesc:top[] - -stglink:hide[]:: - stgdesc:hide[] -stglink:unhide[]:: - stgdesc:unhide[] - -Miscellaneous stack commands -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -stglink:patches[]:: - stgdesc:patches[] - - -Patch commands -~~~~~~~~~~~~~~ - -Patch management -^^^^^^^^^^^^^^^^ - -stglink:new[]:: - stgdesc:new[] -stglink:delete[]:: - stgdesc:delete[] -stglink:rename[]:: - stgdesc:rename[] -stglink:log[]:: - stgdesc:log[] - -Controlling patch contents -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -stglink:files[]:: - stgdesc:files[] -stglink:show[]:: - stgdesc:show[] -stglink:refresh[]:: - stgdesc:refresh[] -stglink:fold[]:: - stgdesc:fold[] -stglink:pick[]:: - stgdesc:pick[] -stglink:sync[]:: - stgdesc:sync[] - -Interaction with the rest of the world -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -stglink:export[]:: - stgdesc:export[] -stglink:import[]:: - stgdesc:import[] -stglink:mail[]:: - stgdesc:mail[] - - -Working-copy commands -~~~~~~~~~~~~~~~~~~~~~ - -stglink:add[]:: - stgdesc:add[] -stglink:rm[]:: - stgdesc:rm[] -stglink:cp[]:: - stgdesc:cp[] -stglink:status[]:: - stgdesc:status[] -stglink:diff[]:: - stgdesc:diff[] -stglink:resolved[]:: - stgdesc:resolved[] +include::stg-cmd-list.txt[] CONFIGURATION MECHANISM ----------------------- diff --git a/Makefile b/Makefile index 9322fe0..288622a 100644 --- a/Makefile +++ b/Makefile @@ -4,10 +4,17 @@ PYTHON ?= python TEST_PATCHES ?= .. -all: +all: build $(PYTHON) setup.py build -install: +build: stgit/commands/cmdlist.py + +ALL_PY = $(shell find stgit -name '*.py') + +stgit/commands/cmdlist.py: $(ALL_PY) + $(PYTHON) stg-build --py-cmd-list > $@ + +install: build $(PYTHON) setup.py install --prefix=$(prefix) --root=$(DESTDIR) --force doc: @@ -19,10 +26,10 @@ install-doc: install-html: $(MAKE) -C Documentation install-html -test: +test: build cd t && $(MAKE) all -test_patches: +test_patches: build for patch in $$(stg series --noprefix $(TEST_PATCHES)); do \ stg goto $$patch && $(MAKE) test || break; \ done @@ -35,8 +42,9 @@ clean: rm -f stgit/*.pyc rm -f stgit/commands/*.pyc rm -f TAGS + rm -f stgit/commands/cmdlist.py tags: ctags -e -R stgit/* -.PHONY: all install doc install-doc install-html test test_patches clean +.PHONY: all build install doc install-doc install-html test test_patches clean diff --git a/stg-build b/stg-build index 8c39a6f..3c9dbfa 100755 --- a/stg-build +++ b/stg-build @@ -2,7 +2,7 @@ # -*- python -*- import optparse, sys import stgit.main -from stgit import argparse +from stgit import argparse, commands def main(): op = optparse.OptionParser() @@ -10,6 +10,10 @@ def main(): help = 'Print asciidoc documentation for a command') op.add_option('--commands', action = 'store_true', help = 'Print list of all stg subcommands') + op.add_option('--cmd-list', action = 'store_true', + help = 'Print asciidoc command list') + op.add_option('--py-cmd-list', action = 'store_true', + help = 'Write Python command list') options, args = op.parse_args() if args: op.error('Wrong number of arguments') @@ -17,8 +21,15 @@ def main(): argparse.write_asciidoc(stgit.main.commands[options.asciidoc], sys.stdout) elif options.commands: - for cmd in sorted(stgit.main.commands.iterkeys()): + for cmd in sorted(commands.get_commands( + allow_cached = False).iterkeys()): print cmd + elif options.cmd_list: + commands.asciidoc_command_list( + commands.get_commands(allow_cached = False), sys.stdout) + elif options.py_cmd_list: + commands.py_commands(commands.get_commands(allow_cached = False), + sys.stdout) else: op.error('No command') diff --git a/stgit/commands/.gitignore b/stgit/commands/.gitignore new file mode 100644 index 0000000..eff10ee --- /dev/null +++ b/stgit/commands/.gitignore @@ -0,0 +1 @@ +/cmdlist.py diff --git a/stgit/commands/__init__.py b/stgit/commands/__init__.py index 4b03e3a..54a9326 100644 --- a/stgit/commands/__init__.py +++ b/stgit/commands/__init__.py @@ -1,5 +1,8 @@ +# -*- coding: utf-8 -*- + __copyright__ = """ Copyright (C) 2005, Catalin Marinas +Copyright (C) 2008, Karl Hasselström This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as @@ -14,3 +17,78 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """ + +import os +from stgit import utils + +def get_command(mod): + """Import and return the given command module.""" + return __import__(__name__ + '.' + mod, globals(), locals(), ['*']) + +_kinds = [('repo', 'Repository commands'), + ('stack', 'Stack (branch) commands'), + ('patch', 'Patch commands'), + ('wc', 'Index/worktree commands')] +_kind_order = [kind for kind, desc in _kinds] +_kinds = dict(_kinds) + +def _find_commands(): + for p in __path__: + for fn in os.listdir(p): + if not fn.endswith('.py'): + continue + mod = utils.strip_suffix('.py', fn) + m = get_command(mod) + if not hasattr(m, 'usage'): + continue + yield mod, m + +def get_commands(allow_cached = True): + """Return a map from command name to a tuple of module name, command + type, and one-line command help.""" + if allow_cached: + try: + from stgit.commands.cmdlist import command_list + return command_list + except ImportError: + # cmdlist.py doesn't exist, so do it the expensive way. + pass + return dict((getattr(m, 'name', mod), (mod, _kinds[m.kind], m.help)) + for mod, m in _find_commands()) + +def py_commands(commands, f): + f.write('command_list = {\n') + for key, val in sorted(commands.iteritems()): + f.write(' %r: %r,\n' % (key, val)) + f.write(' }\n') + +def _command_list(commands): + kinds = {} + for cmd, (mod, kind, help) in commands.iteritems(): + kinds.setdefault(kind, {})[cmd] = help + for kind in _kind_order: + kind = _kinds[kind] + yield kind, sorted(kinds[kind].iteritems()) + +def pretty_command_list(commands, f): + cmd_len = max(len(cmd) for cmd in commands.iterkeys()) + sep = '' + for kind, cmds in _command_list(commands): + f.write(sep) + sep = '\n' + f.write('%s:\n' % kind) + for cmd, help in cmds: + f.write(' %*s %s\n' % (-cmd_len, cmd, help)) + +def _write_underlined(s, u, f): + f.write(s + '\n') + f.write(u*len(s) + '\n') + +def asciidoc_command_list(commands, f): + for kind, cmds in _command_list(commands): + _write_underlined(kind, '~', f) + f.write('\n') + for cmd, help in cmds: + f.write('stgsublink:%s[]::\n' % cmd) + f.write(' %s\n' % help) + f.write('\n') diff --git a/stgit/commands/branch.py b/stgit/commands/branch.py index 33a8afe..1b1b98f 100644 --- a/stgit/commands/branch.py +++ b/stgit/commands/branch.py @@ -23,6 +23,7 @@ from stgit.out import * from stgit import stack, git, basedir help = 'Branch operations: switch, list, create, rename, delete, ...' +kind = 'stack' usage = ['', '', '--list', diff --git a/stgit/commands/clean.py b/stgit/commands/clean.py index 5334704..27a7716 100644 --- a/stgit/commands/clean.py +++ b/stgit/commands/clean.py @@ -21,6 +21,7 @@ from stgit.commands import common from stgit.lib import transaction help = 'Delete the empty patches in the series' +kind = 'stack' usage = [''] description = """ Delete the empty patches in the whole series or only those applied or diff --git a/stgit/commands/clone.py b/stgit/commands/clone.py index b83169e..28500c5 100644 --- a/stgit/commands/clone.py +++ b/stgit/commands/clone.py @@ -21,6 +21,7 @@ from stgit.utils import * from stgit import stack, git help = 'Make a local clone of a remote repository' +kind = 'repo' usage = [' '] description = """ Clone a git repository into the local directory (using diff --git a/stgit/commands/coalesce.py b/stgit/commands/coalesce.py index b390584..024668a 100644 --- a/stgit/commands/coalesce.py +++ b/stgit/commands/coalesce.py @@ -24,6 +24,7 @@ from stgit.commands import common from stgit.lib import git, transaction help = 'Coalesce two or more patches into one' +kind = 'stack' usage = ['[options] '] description = """ Coalesce two or more patches, creating one big patch that contains all diff --git a/stgit/commands/commit.py b/stgit/commands/commit.py index 7d46724..99b7b5d 100644 --- a/stgit/commands/commit.py +++ b/stgit/commands/commit.py @@ -21,6 +21,7 @@ from stgit.lib import transaction from stgit.out import * help = 'Permanently store the applied patches into the stack base' +kind = 'stack' usage = ['', '', '-n NUM', diff --git a/stgit/commands/delete.py b/stgit/commands/delete.py index 3ba7fc2..b92a039 100644 --- a/stgit/commands/delete.py +++ b/stgit/commands/delete.py @@ -21,6 +21,7 @@ from stgit.commands import common from stgit.lib import transaction help = 'Delete patches' +kind = 'patch' usage = ['[options] [] [..]'] description = """ Delete the patches passed as arguments. diff --git a/stgit/commands/diff.py b/stgit/commands/diff.py index 47e2e7f..e0078f9 100644 --- a/stgit/commands/diff.py +++ b/stgit/commands/diff.py @@ -25,6 +25,7 @@ from stgit.out import * from stgit import argparse, stack, git help = 'Show the tree diff' +kind = 'wc' usage = ['[options] []'] description = """ Show the diff (default) or diffstat between the current working copy diff --git a/stgit/commands/edit.py b/stgit/commands/edit.py index 0db3254..b6ef6c7 100644 --- a/stgit/commands/edit.py +++ b/stgit/commands/edit.py @@ -25,6 +25,7 @@ from stgit.lib import git as gitlib, transaction from stgit.out import * help = 'edit a patch description or diff' +kind = 'patch' usage = ['[options] []'] description = """ Edit the description and author information of the given patch (or the diff --git a/stgit/commands/export.py b/stgit/commands/export.py index 3d74cc8..8d05996 100644 --- a/stgit/commands/export.py +++ b/stgit/commands/export.py @@ -26,6 +26,7 @@ from stgit.out import out from stgit.lib import git as gitlib help = 'Export patches to a directory' +kind = 'patch' usage = ['[options] [] [] [..]'] description = """ Export a range of applied patches to a given directory (defaults to diff --git a/stgit/commands/files.py b/stgit/commands/files.py index 08f882c..318a4a3 100644 --- a/stgit/commands/files.py +++ b/stgit/commands/files.py @@ -24,6 +24,7 @@ from stgit.out import * from stgit import argparse, stack, git help = 'Show the files modified by a patch (or the current patch)' +kind = 'patch' usage = ['[options] [[:]]'] description = """ List the files modified by the given patch (defaulting to the current diff --git a/stgit/commands/float.py b/stgit/commands/float.py index ac8eaea..1ca4ed3 100644 --- a/stgit/commands/float.py +++ b/stgit/commands/float.py @@ -23,6 +23,7 @@ from stgit.utils import * from stgit import stack, git help = 'Push patches to the top, even if applied' +kind = 'stack' usage = ['', '-s '] description = """ diff --git a/stgit/commands/fold.py b/stgit/commands/fold.py index 6ddaea9..0f1486a 100644 --- a/stgit/commands/fold.py +++ b/stgit/commands/fold.py @@ -23,6 +23,7 @@ from stgit.out import * from stgit import stack, git help = 'Integrate a GNU diff patch into the current patch' +kind = 'patch' usage = ['[options] []'] description = """ Apply the given GNU diff file (or the standard input) onto the top of diff --git a/stgit/commands/goto.py b/stgit/commands/goto.py index 33b20ed..2bfef0f 100644 --- a/stgit/commands/goto.py +++ b/stgit/commands/goto.py @@ -19,6 +19,7 @@ from stgit.commands import common from stgit.lib import transaction help = 'Push or pop patches to the given one' +kind = 'stack' usage = [''] description = """ Push/pop patches to/from the stack until the one given on the command diff --git a/stgit/commands/hide.py b/stgit/commands/hide.py index 488ea18..bee2162 100644 --- a/stgit/commands/hide.py +++ b/stgit/commands/hide.py @@ -23,6 +23,7 @@ from stgit.out import * from stgit import stack, git help = 'Hide a patch in the series' +kind = 'stack' usage = ['[options] '] description = """ Hide a range of unapplied patches so that they are no longer shown in diff --git a/stgit/commands/id.py b/stgit/commands/id.py index 18bab97..857ec33 100644 --- a/stgit/commands/id.py +++ b/stgit/commands/id.py @@ -20,6 +20,7 @@ from stgit.commands import common from stgit.lib import stack help = 'Print the git hash value of a StGit reference' +kind = 'repo' usage = ['[options] [id]'] description = """ Print the SHA1 value of a Git id (defaulting to HEAD). In addition to diff --git a/stgit/commands/imprt.py b/stgit/commands/imprt.py index e97b01d..150d9ee 100644 --- a/stgit/commands/imprt.py +++ b/stgit/commands/imprt.py @@ -26,6 +26,7 @@ from stgit import argparse, stack, git name = 'import' help = 'Import a GNU diff file as a new patch' +kind = 'patch' usage = ['[options] [|]'] description = """ Create a new patch and apply the given GNU diff file (or the standard diff --git a/stgit/commands/init.py b/stgit/commands/init.py index f7f7a21..67d20d1 100644 --- a/stgit/commands/init.py +++ b/stgit/commands/init.py @@ -20,6 +20,7 @@ from stgit.commands import common from stgit.lib import stack help = 'Initialise the current branch for use with StGIT' +kind = 'stack' usage = [''] description = """ Initialise the current git branch to be used as an StGIT stack. The diff --git a/stgit/commands/log.py b/stgit/commands/log.py index b505ed5..de210ea 100644 --- a/stgit/commands/log.py +++ b/stgit/commands/log.py @@ -24,6 +24,7 @@ from stgit.out import * from stgit.run import Run help = 'Display the patch changelog' +kind = 'patch' usage = ['[options] [patch]'] description = """ List all the current and past commit ids of the given patch. The diff --git a/stgit/commands/mail.py b/stgit/commands/mail.py index 83acc86..caf8f9e 100644 --- a/stgit/commands/mail.py +++ b/stgit/commands/mail.py @@ -26,6 +26,7 @@ from stgit.config import config from stgit.run import Run help = 'Send a patch or series of patches by e-mail' +kind = 'patch' usage = [' [options] [] [] [..]'] description = r""" Send a patch or a range of patches by e-mail using the SMTP server diff --git a/stgit/commands/new.py b/stgit/commands/new.py index 4ed2079..f36fbd6 100644 --- a/stgit/commands/new.py +++ b/stgit/commands/new.py @@ -22,6 +22,7 @@ from stgit.lib import git as gitlib, transaction from stgit.config import config help = 'Create a new, empty patch' +kind = 'patch' usage = ['[options] []'] description = """ Create a new, empty patch on the current stack. The new patch is diff --git a/stgit/commands/patches.py b/stgit/commands/patches.py index 656a4a1..0cbc275 100644 --- a/stgit/commands/patches.py +++ b/stgit/commands/patches.py @@ -24,6 +24,7 @@ from stgit.out import * from stgit import stack, git help = 'Show the applied patches modifying a file' +kind = 'stack' usage = ['[options] []'] description = """ Show the applied patches modifying the given files. Without arguments, diff --git a/stgit/commands/pick.py b/stgit/commands/pick.py index 72b2359..8a88262 100644 --- a/stgit/commands/pick.py +++ b/stgit/commands/pick.py @@ -24,6 +24,7 @@ from stgit import stack, git from stgit.stack import Series help = 'Import a patch from a different branch or a commit object' +kind = 'patch' usage = ['[options] ([] [] [..])|'] description = """ Import one or more patches from a different branch or a commit object diff --git a/stgit/commands/pop.py b/stgit/commands/pop.py index b3c4008..cf89846 100644 --- a/stgit/commands/pop.py +++ b/stgit/commands/pop.py @@ -23,6 +23,7 @@ from stgit.utils import * from stgit import stack, git help = 'Pop one or more patches from the stack' +kind = 'stack' usage = ['[options] [] [] [..]'] description = """ Pop the topmost patch or a range of patches from the stack. The diff --git a/stgit/commands/pull.py b/stgit/commands/pull.py index 3801bf2..c989b5d 100644 --- a/stgit/commands/pull.py +++ b/stgit/commands/pull.py @@ -24,6 +24,7 @@ from stgit.config import GitConfigException from stgit import stack, git help = 'Pull changes from a remote repository' +kind = 'stack' usage = ['[options] []'] description = """ Pull the latest changes from the given remote repository (defaulting diff --git a/stgit/commands/push.py b/stgit/commands/push.py index ee7b56e..c6056cc 100644 --- a/stgit/commands/push.py +++ b/stgit/commands/push.py @@ -24,6 +24,7 @@ from stgit.out import * from stgit import stack, git help = 'Push one or more patches onto the stack' +kind = 'stack' usage = ['[options] [] [] [..]'] description = """ Push one or more patches (defaulting to the first unapplied one) onto diff --git a/stgit/commands/rebase.py b/stgit/commands/rebase.py index ffec329..b09204e 100644 --- a/stgit/commands/rebase.py +++ b/stgit/commands/rebase.py @@ -22,6 +22,7 @@ from stgit.utils import * from stgit import stack, git help = 'Move the stack base to another point in history' +kind = 'stack' usage = ['[options] '] description = """ Pop all patches from current stack, move the stack base to the given diff --git a/stgit/commands/refresh.py b/stgit/commands/refresh.py index e30085b..a20fcc5 100644 --- a/stgit/commands/refresh.py +++ b/stgit/commands/refresh.py @@ -25,6 +25,7 @@ from stgit import stack, git from stgit.config import config help = 'Generate a new commit for the current patch' +kind = 'patch' usage = ['[options] []'] description = """ Include the latest tree changes in the current patch. This command diff --git a/stgit/commands/rename.py b/stgit/commands/rename.py index b978ecf..fdb31ee 100644 --- a/stgit/commands/rename.py +++ b/stgit/commands/rename.py @@ -23,6 +23,7 @@ from stgit.out import * from stgit import stack, git help = 'Rename a patch' +kind = 'patch' usage = ['[options] [oldpatch] '] description = """ Rename into in a series. If is not diff --git a/stgit/commands/repair.py b/stgit/commands/repair.py index a5156cd..6218caa 100644 --- a/stgit/commands/repair.py +++ b/stgit/commands/repair.py @@ -26,6 +26,7 @@ from stgit.run import * from stgit import stack, git help = 'Fix StGit metadata if branch was modified with git commands' +kind = 'stack' usage = [''] description = """ If you modify an StGit stack (branch) with some git commands -- such diff --git a/stgit/commands/resolved.py b/stgit/commands/resolved.py index 5643da8..d8dacd6 100644 --- a/stgit/commands/resolved.py +++ b/stgit/commands/resolved.py @@ -25,6 +25,7 @@ from stgit.config import config, file_extensions from stgit.gitmergeonefile import interactive_merge help = 'Mark a file conflict as solved' +kind = 'wc' usage = ['[options] []'] description = """ Mark a merge conflict as resolved. The conflicts can be seen with the diff --git a/stgit/commands/series.py b/stgit/commands/series.py index da31061..e9d148a 100644 --- a/stgit/commands/series.py +++ b/stgit/commands/series.py @@ -23,6 +23,7 @@ from stgit.out import out from stgit.config import config help = 'Print the patch series' +kind = 'stack' usage = ['[options] []'] description = """ Show all the patches in the series or just those in the given diff --git a/stgit/commands/show.py b/stgit/commands/show.py index c12793f..41cb31e 100644 --- a/stgit/commands/show.py +++ b/stgit/commands/show.py @@ -22,6 +22,7 @@ from stgit.commands.common import * from stgit import argparse, git help = 'Show the commit corresponding to a patch' +kind = 'patch' usage = ['[options] [] [] [..]'] description = """ Show the commit log and the diff corresponding to the given patches. diff --git a/stgit/commands/sink.py b/stgit/commands/sink.py index bf13f2b..95a43e1 100644 --- a/stgit/commands/sink.py +++ b/stgit/commands/sink.py @@ -23,6 +23,7 @@ from stgit.utils import * from stgit import stack, git help = 'Send patches deeper down the stack' +kind = 'stack' usage = ['[-t ] [-n] []'] description = """ This is the opposite operation of stglink:float[]: move the specified diff --git a/stgit/commands/status.py b/stgit/commands/status.py index eadb507..7c68ba6 100644 --- a/stgit/commands/status.py +++ b/stgit/commands/status.py @@ -23,6 +23,7 @@ from stgit.utils import * from stgit import stack, git help = 'Show the tree status' +kind = 'wc' usage = ['[options] []'] description = """ Show the status of the whole working copy or the given files. The diff --git a/stgit/commands/sync.py b/stgit/commands/sync.py index ef94439..767b4d2 100644 --- a/stgit/commands/sync.py +++ b/stgit/commands/sync.py @@ -24,6 +24,7 @@ from stgit.out import * from stgit import stack, git help = 'Synchronise patches with a branch or a series' +kind = 'patch' usage = ['[options] [] [] [..]'] description = """ For each of the specified patches perform a three-way merge with the diff --git a/stgit/commands/top.py b/stgit/commands/top.py index f4962e7..523afa4 100644 --- a/stgit/commands/top.py +++ b/stgit/commands/top.py @@ -21,6 +21,7 @@ from stgit.commands import common from stgit.out import out help = 'Print the name of the top patch' +kind = 'stack' usage = [''] description = """ Print the name of the current (topmost) patch.""" diff --git a/stgit/commands/uncommit.py b/stgit/commands/uncommit.py index 19ec3c9..c44385d 100644 --- a/stgit/commands/uncommit.py +++ b/stgit/commands/uncommit.py @@ -24,6 +24,7 @@ from stgit.out import * from stgit import utils help = 'Turn regular git commits into StGit patches' +kind = 'stack' usage = [' [ ...]', '-n NUM []', '-t [-x]'] diff --git a/stgit/commands/unhide.py b/stgit/commands/unhide.py index 6c624d0..c34bc1d 100644 --- a/stgit/commands/unhide.py +++ b/stgit/commands/unhide.py @@ -23,6 +23,7 @@ from stgit.out import * from stgit import stack, git help = 'Unhide a hidden patch' +kind = 'stack' usage = ['[options] '] description = """ Unhide a hidden range of patches so that they are shown in the plain diff --git a/stgit/main.py b/stgit/main.py index 55c467c..48d8dbb 100644 --- a/stgit/main.py +++ b/stgit/main.py @@ -48,107 +48,13 @@ class Commands(dict): return candidates[0] def __getitem__(self, key): - """Return the command python module name based. - """ - global prog - cmd_mod = self.get(key) or self.get(self.canonical_cmd(key)) - - __import__('stgit.commands.' + cmd_mod) - return getattr(stgit.commands, cmd_mod) - -commands = Commands({ - 'branch': 'branch', - 'delete': 'delete', - 'diff': 'diff', - 'clean': 'clean', - 'clone': 'clone', - 'coalesce': 'coalesce', - 'commit': 'commit', - 'edit': 'edit', - 'export': 'export', - 'files': 'files', - 'float': 'float', - 'fold': 'fold', - 'goto': 'goto', - 'hide': 'hide', - 'id': 'id', - 'import': 'imprt', - 'init': 'init', - 'log': 'log', - 'mail': 'mail', - 'new': 'new', - 'patches': 'patches', - 'pick': 'pick', - 'pop': 'pop', - 'pull': 'pull', - 'push': 'push', - 'rebase': 'rebase', - 'refresh': 'refresh', - 'rename': 'rename', - 'repair': 'repair', - 'resolved': 'resolved', - 'series': 'series', - 'show': 'show', - 'sink': 'sink', - 'status': 'status', - 'sync': 'sync', - 'top': 'top', - 'uncommit': 'uncommit', - 'unhide': 'unhide' - }) + return stgit.commands.get_command(cmd_mod) -# classification: repository, stack, patch, working copy -repocommands = ( - 'clone', - 'id', - ) -stackcommands = ( - 'branch', - 'clean', - 'coalesce', - 'commit', - 'float', - 'goto', - 'hide', - 'init', - 'patches', - 'pop', - 'pull', - 'push', - 'rebase', - 'repair', - 'series', - 'sink', - 'top', - 'uncommit', - 'unhide', - ) -patchcommands = ( - 'delete', - 'edit', - 'export', - 'files', - 'fold', - 'import', - 'log', - 'mail', - 'new', - 'pick', - 'refresh', - 'rename', - 'show', - 'sync', - ) -wccommands = ( - 'diff', - 'resolved', - 'status', - ) +cmd_list = stgit.commands.get_commands() +commands = Commands((cmd, mod) for cmd, (mod, kind, help) + in cmd_list.iteritems()) -def _print_helpstring(cmd): - print ' ' + cmd + ' ' * (12 - len(cmd)) + commands[cmd].help - def print_help(): print 'usage: %s [options]' % os.path.basename(sys.argv[0]) print @@ -156,33 +62,8 @@ def print_help(): print ' help print the detailed command usage' print ' version display version information' print ' copyright display copyright information' - # unclassified commands if any - cmds = commands.keys() - cmds.sort() - for cmd in cmds: - if not cmd in repocommands and not cmd in stackcommands \ - and not cmd in patchcommands and not cmd in wccommands: - _print_helpstring(cmd) - print - - print 'Repository commands:' - for cmd in repocommands: - _print_helpstring(cmd) print - - print 'Stack commands:' - for cmd in stackcommands: - _print_helpstring(cmd) - print - - print 'Patch commands:' - for cmd in patchcommands: - _print_helpstring(cmd) - print - - print 'Working-copy commands:' - for cmd in wccommands: - _print_helpstring(cmd) + stgit.commands.pretty_command_list(cmd_list, sys.stdout) # # The main function (command dispatcher) -- 2.11.0