1 """Basic quilt-like functionality
5 Copyright (C) 2005, Catalin Marinas <catalin.marinas@gmail.com>
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.
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.
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
22 from optparse import OptionParser
25 from stgit.out import *
31 """Commands class. It performs on-demand module loading
33 def canonical_cmd(self, key):
34 """Return the canonical name for a possibly-shortenned
37 candidates = [cmd for cmd in self.keys() if cmd.startswith(key)]
40 out.error('Unknown command: %s' % key,
41 'Try "%s help" for a list of supported commands' % prog)
43 elif len(candidates) > 1:
44 out.error('Ambiguous command: %s' % key,
45 'Candidates are: %s' % ', '.join(candidates))
50 def __getitem__(self, key):
51 """Return the command python module name based.
55 cmd_mod = self.get(key) or self.get(self.canonical_cmd(key))
57 __import__('stgit.commands.' + cmd_mod)
58 return getattr(stgit.commands, cmd_mod)
63 'assimilate': 'assimilate',
92 'resolved': 'resolved',
100 'unapplied': 'unapplied',
101 'uncommit': 'uncommit',
105 # classification: repository, stack, patch, working copy
157 def _print_helpstring(cmd):
158 print ' ' + cmd + ' ' * (12 - len(cmd)) + commands[cmd].help
161 print 'usage: %s <command> [options]' % os.path.basename(sys.argv[0])
163 print 'Generic commands:'
164 print ' help print the detailed command usage'
165 print ' version display version information'
166 print ' copyright display copyright information'
167 # unclassified commands if any
168 cmds = commands.keys()
171 if not cmd in repocommands and not cmd in stackcommands \
172 and not cmd in patchcommands and not cmd in wccommands:
173 _print_helpstring(cmd)
176 print 'Repository commands:'
177 for cmd in repocommands:
178 _print_helpstring(cmd)
181 print 'Stack commands:'
182 for cmd in stackcommands:
183 _print_helpstring(cmd)
186 print 'Patch commands:'
187 for cmd in patchcommands:
188 _print_helpstring(cmd)
191 print 'Working-copy commands:'
192 for cmd in wccommands:
193 _print_helpstring(cmd)
196 # The main function (command dispatcher)
203 prog = os.path.basename(sys.argv[0])
205 if len(sys.argv) < 2:
206 print >> sys.stderr, 'usage: %s <command>' % prog
207 print >> sys.stderr, \
208 ' Try "%s --help" for a list of supported commands' % prog
213 if cmd in ['-h', '--help']:
214 if len(sys.argv) >= 3:
215 cmd = commands.canonical_cmd(sys.argv[2])
216 sys.argv[2] = '--help'
221 if len(sys.argv) == 3 and not sys.argv[2] in ['-h', '--help']:
222 cmd = commands.canonical_cmd(sys.argv[2])
223 if not cmd in commands:
224 out.error('%s help: "%s" command unknown' % (prog, cmd))
227 sys.argv[0] += ' %s' % cmd
228 command = commands[cmd]
229 parser = OptionParser(usage = command.usage,
230 option_list = command.options)
231 from pydoc import pager
232 pager(parser.format_help())
236 if cmd in ['-v', '--version', 'version']:
237 from stgit.version import version
238 print 'Stacked GIT %s' % version
239 os.system('git --version')
240 print 'Python version %s' % sys.version
242 if cmd in ['copyright']:
246 # re-build the command line arguments
247 cmd = commands.canonical_cmd(cmd)
248 sys.argv[0] += ' %s' % cmd
251 command = commands[cmd]
252 usage = command.usage.split('\n')[0].strip()
253 parser = OptionParser(usage = usage, option_list = command.options)
254 options, args = parser.parse_args()
256 # These modules are only used from this point onwards and do not
257 # need to be imported earlier
258 from stgit.config import config_setup
259 from ConfigParser import ParsingError, NoSectionError
260 from stgit.stack import Series, StackException
261 from stgit.git import GitException
262 from stgit.commands.common import CmdException
263 from stgit.gitmergeonefile import GitMergeException
264 from stgit.utils import EditorException
267 debug_level = int(os.environ['STGIT_DEBUG_LEVEL'])
271 out.error('Invalid STGIT_DEBUG_LEVEL environment variable')
277 # 'clone' doesn't expect an already initialised GIT tree. A Series
278 # object will be created after the GIT tree is cloned
280 if hasattr(options, 'branch') and options.branch:
281 command.crt_series = Series(options.branch)
283 command.crt_series = Series()
284 stgit.commands.common.crt_series = command.crt_series
286 command.func(parser, options, args)
287 except (IOError, ParsingError, NoSectionError, CmdException,
288 StackException, GitException, GitMergeException,
289 EditorException), err:
290 print >> sys.stderr, '%s %s: %s' % (prog, cmd, err)
295 except KeyboardInterrupt: