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
21 import sys
, os
, traceback
24 from stgit
.out
import *
25 from stgit
import argparse
, run
, utils
26 from stgit
.config
import config
28 class CommandAlias(object):
29 def __init__(self
, name
, command
):
30 self
.__command
= command
32 self
.usage
= ['<arguments>']
33 self
.help = 'Alias for "%s <arguments>".' % self
.__command
37 cmd
= self
.__command
.split() + args
39 p
.discard_exitcode().run()
42 def is_cmd_alias(cmd
):
43 return isinstance(cmd
, CommandAlias
)
45 def append_alias_commands(cmd_list
):
46 for (name
, command
) in config
.getstartswith('stgit.alias.'):
47 name
= utils
.strip_prefix('stgit.alias.', name
)
48 cmd_list
[name
] = (CommandAlias(name
, command
),
49 'Alias commands', command
)
55 """Commands class. It performs on-demand module loading
57 def canonical_cmd(self
, key
):
58 """Return the canonical name for a possibly-shortenned
61 candidates
= [cmd
for cmd
in self
.keys() if cmd
.startswith(key
)]
64 out
.error('Unknown command: %s' % key
,
65 'Try "%s help" for a list of supported commands' % prog
)
66 sys
.exit(utils
.STGIT_GENERAL_ERROR
)
67 elif len(candidates
) > 1:
68 out
.error('Ambiguous command: %s' % key
,
69 'Candidates are: %s' %
', '.join(candidates
))
70 sys
.exit(utils
.STGIT_GENERAL_ERROR
)
74 def __getitem__(self
, key
):
75 cmd_mod
= self
.get(key
) or self
.get(self
.canonical_cmd(key
))
76 if is_cmd_alias(cmd_mod
):
79 return stgit
.commands
.get_command(cmd_mod
)
81 cmd_list
= stgit
.commands
.get_commands()
82 append_alias_commands(cmd_list
)
83 commands
= Commands((cmd
, mod
) for cmd
, (mod
, kind
, help)
84 in cmd_list
.iteritems())
87 print 'usage: %s <command> [options]' % os
.path
.basename(sys
.argv
[0])
89 print 'Generic commands:'
90 print ' help print the detailed command usage'
91 print ' version display version information'
92 print ' copyright display copyright information'
94 stgit
.commands
.pretty_command_list(cmd_list
, sys
.stdout
)
97 # The main function (command dispatcher)
104 prog
= os
.path
.basename(sys
.argv
[0])
106 if len(sys
.argv
) < 2:
107 print >> sys
.stderr
, 'usage: %s <command>' % prog
108 print >> sys
.stderr
, \
109 ' Try "%s --help" for a list of supported commands' % prog
110 sys
.exit(utils
.STGIT_GENERAL_ERROR
)
114 if cmd
in ['-h', '--help']:
115 if len(sys
.argv
) >= 3:
116 cmd
= commands
.canonical_cmd(sys
.argv
[2])
117 sys
.argv
[2] = '--help'
120 sys
.exit(utils
.STGIT_SUCCESS
)
122 if len(sys
.argv
) == 3 and not sys
.argv
[2] in ['-h', '--help']:
123 cmd
= commands
.canonical_cmd(sys
.argv
[2])
124 if not cmd
in commands
:
125 out
.error('%s help: "%s" command unknown' %
(prog
, cmd
))
126 sys
.exit(utils
.STGIT_GENERAL_ERROR
)
128 sys
.argv
[0] += ' %s' % cmd
129 command
= commands
[cmd
]
130 parser
= argparse
.make_option_parser(command
)
131 if is_cmd_alias(command
):
132 parser
.remove_option('-h')
133 from pydoc
import pager
134 pager(parser
.format_help())
137 sys
.exit(utils
.STGIT_SUCCESS
)
138 if cmd
in ['-v', '--version', 'version']:
139 from stgit
.version
import version
140 print 'Stacked GIT %s' % version
141 os
.system('git --version')
142 print 'Python version %s' % sys
.version
143 sys
.exit(utils
.STGIT_SUCCESS
)
144 if cmd
in ['copyright']:
146 sys
.exit(utils
.STGIT_SUCCESS
)
148 # re-build the command line arguments
149 cmd
= commands
.canonical_cmd(cmd
)
150 sys
.argv
[0] += ' %s' % cmd
153 command
= commands
[cmd
]
154 if is_cmd_alias(command
):
155 sys
.exit(command
.func(sys
.argv
[1:]))
157 parser
= argparse
.make_option_parser(command
)
158 options
, args
= parser
.parse_args()
159 directory
= command
.directory
161 # These modules are only used from this point onwards and do not
162 # need to be imported earlier
163 from stgit
.exception
import StgException
164 from stgit
.config
import config_setup
165 from ConfigParser
import ParsingError
, NoSectionError
166 from stgit
.stack
import Series
169 debug_level
= int(os
.environ
.get('STGIT_DEBUG_LEVEL', 0))
171 out
.error('Invalid STGIT_DEBUG_LEVEL environment variable')
172 sys
.exit(utils
.STGIT_GENERAL_ERROR
)
178 # Some commands don't (always) need an initialized series.
179 if directory
.needs_current_series
:
180 if hasattr(options
, 'branch') and options
.branch
:
181 command
.crt_series
= Series(options
.branch
)
183 command
.crt_series
= Series()
185 ret
= command
.func(parser
, options
, args
)
186 except (StgException
, IOError, ParsingError
, NoSectionError
), err
:
187 directory
.write_log(cmd
)
188 out
.error(str(err
), title
= '%s %s' %
(prog
, cmd
))
190 traceback
.print_exc()
191 sys
.exit(utils
.STGIT_COMMAND_ERROR
)
193 # Triggered by the option parser when it finds bad commandline
195 sys
.exit(utils
.STGIT_COMMAND_ERROR
)
196 except KeyboardInterrupt:
197 sys
.exit(utils
.STGIT_GENERAL_ERROR
)
199 out
.error('Unhandled exception:')
200 traceback
.print_exc()
201 sys
.exit(utils
.STGIT_BUG_ERROR
)
203 directory
.write_log(cmd
)
204 sys
.exit(ret
or utils
.STGIT_SUCCESS
)