Reduce the imports in stgit/main.py
[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.stack import Series, StackException
224 from stgit.git import GitException
225 from stgit.commands.common import CmdException
226 from stgit.gitmergeonefile import GitMergeException
227
228 try:
229 # 'clone' doesn't expect an already initialised GIT tree. A Series
230 # object will be created after the GIT tree is cloned
231 if cmd != 'clone':
232 if hasattr(options, 'branch') and options.branch:
233 command.crt_series = Series(options.branch)
234 else:
235 command.crt_series = Series()
236 stgit.commands.common.crt_series = command.crt_series
237
238 command.func(parser, options, args)
239 except (IOError, CmdException, StackException, GitException,
240 GitMergeException), err:
241 print >> sys.stderr, '%s %s: %s' % (prog, cmd, err)
242 sys.exit(2)
243 except KeyboardInterrupt:
244 sys.exit(1)
245
246 sys.exit(0)