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',
91 'resolved': 'resolved',
99 'unapplied': 'unapplied',
100 'uncommit': 'uncommit',
104 # classification: repository, stack, patch, working copy
155 def _print_helpstring(cmd):
156 print ' ' + cmd + ' ' * (12 - len(cmd)) + commands[cmd].help
159 print 'usage: %s <command> [options]' % os.path.basename(sys.argv[0])
161 print 'Generic commands:'
162 print ' help print the detailed command usage'
163 print ' version display version information'
164 print ' copyright display copyright information'
165 # unclassified commands if any
166 cmds = commands.keys()
169 if not cmd in repocommands and not cmd in stackcommands \
170 and not cmd in patchcommands and not cmd in wccommands:
171 _print_helpstring(cmd)
174 print 'Repository commands:'
175 for cmd in repocommands:
176 _print_helpstring(cmd)
179 print 'Stack commands:'
180 for cmd in stackcommands:
181 _print_helpstring(cmd)
184 print 'Patch commands:'
185 for cmd in patchcommands:
186 _print_helpstring(cmd)
189 print 'Working-copy commands:'
190 for cmd in wccommands:
191 _print_helpstring(cmd)
194 # The main function (command dispatcher)
201 prog = os.path.basename(sys.argv[0])
203 if len(sys.argv) < 2:
204 print >> sys.stderr, 'usage: %s <command>' % prog
205 print >> sys.stderr, \
206 ' Try "%s --help" for a list of supported commands' % prog
211 if cmd in ['-h', '--help']:
212 if len(sys.argv) >= 3:
213 cmd = commands.canonical_cmd(sys.argv[2])
214 sys.argv[2] = '--help'
219 if len(sys.argv) == 3 and not sys.argv[2] in ['-h', '--help']:
220 cmd = commands.canonical_cmd(sys.argv[2])
221 if not cmd in commands:
222 out.error('%s help: "%s" command unknown' % (prog, cmd))
225 sys.argv[0] += ' %s' % cmd
226 command = commands[cmd]
227 parser = OptionParser(usage = command.usage,
228 option_list = command.options)
229 from pydoc import pager
230 pager(parser.format_help())
234 if cmd in ['-v', '--version', 'version']:
235 from stgit.version import version
236 print 'Stacked GIT %s' % version
237 os.system('git --version')
238 print 'Python version %s' % sys.version
240 if cmd in ['copyright']:
244 # re-build the command line arguments
245 cmd = commands.canonical_cmd(cmd)
246 sys.argv[0] += ' %s' % cmd
249 command = commands[cmd]
250 usage = command.usage.split('\n')[0].strip()
251 parser = OptionParser(usage = usage, option_list = command.options)
252 options, args = parser.parse_args()
254 # These modules are only used from this point onwards and do not
255 # need to be imported earlier
256 from stgit.config import config_setup
257 from ConfigParser import ParsingError, NoSectionError
258 from stgit.stack import Series, StackException
259 from stgit.git import GitException
260 from stgit.commands.common import CmdException
261 from stgit.gitmergeonefile import GitMergeException
262 from stgit.utils import EditorException
265 debug_level = int(os.environ['STGIT_DEBUG_LEVEL'])
269 out.error('Invalid STGIT_DEBUG_LEVEL environment variable')
275 # 'clone' doesn't expect an already initialised GIT tree. A Series
276 # object will be created after the GIT tree is cloned
278 if hasattr(options, 'branch') and options.branch:
279 command.crt_series = Series(options.branch)
281 command.crt_series = Series()
282 stgit.commands.common.crt_series = command.crt_series
284 command.func(parser, options, args)
285 except (IOError, ParsingError, NoSectionError, CmdException,
286 StackException, GitException, GitMergeException,
287 EditorException), err:
288 print >> sys.stderr, '%s %s: %s' % (prog, cmd, err)
293 except KeyboardInterrupt: