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