summaryrefslogtreecommitdiffstats
path: root/testing/mozbase/manifestparser/manifestparser/cli.py
diff options
context:
space:
mode:
Diffstat (limited to 'testing/mozbase/manifestparser/manifestparser/cli.py')
-rw-r--r--testing/mozbase/manifestparser/manifestparser/cli.py271
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()