| Index: shell/main.py
|
| diff --git a/shell/main.py b/shell/main.py
|
| index c847e9df2eb700192777befce68dc526347c6474..5a2f60342a9e9610b0693bbea221af657a4a557e 100755
|
| --- a/shell/main.py
|
| +++ b/shell/main.py
|
| @@ -93,6 +93,58 @@ def _FindCommand(cmd_name):
|
| return possible_cmds[choice]
|
|
|
|
|
| +def _ParseArguments(parser, argv):
|
| + '''Helper function to separate arguments for a main program and sub-command.
|
| +
|
| + We split arguments into ones we understand, and ones to pass on to
|
| + sub-commands. For the former, we put them through the given optparse and
|
| + return the result options and sub-command name. For the latter, we just
|
| + return a list of options and arguments not intended for us.
|
| +
|
| + We want to parse only the options that we understand at the top level of
|
| + Chromite. Our heuristic here is that anything after the first positional
|
| + parameter (which we assume is the command) is ignored at this level, and
|
| + is passed down to the command level to handle.
|
| +
|
| + TODO(sjg): Revisit this to include tolerant option parser instead
|
| + http://codereview.chromium.org/6469035/
|
| +
|
| + Args:
|
| + parser: Option parser.
|
| + argv: List of program arguments
|
| +
|
| + Returns:
|
| + options: Top level options (returned from optparse).
|
| + cmd_str: Subcommand to run
|
| + cmd_args: Arguments intended for subcommands.
|
| + '''
|
| + our_args = []
|
| + cmd_args = list(argv)
|
| + cmd_str = ''
|
| + args = [] # Nothing until we call optparse
|
| + while not cmd_str:
|
| + if our_args:
|
| + (options, args) = parser.parse_args(our_args)
|
| + if len(args) > 1:
|
| + cmd_str = args[1].lower()
|
| + elif cmd_args:
|
| + # We don't have a command yet. Transfer a positional arg from from
|
| + # cmd_args to our_args to see if that does the trick. We move over any
|
| + # options we find also.
|
| + while cmd_args:
|
| + arg = cmd_args.pop(0)
|
| + our_args.append(arg)
|
| + if not arg.startswith( '-'):
|
| + break
|
| + else:
|
| + # No more cmd_args to consume.
|
| + break
|
| +
|
| + # We must run the parser, even if it dies due to lack of arguments
|
| + if not args:
|
| + (options, args) = parser.parse_args(our_args)
|
| + return options, cmd_str, cmd_args
|
| +
|
| def main():
|
| """Main function for the chromite shell."""
|
|
|
| @@ -128,7 +180,7 @@ def main():
|
|
|
| # Verbose defaults to full for now, just to keep people acclimatized to
|
| # vast amounts of comforting output.
|
| - parser.add_option('-v', dest='verbose', default=3,
|
| + parser.add_option('-v', dest='verbose', default=3, type='int',
|
| help='Control verbosity: 0=silent, 1=progress, 3=full')
|
| parser.add_option('-q', action='store_const', dest='verbose', const=0,
|
| help='Be quieter (sets verbosity to 1)')
|
| @@ -138,10 +190,9 @@ def main():
|
| help="Chroot spec to use. Can be an absolute path to a spec file "
|
| "or a substring of a chroot spec name (without .spec suffix)")
|
| parser.usage = help_str
|
| - try:
|
| - (options, args) = parser.parse_args()
|
| - except:
|
| - sys.exit(1)
|
| +
|
| + # Parse the arguments and separate them into top-level and subcmd arguments.
|
| + options, cmd_str, cmd_args = _ParseArguments(parser, sys.argv)
|
|
|
| # Set up the cros system.
|
| cros_env = chromite_env.ChromiteEnv()
|
| @@ -163,13 +214,6 @@ def main():
|
| # Already in the chroot; no need to get config...
|
| chroot_config = None
|
|
|
| - # Get command and arguments
|
| - if args:
|
| - cmd_str = args[0].lower()
|
| - args = args[1:]
|
| - else:
|
| - cmd_str = ''
|
| -
|
| # Validate the subcmd, popping a menu if needed.
|
| cmd_str = _FindCommand(cmd_str)
|
| oper.Info("Running command '%s'." % cmd_str)
|
| @@ -179,7 +223,7 @@ def main():
|
| cmd_obj = cmd_cls()
|
| cmd_obj.SetChromiteEnv(cros_env)
|
| try:
|
| - cmd_obj.Run([cmd_str] + args, chroot_config=chroot_config)
|
| + cmd_obj.Run([cmd_str] + cmd_args, chroot_config=chroot_config)
|
|
|
| # Handle an error in one of the scripts: print a message and exit.
|
| except chromite_env.ChromiteError, msg:
|
|
|