summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEnric Balletbo i Serra <enric.balletbo@collabora.com>2015-03-10 12:10:26 (GMT)
committerEnric Balletbo i Serra <enric.balletbo@collabora.com>2015-03-11 12:33:13 (GMT)
commite88b1c577ae9a0c6f58a2e49bb6c4093504a8d95 (patch)
treed97dbc2d9f862b9caaa42fd3b4e687fa64ccc9eb
parentb9f671c87056c097e62df050d20f2ed7839cf3f2 (diff)
downloadlqa-e88b1c577ae9a0c6f58a2e49bb6c4093504a8d95.tar.gz
lqa-e88b1c577ae9a0c6f58a2e49bb6c4093504a8d95.tar.xz
Add support for multiple subcommands (like git).
It's a common pattern for command line tools to have multiple subcommands, this patch implements a new subcommand command line interface. Each subcommand has its own set of required and optional parameters. The current implemented subcommands are: submit Submit job files cancel Cancel job files resubmit Resubmit job files results Fetch job id list results See 'lqa <command> -h' to read about a specific subcommand. Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
-rwxr-xr-xlqa1
-rw-r--r--lqa_tool/__init__.py124
2 files changed, 85 insertions, 40 deletions
diff --git a/lqa b/lqa
index b620165..8e10daf 100755
--- a/lqa
+++ b/lqa
@@ -22,7 +22,6 @@ from lqa_tool import Cli
def main():
lqa = Cli()
- lqa.command.run()
if __name__ == '__main__':
diff --git a/lqa_tool/__init__.py b/lqa_tool/__init__.py
index 2635f9a..22d7442 100644
--- a/lqa_tool/__init__.py
+++ b/lqa_tool/__init__.py
@@ -90,16 +90,48 @@ class Cli(object):
"""Command line interface using argparse"""
def __init__(self):
- parser = ArgumentParser(description="lqa v{}".format(__version__))
- parser.add_argument('-c', '--config', metavar='CONFIG.yaml',
- help="set configuration file",
+ parser = ArgumentParser(
+ description="lqa v{}".format(__version__),
+ usage='''lqa <command> [<args>]
+
+The most commonly used lqa commands are:
+ submit Submit job files
+ cancel Cancel job files
+ resubmit Resubmit job files
+ results Fetch job id list results
+
+See 'lqa <command> -h' to read about a specific subcommand.
+''')
+
+ parser.add_argument('command', help="command to run")
+ # parse_args defaults to [1:] for args, but you need to
+ # exclude the rest of the args too, or validation will fail
+ args = parser.parse_args(sys.argv[1:2])
+ if not hasattr(self, args.command):
+ print 'Unrecognized command'
+ parser.print_help()
+ exit(1)
+ # use dispatch pattern to invoke method with same name
+ getattr(self, args.command)()
+
+ def add_common_arguments(self, parser):
+ parser.add_argument('-c', '--config', metavar='CONFIG.yaml',
+ help="set configuration file",
default=os.path.join(CONFIG_PATH, LAVA_CONFIG))
- parser.add_argument('-j', '--job-file', nargs='+', type=str,
+ parser.add_argument('--log-file', type=str, help="set the log file")
+
+ def submit(self):
+ parser = ArgumentParser(
+ description='Submit job files',
+ usage='''lqa submit [<args>] JOB_FILE.json [JOB_FILE.json ...]''')
+ # Add common arguments
+ self.add_common_arguments(parser)
+ # NOT prefixing the argument with -- means it's not optional
+ parser.add_argument('submit_job', nargs='+', type=str,
metavar='JOB_FILE.json',
help="process these job files")
- parser.add_argument('-s', '--submit-job', action='store_true',
- help="submit test jobs")
- parser.add_argument('--print-json', action='store_true',
+ # prefixing the argument with -- means it's optional
+ parser.add_argument('--print-json', action='store_true',
help="print the json job to stdout")
parser.add_argument('-g', '--profile-file', metavar='PROFILE.yaml',
help="set profile file")
@@ -111,17 +143,46 @@ class Cli(object):
help="set 'field:value' "
"template variables/values "
"(can be given multiple times")
- parser.add_argument('--log-file', type=str, help="set the log file")
- parser.add_argument('-r', '--resubmit-job', nargs='+', type=str,
- help='resubmit job id list')
- parser.add_argument('-C', '--cancel-job', nargs='+', type=str,
- help='cancel job id list')
- parser.add_argument('-f', '--fetch-result', nargs='+', type=str,
- help='fetch job id list results', dest="job_id")
-
- self.args = parser.parse_args()
- self.command = Lava(self.args)
-
+ # now that we're inside a subcommand, ignore the first TWO argvs
+ args = parser.parse_args(sys.argv[2:])
+ self.command = Lava(args).submit_job()
+
+ def cancel(self):
+ parser = ArgumentParser(
+ description='Cancel job id list results',
+ usage='''lqa cancel [<args>] JOB_ID [JOB_ID ...]''')
+ # Add common arguments
+ self.add_common_arguments(parser)
+ # NOT prefixing the argument with -- means it's not optional
+ parser.add_argument('cancel_job', nargs='+', type=str,
+ metavar='JOB_ID', help='job id list')
+ args = parser.parse_args(sys.argv[2:])
+ print 'Running git cancel, job_id=%s' % args.cancel_job
+ self.command = Lava(args).cancel_job()
+
+ def results(self):
+ parser = ArgumentParser(
+ description='Fetch job id list results',
+ usage='''lqa results [<args>] JOB_ID [JOB_ID ...]''')
+ # Add common arguments
+ self.add_common_arguments(parser)
+ # NOT prefixing the argument with -- means it's not optional
+ parser.add_argument('job_id', nargs='+', type=str,
+ metavar='JOB_ID', help='job id list')
+ args = parser.parse_args(sys.argv[2:])
+ self.command = Lava(args).fetch_result()
+
+ def resubmit(self):
+ parser = ArgumentParser(
+ description='Resubmit job id list results',
+ usage='''lqa resubmit [<args>] JOB_ID [JOB_ID ...]''')
+ # Add common arguments
+ self.add_common_arguments(parser)
+ # NOT prefixing the argument with -- means it's not optional
+ parser.add_argument('resubmit_job', nargs='+', type=str,
+ metavar='JOB_ID', help='job id list')
+ args = parser.parse_args(sys.argv[2:])
+ self.command = Lava(args).resubmit_job()
class Lava(object):
"""Lava sub-command object.
@@ -132,8 +193,6 @@ class Lava(object):
def __init__(self, args):
self.args = args
self.settings = Settings(self, LAVA_CONFIG)
- if self.args.profile_file:
- self.profiles = Profiles(self, self.args.profile_file)
self.server = self.open_connection()
def open_connection(self):
@@ -144,8 +203,8 @@ class Lava(object):
self.settings.config['server']),
use_datetime=True)
- def run(self):
- """Run lava command.
+ def submit_job(self):
+ """Submit job id
It follows the priority for profiles processing:
1) Any profile specified by '-p'
@@ -153,6 +212,7 @@ class Lava(object):
3) Or run without any profile....
"""
if self.args.profile_file:
+ self.profiles = Profiles(self, self.args.profile_file)
# Fetch the main profile and merge later with any sub profile
main_profile = self.profiles.config.get('main-profile', {})
@@ -168,20 +228,7 @@ class Lava(object):
def _run(self, profile={}):
variables = profile.get('variables', {})
- # Resubmit job
- if self.args.resubmit_job:
- self.resubmit_job()
-
- # Cancel job
- if self.args.cancel_job:
- self.cancel_job()
-
- # Fetch results
- if self.args.job_id:
- self.fetch_result()
-
if self.args.template_vars:
- # '@' is used as the field:value separator
# The variables translates to a hash that we can easily use
# for mapping the fields -> values in the json template
for item in self.args.template_vars:
@@ -190,8 +237,8 @@ class Lava(object):
# Get the job files from either the command line '-j' or the profile.
job_files = []
- if self.args.job_file:
- job_files = self.args.job_file
+ if self.args.submit_job:
+ job_files = self.args.submit_job
else:
for t in profile.get('templates', []):
# Search template files from profile var 'template-dir' or '.'
@@ -215,8 +262,7 @@ class Lava(object):
if self.args.print_json:
print json.dumps(json_obj, indent=2)
-
- if self.args.submit_job:
+ else:
try:
job_id = self.server.scheduler.submit_job(
json.dumps(json_obj))