ae7f3be40534a6e2c6fa5f8c67aae70f21363fb0
[yardstick.git] / yardstick / cmd / cli.py
1 ##############################################################################
2 # Copyright (c) 2015 Ericsson AB and others.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9
10 '''
11 Command-line interface to yardstick
12 '''
13
14 import argparse
15 import logging
16
17 from pkg_resources import get_distribution
18 from argparse import RawDescriptionHelpFormatter
19
20 from yardstick.cmd.commands import task
21 from yardstick.cmd.commands import runner
22 from yardstick.cmd.commands import scenario
23
24
25 class YardstickCLI():
26     '''Command-line interface to yardstick'''
27
28     # Command categories
29     categories = {
30         'task': task.TaskCommands,
31         'runner': runner.RunnerCommands,
32         'scenario': scenario.ScenarioCommands
33     }
34
35     def __init__(self):
36         self._version = 'yardstick version %s ' % \
37             get_distribution('yardstick').version
38
39     def _get_base_parser(self):
40         '''get base (top level) parser'''
41
42         parser = argparse.ArgumentParser(
43             prog='yardstick',
44             formatter_class=RawDescriptionHelpFormatter,
45             description=YardstickCLI.__doc__ or ''
46         )
47
48         # Global options
49
50         parser.add_argument(
51             "-V", "--version",
52             help="display version",
53             version=self._version,
54             action="version"
55         )
56
57         parser.add_argument(
58             "-d", "--debug",
59             help="increase output verbosity to debug",
60             action="store_true"
61         )
62
63         parser.add_argument(
64             "-v", "--verbose",
65             help="increase output verbosity to info",
66             action="store_true"
67         )
68
69         return parser
70
71     def _find_actions(self, subparsers, actions_module):
72         '''find action methods'''
73         # Find action methods inside actions_module and
74         # add them to the command parser.
75         # The 'actions_module' argument may be a class
76         # or module. Action methods start with 'do_'
77         for attr in (a for a in dir(actions_module) if a.startswith('do_')):
78             command = attr[3:].replace('_', '-')
79             callback = getattr(actions_module, attr)
80             desc = callback.__doc__ or ''
81             arguments = getattr(callback, 'arguments', [])
82             subparser = subparsers.add_parser(
83                 command,
84                 description=desc
85             )
86             for (args, kwargs) in arguments:
87                 subparser.add_argument(*args, **kwargs)
88             subparser.set_defaults(func=callback)
89
90     def _get_parser(self):
91         '''get a command-line parser'''
92         parser = self._get_base_parser()
93
94         subparsers = parser.add_subparsers(
95             title='subcommands',
96         )
97
98         # add subcommands
99         for category in YardstickCLI.categories:
100             command_object = YardstickCLI.categories[category]()
101             desc = command_object.__doc__ or ''
102             subparser = subparsers.add_parser(
103                 category, description=desc,
104                 formatter_class=RawDescriptionHelpFormatter
105             )
106             subparser.set_defaults(command_object=command_object)
107             cmd_subparsers = subparser.add_subparsers(title='subcommands')
108             self._find_actions(cmd_subparsers, command_object)
109
110         return parser
111
112     def main(self, argv):
113         '''run the command line interface'''
114
115         # get argument parser
116         parser = self._get_parser()
117
118         # parse command-line
119         args = parser.parse_args(argv)
120
121         # handle global opts
122         logger = logging.getLogger('yardstick')
123         logger.setLevel(logging.WARNING)
124
125         if args.verbose:
126             logger.setLevel(logging.INFO)
127
128         if args.debug:
129             logger.setLevel(logging.DEBUG)
130
131         # dispatch to category parser
132         args.func(args)