1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
8 from telemetry
.internal
.util
import camel_case
11 class ArgumentHandlerMixIn(object):
12 """A structured way to handle command-line arguments.
14 In AddCommandLineArgs, add command-line arguments.
15 In ProcessCommandLineArgs, validate them and store them in a private class
16 variable. This way, each class encapsulates its own arguments, without needing
17 to pass an arguments object around everywhere.
21 def AddCommandLineArgs(cls
, parser
):
22 """Override to accept custom command-line arguments."""
25 def ProcessCommandLineArgs(cls
, parser
, args
):
26 """Override to process command-line arguments.
28 We pass in parser so we can call parser.error()."""
31 class Command(ArgumentHandlerMixIn
):
32 """An abstraction for things that run from the command-line."""
36 return camel_case
.ToUnderscore(cls
.__name
__)
41 return cls
.__doc
__.splitlines()[0]
46 raise NotImplementedError()
49 def main(cls
, args
=None):
50 """Main method to run this command as a standalone script."""
51 parser
= argparse
.ArgumentParser()
52 cls
.AddCommandLineArgs(parser
)
53 args
= parser
.parse_args(args
=args
)
54 cls
.ProcessCommandLineArgs(parser
, args
)
55 return min(cls().Run(args
), 255)
58 # TODO: Convert everything to argparse.
59 class OptparseCommand(Command
):
63 def CreateParser(cls
):
64 return optparse
.OptionParser('%%prog %s %s' % (cls
.Name(), cls
.usage
),
65 description
=cls
.Description())
68 def AddCommandLineArgs(cls
, parser
, environment
):
69 # pylint: disable=arguments-differ
73 def ProcessCommandLineArgs(cls
, parser
, args
, environment
):
74 # pylint: disable=arguments-differ
78 raise NotImplementedError()
81 def main(cls
, args
=None):
82 """Main method to run this command as a standalone script."""
83 parser
= cls
.CreateParser()
84 cls
.AddCommandLineArgs(parser
, None)
85 options
, args
= parser
.parse_args(args
=args
)
86 options
.positional_args
= args
87 cls
.ProcessCommandLineArgs(parser
, options
, None)
88 return min(cls().Run(options
), 255)
91 class SubcommandCommand(Command
):
92 """Combines Commands into one big command with sub-commands.
94 E.g. "svn checkout", "svn update", and "svn commit" are separate sub-commands.
97 class MyCommand(command_line.SubcommandCommand):
98 commands = (Help, List, Run)
100 if __name__ == '__main__':
101 sys.exit(MyCommand.main())
107 def AddCommandLineArgs(cls
, parser
):
108 subparsers
= parser
.add_subparsers()
110 for command
in cls
.commands
:
111 subparser
= subparsers
.add_parser(
112 command
.Name(), help=command
.Description())
113 subparser
.set_defaults(command
=command
)
114 command
.AddCommandLineArgs(subparser
)
117 def ProcessCommandLineArgs(cls
, parser
, args
):
118 args
.command
.ProcessCommandLineArgs(parser
, args
)
121 return args
.command().Run(args
)