chiark / gitweb /
Automatically generate patch names for uncommit
[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)