1 """Basic quilt-like functionality"""
8 from stgit
import argparse
, run
, utils
9 from stgit
.compat
import environ_get
, fsdecode_utf8
10 from stgit
.config
import config
11 from stgit
.out
import out
12 from stgit
.pager
import pager
15 Copyright (C) 2005, Catalin Marinas <catalin.marinas@gmail.com>
17 This program is free software; you can redistribute it and/or modify
18 it under the terms of the GNU General Public License version 2 as
19 published by the Free Software Foundation.
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, see http://www.gnu.org/licenses/.
32 def __init__(self
, name
, command
):
33 self
._command
= command
35 self
.usage
= ['<arguments>']
36 self
.help = 'Alias for "%s <arguments>".' % self
._command
40 cmd
= self
._command
.split() + args
42 p
.discard_exitcode().run()
46 def is_cmd_alias(cmd
):
47 return isinstance(cmd
, CommandAlias
)
50 def append_alias_commands(cmd_list
):
51 for (name
, command
) in config
.getstartswith('stgit.alias.'):
52 name
= utils
.strip_prefix('stgit.alias.', name
)
53 cmd_list
.append((name
, CommandAlias(name
, command
), 'Alias commands', command
))
60 """Commands class. It performs on-demand module loading"""
62 def canonical_cmd(self
, key
):
63 """Return the canonical name for a possibly-shortened command name."""
64 candidates
= [cmd
for cmd
in self
if cmd
.startswith(key
)]
68 'Unknown command: %s' % key
,
69 'Try "%s help" for a list of supported commands' % prog
,
71 sys
.exit(utils
.STGIT_GENERAL_ERROR
)
72 elif len(candidates
) == 1:
74 elif key
in candidates
:
78 'Ambiguous command: %s' % key
,
79 'Candidates are: %s' % ', '.join(candidates
),
81 sys
.exit(utils
.STGIT_GENERAL_ERROR
)
83 def __getitem__(self
, key
):
84 cmd_mod
= self
.get(key
) or self
.get(self
.canonical_cmd(key
))
85 if is_cmd_alias(cmd_mod
):
88 return stgit
.commands
.get_command(cmd_mod
)
91 cmd_list
= stgit
.commands
.get_commands()
92 append_alias_commands(cmd_list
)
93 commands
= Commands((cmd
, mod
) for cmd
, mod
, _
, _
in cmd_list
)
97 print('usage: %s <command> [options]' % os
.path
.basename(sys
.argv
[0]))
99 print('Generic commands:')
100 print(' help print the detailed command usage')
101 print(' version display version information')
102 print(' copyright display copyright information')
104 stgit
.commands
.pretty_command_list(cmd_list
, sys
.stdout
)
110 sys
.argv
= list(map(fsdecode_utf8
, sys
.argv
))
112 prog
= os
.path
.basename(sys
.argv
[0])
114 if len(sys
.argv
) < 2:
115 print('usage: %s <command>' % prog
, file=sys
.stderr
)
117 ' Try "%s --help" for a list of supported commands' % prog
, file=sys
.stderr
119 sys
.exit(utils
.STGIT_GENERAL_ERROR
)
123 if cmd
in ['-h', '--help']:
124 if len(sys
.argv
) >= 3:
125 cmd
= commands
.canonical_cmd(sys
.argv
[2])
126 sys
.argv
[2] = '--help'
129 sys
.exit(utils
.STGIT_SUCCESS
)
131 if len(sys
.argv
) == 3 and not sys
.argv
[2] in ['-h', '--help']:
132 cmd
= commands
.canonical_cmd(sys
.argv
[2])
133 sys
.argv
[0] += ' %s' % cmd
134 command
= commands
[cmd
]
135 parser
= argparse
.make_option_parser(command
)
136 if is_cmd_alias(command
):
137 parser
.remove_option('-h')
138 pager(parser
.format_help().encode())
141 sys
.exit(utils
.STGIT_SUCCESS
)
142 if cmd
in ['-v', '--version', 'version']:
143 from stgit
.version
import get_version
145 print('Stacked Git %s' % get_version())
146 os
.system('git --version')
147 print('Python version %s' % sys
.version
)
148 sys
.exit(utils
.STGIT_SUCCESS
)
149 if cmd
in ['copyright']:
151 sys
.exit(utils
.STGIT_SUCCESS
)
153 # re-build the command line arguments
154 cmd
= commands
.canonical_cmd(cmd
)
155 sys
.argv
[0] += ' %s' % cmd
158 command
= commands
[cmd
]
159 if is_cmd_alias(command
):
160 sys
.exit(command
.func(sys
.argv
[1:]))
162 parser
= argparse
.make_option_parser(command
)
164 # These modules are only used from this point onwards and do not
165 # need to be imported earlier
167 from configparser
import NoSectionError
, ParsingError
169 from ConfigParser
import NoSectionError
, ParsingError
170 from stgit
.config
import config_setup
171 from stgit
.exception
import StgException
172 from stgit
.lib
.git
import MergeConflictException
175 debug_level
= int(environ_get('STGIT_DEBUG_LEVEL', 0))
177 out
.error('Invalid STGIT_DEBUG_LEVEL environment variable')
178 sys
.exit(utils
.STGIT_GENERAL_ERROR
)
181 (options
, args
) = parser
.parse_args()
182 command
.directory
.setup()
184 ret
= command
.func(parser
, options
, args
)
185 except MergeConflictException
as err
:
187 traceback
.print_exc(file=sys
.stderr
)
188 for conflict
in err
.conflicts
:
190 sys
.exit(utils
.STGIT_CONFLICT
)
191 except (StgException
, IOError, ParsingError
, NoSectionError
) as err
:
193 traceback
.print_exc(file=sys
.stderr
)
194 out
.error(str(err
), title
='%s %s' % (prog
, cmd
))
195 sys
.exit(utils
.STGIT_COMMAND_ERROR
)
197 # Triggered by the option parser when it finds bad commandline
199 sys
.exit(utils
.STGIT_COMMAND_ERROR
)
200 except KeyboardInterrupt:
201 sys
.exit(utils
.STGIT_GENERAL_ERROR
)
202 except BaseException
:
203 out
.error('Unhandled exception:')
204 traceback
.print_exc(file=sys
.stderr
)
205 sys
.exit(utils
.STGIT_BUG_ERROR
)
207 sys
.exit(ret
or utils
.STGIT_SUCCESS
)