Classify commands in stg --help output.
[stgit] / stgit / main.py
1 """Basic quilt-like functionality
2 """
3
4 __copyright__ = """
5 Copyright (C) 2005, Catalin Marinas <catalin.marinas@gmail.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 """
20
21 import sys, os
22 from optparse import OptionParser, make_option
23
24 from stgit.utils import *
25 from stgit import stack, git, gitmergeonefile
26 from stgit.version import version
27 from stgit.config import config
28 from stgit.commands.common import *
29
30 # The commands
31 import stgit.commands.add
32 import stgit.commands.applied
33 import stgit.commands.branch
34 import stgit.commands.delete
35 import stgit.commands.diff
36 import stgit.commands.clean
37 import stgit.commands.clone
38 import stgit.commands.commit
39 import stgit.commands.export
40 import stgit.commands.files
41 import stgit.commands.fold
42 import stgit.commands.goto
43 import stgit.commands.id
44 import stgit.commands.imprt
45 import stgit.commands.init
46 import stgit.commands.mail
47 import stgit.commands.new
48 import stgit.commands.patches
49 import stgit.commands.pick
50 import stgit.commands.pop
51 import stgit.commands.pull
52 import stgit.commands.push
53 import stgit.commands.refresh
54 import stgit.commands.rename
55 import stgit.commands.resolved
56 import stgit.commands.rm
57 import stgit.commands.series
58 import stgit.commands.show
59 import stgit.commands.status
60 import stgit.commands.top
61 import stgit.commands.unapplied
62 import stgit.commands.uncommit
63
64
65 #
66 # The commands map
67 #
68 commands = {
69 'add': stgit.commands.add,
70 'applied': stgit.commands.applied,
71 'branch': stgit.commands.branch,
72 'delete': stgit.commands.delete,
73 'diff': stgit.commands.diff,
74 'clean': stgit.commands.clean,
75 'clone': stgit.commands.clone,
76 'commit': stgit.commands.commit,
77 'export': stgit.commands.export,
78 'files': stgit.commands.files,
79 'fold': stgit.commands.fold,
80 'goto': stgit.commands.goto,
81 'id': stgit.commands.id,
82 'import': stgit.commands.imprt,
83 'init': stgit.commands.init,
84 'mail': stgit.commands.mail,
85 'new': stgit.commands.new,
86 'patches': stgit.commands.patches,
87 'pick': stgit.commands.pick,
88 'pop': stgit.commands.pop,
89 'pull': stgit.commands.pull,
90 'push': stgit.commands.push,
91 'refresh': stgit.commands.refresh,
92 'rename': stgit.commands.rename,
93 'resolved': stgit.commands.resolved,
94 'rm': stgit.commands.rm,
95 'series': stgit.commands.series,
96 'show': stgit.commands.show,
97 'status': stgit.commands.status,
98 'top': stgit.commands.top,
99 'unapplied':stgit.commands.unapplied,
100 'uncommit': stgit.commands.uncommit,
101 }
102
103 # classification: repository, stack, patch, working copy
104 repocommands = (
105 'branch',
106 'clone',
107 'id',
108 'pull'
109 )
110 stackcommands = (
111 'applied',
112 'clean',
113 'commit',
114 'goto',
115 'init',
116 'pop',
117 'push',
118 'series',
119 'top',
120 'unapplied',
121 'uncommit'
122 )
123 patchcommands = (
124 'delete',
125 'export',
126 'files',
127 'fold',
128 'import',
129 'mail',
130 'new',
131 'pick',
132 'refresh',
133 'rename',
134 'show'
135 )
136 wccommands = (
137 'add',
138 'diff',
139 'patches',
140 'resolved',
141 'rm',
142 'status'
143 )
144
145 def _print_helpstring(cmd):
146 print ' ' + cmd + ' ' * (12 - len(cmd)) + commands[cmd].help
147
148 def print_help():
149 print 'usage: %s <command> [options]' % os.path.basename(sys.argv[0])
150 print
151 print 'Generic commands:'
152 print ' help print the detailed command usage'
153 print ' version display version information'
154 print ' copyright display copyright information'
155 # unclassified commands if any
156 cmds = commands.keys()
157 cmds.sort()
158 for cmd in cmds:
159 if not cmd in repocommands and not cmd in stackcommands \
160 and not cmd in patchcommands and not cmd in wccommands:
161 _print_helpstring(cmd)
162 print
163
164 print 'Repository commands:'
165 for cmd in repocommands:
166 _print_helpstring(cmd)
167 print
168
169 print 'Stack commands:'
170 for cmd in stackcommands:
171 _print_helpstring(cmd)
172 print
173
174 print 'Patch commands:'
175 for cmd in patchcommands:
176 _print_helpstring(cmd)
177 print
178
179 print 'Working-copy commands:'
180 for cmd in wccommands:
181 _print_helpstring(cmd)
182
183 #
184 # The main function (command dispatcher)
185 #
186 def main():
187 """The main function
188 """
189 prog = os.path.basename(sys.argv[0])
190
191 if len(sys.argv) < 2:
192 print >> sys.stderr, 'Unknown command'
193 print >> sys.stderr, \
194 ' Try "%s --help" for a list of supported commands' % prog
195 sys.exit(1)
196
197 cmd = sys.argv[1]
198
199 if cmd in ['-h', '--help']:
200 if len(sys.argv) == 3 and sys.argv[2] in commands:
201 cmd = sys.argv[2]
202 sys.argv[2] = '--help'
203 else:
204 print_help()
205 sys.exit(0)
206 if cmd == 'help':
207 if len(sys.argv) == 3 and not sys.argv[2] in ['-h', '--help']:
208 cmd = sys.argv[2]
209 if not cmd in commands:
210 print >> sys.stderr, '%s help: "%s" command unknown' \
211 % (prog, cmd)
212 sys.exit(1)
213
214 sys.argv[0] += ' %s' % cmd
215 command = commands[cmd]
216 parser = OptionParser(usage = command.usage,
217 option_list = command.options)
218 parser.print_help()
219 else:
220 print 'usage: %s help <command>' % prog
221
222 sys.exit(0)
223 if cmd in ['-v', '--version', 'version']:
224 print 'Stacked GIT %s' % version
225 os.system('git --version')
226 print 'Python version %s' % sys.version
227 sys.exit(0)
228 if cmd in ['copyright']:
229 print __copyright__
230 sys.exit(0)
231 if not cmd in commands:
232 print >> sys.stderr, 'Unknown command: %s' % cmd
233 print >> sys.stderr, ' Try "%s help" for a list of supported ' \
234 'commands' % prog
235 sys.exit(1)
236
237 # re-build the command line arguments
238 sys.argv[0] += ' %s' % cmd
239 del(sys.argv[1])
240
241 command = commands[cmd]
242 usage = command.usage.split('\n')[0].strip()
243 parser = OptionParser(usage = usage, option_list = command.options)
244 options, args = parser.parse_args()
245 try:
246 # 'clone' doesn't expect an already initialised GIT tree. A Series
247 # object will be created after the GIT tree is cloned
248 if cmd != 'clone':
249 if hasattr(options, 'branch') and options.branch:
250 command.crt_series = stack.Series(options.branch)
251 else:
252 command.crt_series = stack.Series()
253 stgit.commands.common.crt_series = command.crt_series
254
255 command.func(parser, options, args)
256 except (IOError, CmdException, stack.StackException, git.GitException,
257 gitmergeonefile.GitMergeException), err:
258 print >> sys.stderr, '%s %s: %s' % (prog, cmd, err)
259 sys.exit(2)
260 except KeyboardInterrupt:
261 sys.exit(1)
262
263 sys.exit(0)