diff options
Diffstat (limited to 'testing/mozbase/manifestparser/manifestparser/cli.py')
-rw-r--r-- | testing/mozbase/manifestparser/manifestparser/cli.py | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/testing/mozbase/manifestparser/manifestparser/cli.py b/testing/mozbase/manifestparser/manifestparser/cli.py new file mode 100644 index 0000000000..2fefca33e7 --- /dev/null +++ b/testing/mozbase/manifestparser/manifestparser/cli.py @@ -0,0 +1,271 @@ +#!/usr/bin/env python +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at http://mozilla.org/MPL/2.0/. + +""" +Mozilla universal manifest parser +""" +import os +import sys +from optparse import OptionParser + +from .manifestparser import ManifestParser, convert + + +class ParserError(Exception): + """error for exceptions while parsing the command line""" + + +def parse_args(_args): + """ + parse and return: + --keys=value (or --key value) + -tags + args + """ + + # return values + _dict = {} + tags = [] + args = [] + + # parse the arguments + key = None + for arg in _args: + if arg.startswith("---"): + raise ParserError("arguments should start with '-' or '--' only") + elif arg.startswith("--"): + if key: + raise ParserError("Key %s still open" % key) + key = arg[2:] + if "=" in key: + key, value = key.split("=", 1) + _dict[key] = value + key = None + continue + elif arg.startswith("-"): + if key: + raise ParserError("Key %s still open" % key) + tags.append(arg[1:]) + continue + else: + if key: + _dict[key] = arg + continue + args.append(arg) + + # return values + return (_dict, tags, args) + + +class CLICommand(object): + usage = "%prog [options] command" + + def __init__(self, parser): + self._parser = parser # master parser + + def parser(self): + return OptionParser( + usage=self.usage, description=self.__doc__, add_help_option=False + ) + + +class Copy(CLICommand): + usage = "%prog [options] copy manifest directory -tag1 -tag2 --key1=value1 --key2=value2 ..." + + def __call__(self, options, args): + # parse the arguments + try: + kwargs, tags, args = parse_args(args) + except ParserError as e: + self._parser.error(str(e)) + + # make sure we have some manifests, otherwise it will + # be quite boring + if not len(args) == 2: + HelpCLI(self._parser)(options, ["copy"]) + return + + # read the manifests + # TODO: should probably ensure these exist here + manifests = ManifestParser() + manifests.read(args[0]) + + # print the resultant query + manifests.copy(args[1], None, *tags, **kwargs) + + +class CreateCLI(CLICommand): + """ + create a manifest from a list of directories + """ + + usage = "%prog [options] create directory <directory> <...>" + + def parser(self): + parser = CLICommand.parser(self) + parser.add_option( + "-p", "--pattern", dest="pattern", help="glob pattern for files" + ) + parser.add_option( + "-i", + "--ignore", + dest="ignore", + default=[], + action="append", + help="directories to ignore", + ) + parser.add_option( + "-w", + "--in-place", + dest="in_place", + help="Write .ini files in place; filename to write to", + ) + return parser + + def __call__(self, _options, args): + parser = self.parser() + options, args = parser.parse_args(args) + + # need some directories + if not len(args): + parser.print_usage() + return + + # add the directories to the manifest + for arg in args: + assert os.path.exists(arg) + assert os.path.isdir(arg) + manifest = convert( + args, + pattern=options.pattern, + ignore=options.ignore, + write=options.in_place, + ) + if manifest: + print(manifest) + + +class WriteCLI(CLICommand): + """ + write a manifest based on a query + """ + + usage = "%prog [options] write manifest <manifest> -tag1 -tag2 --key1=value1 --key2=value2 ..." + + def __call__(self, options, args): + + # parse the arguments + try: + kwargs, tags, args = parse_args(args) + except ParserError as e: + self._parser.error(str(e)) + + # make sure we have some manifests, otherwise it will + # be quite boring + if not args: + HelpCLI(self._parser)(options, ["write"]) + return + + # read the manifests + # TODO: should probably ensure these exist here + manifests = ManifestParser() + manifests.read(*args) + + # print the resultant query + manifests.write(global_tags=tags, global_kwargs=kwargs) + + +class HelpCLI(CLICommand): + """ + get help on a command + """ + + usage = "%prog [options] help [command]" + + def __call__(self, options, args): + if len(args) == 1 and args[0] in commands: + commands[args[0]](self._parser).parser().print_help() + else: + self._parser.print_help() + print("\nCommands:") + for command in sorted(commands): + print(" %s : %s" % (command, commands[command].__doc__.strip())) + + +class UpdateCLI(CLICommand): + """ + update the tests as listed in a manifest from a directory + """ + + usage = "%prog [options] update manifest directory -tag1 -tag2 --key1=value1 --key2=value2 ..." + + def __call__(self, options, args): + # parse the arguments + try: + kwargs, tags, args = parse_args(args) + except ParserError as e: + self._parser.error(str(e)) + + # make sure we have some manifests, otherwise it will + # be quite boring + if not len(args) == 2: + HelpCLI(self._parser)(options, ["update"]) + return + + # read the manifests + # TODO: should probably ensure these exist here + manifests = ManifestParser() + manifests.read(args[0]) + + # print the resultant query + manifests.update(args[1], None, *tags, **kwargs) + + +# command -> class mapping +commands = { + "create": CreateCLI, + "help": HelpCLI, + "update": UpdateCLI, + "write": WriteCLI, +} + + +def main(args=sys.argv[1:]): + """console_script entry point""" + + # set up an option parser + usage = "%prog [options] [command] ..." + description = "%s. Use `help` to display commands" % __doc__.strip() + parser = OptionParser(usage=usage, description=description) + parser.add_option( + "-s", + "--strict", + dest="strict", + action="store_true", + default=False, + help="adhere strictly to errors", + ) + parser.disable_interspersed_args() + + options, args = parser.parse_args(args) + + if not args: + HelpCLI(parser)(options, args) + parser.exit() + + # get the command + command = args[0] + if command not in commands: + parser.error( + "Command must be one of %s (you gave '%s')" + % (", ".join(sorted(commands.keys())), command) + ) + + handler = commands[command](parser) + handler(options, args[1:]) + + +if __name__ == "__main__": + main() |