Package logilab-common-0 ::
Package 39 ::
Package 0 ::
Module clcommands
|
|
1 """Helper functions to support command line tools providing more than
2 one command.
3
4 e.g called as "tool command [options] args..." where <options> and <args> are
5 command'specific
6
7 :copyright: 2003-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
8 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
9 :license: General Public License version 2 - http://www.gnu.org/licenses
10 """
11 __docformat__ = "restructuredtext en"
12
13
14 import sys
15 from os.path import basename
16
17 from logilab.common.configuration import Configuration
18
19
20 DEFAULT_COPYRIGHT = '''\
21 Copyright (c) 2004-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
22 http://www.logilab.fr/ -- mailto:contact@logilab.fr'''
23
24
25 DEFAULT_DOC = '''\
26 Type "%prog <command> --help" for more information about a specific
27 command. Available commands are :\n'''
28
30 """Raised when an unknown command is used or when a command is not
31 correctly used.
32 """
33
34
36 """Base class for command line commands."""
37 arguments = ''
38 name = ''
39
40 hidden = False
41
42 min_args = None
43 max_args = None
44 - def __init__(self, __doc__=None, version=None):
51
58
59 - def run(self, args):
60 """run the command with its specific arguments"""
61 raise NotImplementedError()
62
63
64 -def pop_arg(args_list, expected_size_after=0, msg="Missing argument"):
65 """helper function to get and check command line arguments"""
66 try:
67 value = args_list.pop(0)
68 except IndexError:
69 raise BadCommandUsage(msg)
70 if expected_size_after is not None and len(args_list) > expected_size_after:
71 raise BadCommandUsage('too many arguments')
72 return value
73
74
75 _COMMANDS = {}
76
78 """register existing commands"""
79 for command_klass in commands:
80 _COMMANDS[command_klass.name] = command_klass
81
82
83 -def main_usage(status=0, __doc__=DEFAULT_DOC, copyright=DEFAULT_COPYRIGHT):
84 """display usage for the main program (ie when no command supplied)
85 and exit
86 """
87 commands = _COMMANDS.keys()
88 commands.sort()
89 doc = __doc__
90 if doc != DEFAULT_DOC:
91 try:
92 doc = __doc__ % ('<command>', '<command arguments>',
93 '''\
94 Type "%prog <command> --help" for more information about a specific
95 command. Available commands are :\n''')
96 except TypeError:
97 print 'could not find the "command", "arguments" and "default" slots'
98 doc = doc.replace('%prog', basename(sys.argv[0]))
99 print 'usage:', doc
100 max_len = max([len(cmd) for cmd in commands])
101 padding = ' '*max_len
102 for command in commands:
103 cmd = _COMMANDS[command]
104 if not cmd.hidden:
105 title = cmd.__doc__.split('.')[0]
106 print ' ', (command+padding)[:max_len], title
107 print '\n', copyright
108 sys.exit(status)
109
110
125
126
127 -def main_run(args, doc=DEFAULT_DOC):
128 """command line tool"""
129 try:
130 arg = args.pop(0)
131 except IndexError:
132 main_usage(status=1, __doc__=doc)
133 if arg in ('-h', '--help'):
134 main_usage(__doc__=doc)
135 try:
136 cmd_run(arg, *args)
137 except BadCommandUsage, err:
138 print 'ERROR: ', err
139 main_usage(1, doc)
140
141
143 """list available commands, useful for bash completion."""
144 name = 'listcommands'
145 arguments = '[command]'
146 hidden = True
147
148 - def run(self, args):
149 """run the command with its specific arguments"""
150 if args:
151 command = pop_arg(args)
152 cmd = _COMMANDS[command]
153 for optname, optdict in cmd.options:
154 print '--help'
155 print '--' + optname
156 else:
157 commands = _COMMANDS.keys()
158 commands.sort()
159 for command in commands:
160 cmd = _COMMANDS[command]
161 if not cmd.hidden:
162 print command
163
164 register_commands([ListCommandsCommand])
165