Remove "stg cp"
[stgit] / stgit / main.py
CommitLineData
41a6d859
CM
1"""Basic quilt-like functionality
2"""
3
4__copyright__ = """
5Copyright (C) 2005, Catalin Marinas <catalin.marinas@gmail.com>
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License version 2 as
9published by the Free Software Foundation.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19"""
20
21import sys, os
c333afcf 22from optparse import OptionParser
41a6d859 23
c333afcf 24import stgit.commands
5e888f30 25from stgit.out import *
5be69cd8 26from stgit import utils
41a6d859 27
41a6d859
CM
28#
29# The commands map
30#
c333afcf
CM
31class Commands(dict):
32 """Commands class. It performs on-demand module loading
33 """
78340ff1
YD
34 def canonical_cmd(self, key):
35 """Return the canonical name for a possibly-shortenned
36 command name.
37 """
38 candidates = [cmd for cmd in self.keys() if cmd.startswith(key)]
39
40 if not candidates:
27ac2b7e
KH
41 out.error('Unknown command: %s' % key,
42 'Try "%s help" for a list of supported commands' % prog)
5be69cd8 43 sys.exit(utils.STGIT_GENERAL_ERROR)
78340ff1 44 elif len(candidates) > 1:
27ac2b7e
KH
45 out.error('Ambiguous command: %s' % key,
46 'Candidates are: %s' % ', '.join(candidates))
5be69cd8 47 sys.exit(utils.STGIT_GENERAL_ERROR)
78340ff1
YD
48
49 return candidates[0]
50
c333afcf 51 def __getitem__(self, key):
514dd4f2
CM
52 """Return the command python module name based.
53 """
54 global prog
55
78340ff1 56 cmd_mod = self.get(key) or self.get(self.canonical_cmd(key))
514dd4f2 57
c333afcf
CM
58 __import__('stgit.commands.' + cmd_mod)
59 return getattr(stgit.commands, cmd_mod)
60
61commands = Commands({
c333afcf 62 'applied': 'applied',
c333afcf
CM
63 'branch': 'branch',
64 'delete': 'delete',
65 'diff': 'diff',
66 'clean': 'clean',
67 'clone': 'clone',
68 'commit': 'commit',
ed60fdae 69 'edit': 'edit',
c333afcf
CM
70 'export': 'export',
71 'files': 'files',
72 'float': 'float',
73 'fold': 'fold',
74 'goto': 'goto',
841c7b2a 75 'hide': 'hide',
c333afcf
CM
76 'id': 'id',
77 'import': 'imprt',
78 'init': 'init',
79 'log': 'log',
80 'mail': 'mail',
81 'new': 'new',
82 'patches': 'patches',
83 'pick': 'pick',
84 'pop': 'pop',
85 'pull': 'pull',
86 'push': 'push',
22037590 87 'rebase': 'rebase',
c333afcf
CM
88 'refresh': 'refresh',
89 'rename': 'rename',
051090dd 90 'repair': 'repair',
c333afcf 91 'resolved': 'resolved',
c333afcf
CM
92 'series': 'series',
93 'show': 'show',
6f1c5e3c 94 'sink': 'sink',
c333afcf 95 'status': 'status',
06848fab 96 'sync': 'sync',
c333afcf
CM
97 'top': 'top',
98 'unapplied': 'unapplied',
841c7b2a
CM
99 'uncommit': 'uncommit',
100 'unhide': 'unhide'
c333afcf 101 })
41a6d859 102
5dc51fea
YD
103# classification: repository, stack, patch, working copy
104repocommands = (
5dc51fea
YD
105 'clone',
106 'id',
5dc51fea
YD
107 )
108stackcommands = (
109 'applied',
4ec67741 110 'branch',
5dc51fea
YD
111 'clean',
112 'commit',
d98a499c 113 'float',
5dc51fea 114 'goto',
841c7b2a 115 'hide',
5dc51fea 116 'init',
4ec67741 117 'patches',
5dc51fea 118 'pop',
4ec67741 119 'pull',
5dc51fea 120 'push',
22037590 121 'rebase',
051090dd 122 'repair',
5dc51fea 123 'series',
6f1c5e3c 124 'sink',
5dc51fea
YD
125 'top',
126 'unapplied',
841c7b2a 127 'uncommit',
4ec67741 128 'unhide',
5dc51fea
YD
129 )
130patchcommands = (
131 'delete',
d8b2e601 132 'edit',
5dc51fea
YD
133 'export',
134 'files',
135 'fold',
136 'import',
64354a2d 137 'log',
5dc51fea
YD
138 'mail',
139 'new',
140 'pick',
141 'refresh',
142 'rename',
06848fab 143 'show',
4ec67741 144 'sync',
5dc51fea
YD
145 )
146wccommands = (
5dc51fea 147 'diff',
5dc51fea 148 'resolved',
4ec67741 149 'status',
5dc51fea
YD
150 )
151
152def _print_helpstring(cmd):
153 print ' ' + cmd + ' ' * (12 - len(cmd)) + commands[cmd].help
154
41a6d859
CM
155def print_help():
156 print 'usage: %s <command> [options]' % os.path.basename(sys.argv[0])
157 print
5dc51fea 158 print 'Generic commands:'
f0699cc7 159 print ' help print the detailed command usage'
1e0bdf2a 160 print ' version display version information'
22ea9102 161 print ' copyright display copyright information'
5dc51fea 162 # unclassified commands if any
41a6d859
CM
163 cmds = commands.keys()
164 cmds.sort()
165 for cmd in cmds:
5dc51fea
YD
166 if not cmd in repocommands and not cmd in stackcommands \
167 and not cmd in patchcommands and not cmd in wccommands:
168 _print_helpstring(cmd)
169 print
170
171 print 'Repository commands:'
172 for cmd in repocommands:
173 _print_helpstring(cmd)
174 print
175
176 print 'Stack commands:'
177 for cmd in stackcommands:
178 _print_helpstring(cmd)
179 print
180
181 print 'Patch commands:'
182 for cmd in patchcommands:
183 _print_helpstring(cmd)
184 print
185
186 print 'Working-copy commands:'
187 for cmd in wccommands:
188 _print_helpstring(cmd)
41a6d859
CM
189
190#
191# The main function (command dispatcher)
192#
193def main():
194 """The main function
195 """
514dd4f2
CM
196 global prog
197
41a6d859
CM
198 prog = os.path.basename(sys.argv[0])
199
200 if len(sys.argv) < 2:
d00e708a 201 print >> sys.stderr, 'usage: %s <command>' % prog
41a6d859 202 print >> sys.stderr, \
f0699cc7 203 ' Try "%s --help" for a list of supported commands' % prog
5be69cd8 204 sys.exit(utils.STGIT_GENERAL_ERROR)
41a6d859
CM
205
206 cmd = sys.argv[1]
207
f0699cc7 208 if cmd in ['-h', '--help']:
78340ff1
YD
209 if len(sys.argv) >= 3:
210 cmd = commands.canonical_cmd(sys.argv[2])
f0699cc7 211 sys.argv[2] = '--help'
31c5abf2
PR
212 else:
213 print_help()
5be69cd8 214 sys.exit(utils.STGIT_SUCCESS)
f0699cc7
CM
215 if cmd == 'help':
216 if len(sys.argv) == 3 and not sys.argv[2] in ['-h', '--help']:
78340ff1 217 cmd = commands.canonical_cmd(sys.argv[2])
f0699cc7 218 if not cmd in commands:
27ac2b7e 219 out.error('%s help: "%s" command unknown' % (prog, cmd))
5be69cd8 220 sys.exit(utils.STGIT_GENERAL_ERROR)
f0699cc7
CM
221
222 sys.argv[0] += ' %s' % cmd
223 command = commands[cmd]
224 parser = OptionParser(usage = command.usage,
225 option_list = command.options)
0d4cd7ce
CM
226 from pydoc import pager
227 pager(parser.format_help())
f0699cc7 228 else:
4fe42e63 229 print_help()
5be69cd8 230 sys.exit(utils.STGIT_SUCCESS)
1e0bdf2a 231 if cmd in ['-v', '--version', 'version']:
c333afcf 232 from stgit.version import version
4df2f866 233 print 'Stacked GIT %s' % version
50725547 234 os.system('git --version')
1e0bdf2a 235 print 'Python version %s' % sys.version
5be69cd8 236 sys.exit(utils.STGIT_SUCCESS)
22ea9102
CM
237 if cmd in ['copyright']:
238 print __copyright__
5be69cd8 239 sys.exit(utils.STGIT_SUCCESS)
41a6d859
CM
240
241 # re-build the command line arguments
3faeaeb1
CM
242 cmd = commands.canonical_cmd(cmd)
243 sys.argv[0] += ' %s' % cmd
41a6d859
CM
244 del(sys.argv[1])
245
246 command = commands[cmd]
f0699cc7
CM
247 usage = command.usage.split('\n')[0].strip()
248 parser = OptionParser(usage = usage, option_list = command.options)
41a6d859 249 options, args = parser.parse_args()
6dd8fafa 250 directory = command.directory
22d87516
CM
251
252 # These modules are only used from this point onwards and do not
253 # need to be imported earlier
87c93eab 254 from stgit.exception import StgException
eee7283e 255 from stgit.config import config_setup
9e3f506f 256 from ConfigParser import ParsingError, NoSectionError
87c93eab 257 from stgit.stack import Series
22d87516 258
41a6d859 259 try:
4200335f 260 debug_level = int(os.environ.get('STGIT_DEBUG_LEVEL', 0))
b2017c38 261 except ValueError:
27ac2b7e 262 out.error('Invalid STGIT_DEBUG_LEVEL environment variable')
5be69cd8 263 sys.exit(utils.STGIT_GENERAL_ERROR)
b2017c38
CM
264
265 try:
6dd8fafa 266 directory.setup()
eee7283e
CM
267 config_setup()
268
44a01a58
KH
269 # Some commands don't (always) need an initialized series.
270 if directory.needs_current_series:
98290387 271 if hasattr(options, 'branch') and options.branch:
c333afcf 272 command.crt_series = Series(options.branch)
98290387 273 else:
c333afcf 274 command.crt_series = Series()
9ac09909 275
41a6d859 276 command.func(parser, options, args)
87c93eab 277 except (StgException, IOError, ParsingError, NoSectionError), err:
762f6c8c 278 out.error(str(err), title = '%s %s' % (prog, cmd))
fe104619 279 if debug_level > 0:
b2017c38
CM
280 raise
281 else:
5be69cd8 282 sys.exit(utils.STGIT_COMMAND_ERROR)
4d9fc826 283 except KeyboardInterrupt:
5be69cd8 284 sys.exit(utils.STGIT_GENERAL_ERROR)
41a6d859 285
5be69cd8 286 sys.exit(utils.STGIT_SUCCESS)