chiark / gitweb /
ea65288299ff46bdb59c5adb5861acfd7d4cc739
[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.float
42 import stgit.commands.fold
43 import stgit.commands.goto
44 import stgit.commands.id
45 import stgit.commands.imprt
46 import stgit.commands.init
47 import stgit.commands.log
48 import stgit.commands.mail
49 import stgit.commands.new
50 import stgit.commands.patches
51 import stgit.commands.pick
52 import stgit.commands.pop
53 import stgit.commands.pull
54 import stgit.commands.push
55 import stgit.commands.refresh
56 import stgit.commands.rename
57 import stgit.commands.resolved
58 import stgit.commands.rm
59 import stgit.commands.series
60 import stgit.commands.show
61 import stgit.commands.status
62 import stgit.commands.top
63 import stgit.commands.unapplied
64 import stgit.commands.uncommit
65
66
67 #
68 # The commands map
69 #
70 commands = {
71     'add':      stgit.commands.add,
72     'applied':  stgit.commands.applied,
73     'branch':   stgit.commands.branch,
74     'delete':   stgit.commands.delete,
75     'diff':     stgit.commands.diff,
76     'clean':    stgit.commands.clean,
77     'clone':    stgit.commands.clone,
78     'commit':   stgit.commands.commit,
79     'export':   stgit.commands.export,
80     'files':    stgit.commands.files,
81     'float':    stgit.commands.float,
82     'fold':     stgit.commands.fold,
83     'goto':     stgit.commands.goto,
84     'id':       stgit.commands.id,
85     'import':   stgit.commands.imprt,
86     'init':     stgit.commands.init,
87     'log':      stgit.commands.log,
88     'mail':     stgit.commands.mail,
89     'new':      stgit.commands.new,
90     'patches':  stgit.commands.patches,
91     'pick':     stgit.commands.pick,
92     'pop':      stgit.commands.pop,
93     'pull':     stgit.commands.pull,
94     'push':     stgit.commands.push,
95     'refresh':  stgit.commands.refresh,
96     'rename':   stgit.commands.rename,
97     'resolved': stgit.commands.resolved,
98     'rm':       stgit.commands.rm,
99     'series':   stgit.commands.series,
100     'show':     stgit.commands.show,
101     'status':   stgit.commands.status,
102     'top':      stgit.commands.top,
103     'unapplied':stgit.commands.unapplied,
104     'uncommit': stgit.commands.uncommit,
105     }
106
107 # classification: repository, stack, patch, working copy
108 repocommands = (
109     'branch',
110     'clone',
111     'id',
112     'pull'
113     )
114 stackcommands = (
115     'applied',
116     'clean',
117     'commit',
118     'float',
119     'goto',
120     'init',
121     'pop',
122     'push',
123     'series',
124     'top',
125     'unapplied',
126     'uncommit'
127     )
128 patchcommands = (
129     'delete',
130     'export',
131     'files',
132     'fold',
133     'import',
134     'log',
135     'mail',
136     'new',
137     'pick',
138     'refresh',
139     'rename',
140     'show'
141     )
142 wccommands = (
143     'add',
144     'diff',
145     'patches',
146     'resolved',
147     'rm',
148     'status'
149     )
150
151 def _print_helpstring(cmd):
152     print '  ' + cmd + ' ' * (12 - len(cmd)) + commands[cmd].help
153     
154 def print_help():
155     print 'usage: %s <command> [options]' % os.path.basename(sys.argv[0])
156     print
157     print 'Generic commands:'
158     print '  help        print the detailed command usage'
159     print '  version     display version information'
160     print '  copyright   display copyright information'
161     # unclassified commands if any
162     cmds = commands.keys()
163     cmds.sort()
164     for cmd in cmds:
165         if not cmd in repocommands and not cmd in stackcommands \
166                and not cmd in patchcommands and not cmd in wccommands:
167             _print_helpstring(cmd)
168     print
169
170     print 'Repository commands:'
171     for cmd in repocommands:
172         _print_helpstring(cmd)
173     print
174     
175     print 'Stack commands:'
176     for cmd in stackcommands:
177         _print_helpstring(cmd)
178     print
179
180     print 'Patch commands:'
181     for cmd in patchcommands:
182         _print_helpstring(cmd)
183     print
184
185     print 'Working-copy commands:'
186     for cmd in wccommands:
187         _print_helpstring(cmd)
188
189 #
190 # The main function (command dispatcher)
191 #
192 def main():
193     """The main function
194     """
195     prog = os.path.basename(sys.argv[0])
196
197     if len(sys.argv) < 2:
198         print >> sys.stderr, 'usage: %s <command>' % prog
199         print >> sys.stderr, \
200               '  Try "%s --help" for a list of supported commands' % prog
201         sys.exit(1)
202
203     cmd = sys.argv[1]
204
205     if cmd in ['-h', '--help']:
206         if len(sys.argv) == 3 and sys.argv[2] in commands:
207             cmd = sys.argv[2]
208             sys.argv[2] = '--help'
209         else:
210             print_help()
211             sys.exit(0)
212     if cmd == 'help':
213         if len(sys.argv) == 3 and not sys.argv[2] in ['-h', '--help']:
214             cmd = sys.argv[2]
215             if not cmd in commands:
216                 print >> sys.stderr, '%s help: "%s" command unknown' \
217                       % (prog, cmd)
218                 sys.exit(1)
219
220             sys.argv[0] += ' %s' % cmd
221             command = commands[cmd]
222             parser = OptionParser(usage = command.usage,
223                                   option_list = command.options)
224             parser.print_help()
225         else:
226             print_help()
227         sys.exit(0)
228     if cmd in ['-v', '--version', 'version']:
229         print 'Stacked GIT %s' % version
230         os.system('git --version')
231         print 'Python version %s' % sys.version
232         sys.exit(0)
233     if cmd in ['copyright']:
234         print __copyright__
235         sys.exit(0)
236     if not cmd in commands:
237         print >> sys.stderr, 'Unknown command: %s' % cmd
238         print >> sys.stderr, '  Try "%s help" for a list of supported ' \
239               'commands' % prog
240         sys.exit(1)
241
242     # re-build the command line arguments
243     sys.argv[0] += ' %s' % cmd
244     del(sys.argv[1])
245
246     command = commands[cmd]
247     usage = command.usage.split('\n')[0].strip()
248     parser = OptionParser(usage = usage, option_list = command.options)
249     options, args = parser.parse_args()
250     try:
251         # 'clone' doesn't expect an already initialised GIT tree. A Series
252         # object will be created after the GIT tree is cloned
253         if cmd != 'clone':
254             if hasattr(options, 'branch') and options.branch:
255                 command.crt_series = stack.Series(options.branch)
256             else:
257                 command.crt_series = stack.Series()
258             stgit.commands.common.crt_series = command.crt_series
259
260         command.func(parser, options, args)
261     except (IOError, CmdException, stack.StackException, git.GitException,
262             gitmergeonefile.GitMergeException), err:
263         print >> sys.stderr, '%s %s: %s' % (prog, cmd, err)
264         sys.exit(2)
265     except KeyboardInterrupt:
266         sys.exit(1)
267
268     sys.exit(0)