mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 1 | # |
| 2 | # Copyright 2008 Google Inc. All Rights Reserved. |
| 3 | # |
| 4 | """Command line interface for autotest |
| 5 | |
| 6 | This module contains the generic CLI processing |
| 7 | |
| 8 | See topic_common.py for a High Level Design and Algorithm. |
| 9 | |
| 10 | This file figures out the topic and action from the 2 first arguments |
| 11 | on the command line and imports the site_<topic> or <topic> module. |
| 12 | |
| 13 | It then creates a <topic>_<action> object, and calls it parses), |
| 14 | execute() and output() methods. |
| 15 | """ |
| 16 | |
| 17 | __author__ = 'jmeurin@google.com (Jean-Marc Eurin)' |
| 18 | |
mbligh | bac1d2f | 2008-11-07 00:10:19 +0000 | [diff] [blame] | 19 | import os, sys, optparse, re, traceback |
mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 20 | |
| 21 | import common |
| 22 | from autotest_lib.cli import topic_common |
| 23 | |
| 24 | |
| 25 | def main(): |
| 26 | """ |
| 27 | The generic syntax is: |
| 28 | atest <topic> <action> <options> |
| 29 | atest-<topic> <action> <options> |
| 30 | atest --help |
| 31 | """ |
| 32 | cli = os.path.basename(sys.argv[0]) |
| 33 | syntax_obj = topic_common.atest() |
| 34 | |
| 35 | # Normalize the various --help, -h and help to -h |
| 36 | sys.argv = [re.sub('--help|help', '-h', arg) for arg in sys.argv] |
| 37 | |
| 38 | match = re.search('^atest-(\w+)$', cli) |
| 39 | if match: |
| 40 | topic = match.group(1) |
| 41 | else: |
| 42 | if len(sys.argv) > 1: |
| 43 | topic = sys.argv.pop(1) |
| 44 | else: |
| 45 | syntax_obj.invalid_syntax('No topic argument') |
| 46 | |
| 47 | |
| 48 | if topic == '-h': |
| 49 | sys.argv.insert(1, '-h') |
| 50 | syntax_obj.parse() |
| 51 | |
| 52 | # The ignore flag should *only* be used by unittests. |
| 53 | ignore_site = '--ignore_site_file' in sys.argv |
| 54 | if ignore_site: |
| 55 | sys.argv.remove('--ignore_site_file') |
| 56 | |
| 57 | # Import the topic specific file |
| 58 | cli_dir = os.path.abspath(os.path.dirname(__file__)) |
| 59 | if (not ignore_site and |
| 60 | os.path.exists(os.path.join(cli_dir, 'site_%s.py' % topic))): |
| 61 | topic = 'site_%s' % topic |
| 62 | elif not os.path.exists(os.path.join(cli_dir, '%s.py' % topic)): |
| 63 | syntax_obj.invalid_syntax('Invalid topic %s' % topic) |
| 64 | topic_module = common.setup_modules.import_module(topic, |
| 65 | 'autotest_lib.cli') |
| 66 | |
| 67 | # If we have a syntax error now, it should |
| 68 | # refer to the topic class. |
mbligh | 5a49608 | 2009-08-03 16:44:54 +0000 | [diff] [blame] | 69 | topic_class = getattr(topic_module, topic) |
| 70 | topic_obj = topic_class() |
mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 71 | |
| 72 | if len(sys.argv) > 1: |
| 73 | action = sys.argv.pop(1) |
| 74 | |
| 75 | if action == '-h': |
| 76 | action = 'help' |
| 77 | sys.argv.insert(1, '-h') |
| 78 | else: |
mbligh | 5a49608 | 2009-08-03 16:44:54 +0000 | [diff] [blame] | 79 | topic_obj.invalid_syntax('No action argument') |
| 80 | |
| 81 | # Any backward compatibility changes? |
| 82 | action = topic_obj.backward_compatibility(action, sys.argv) |
mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 83 | |
| 84 | # Instantiate a topic object |
| 85 | try: |
mbligh | 5a49608 | 2009-08-03 16:44:54 +0000 | [diff] [blame] | 86 | action_class = getattr(topic_module, topic + '_' + action) |
mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 87 | except AttributeError: |
mbligh | 5a49608 | 2009-08-03 16:44:54 +0000 | [diff] [blame] | 88 | topic_obj.invalid_syntax('Invalid action %s' % action) |
mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 89 | |
mbligh | 5a49608 | 2009-08-03 16:44:54 +0000 | [diff] [blame] | 90 | action_obj = action_class() |
mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 91 | |
mbligh | 5a49608 | 2009-08-03 16:44:54 +0000 | [diff] [blame] | 92 | action_obj.parse() |
mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 93 | try: |
| 94 | try: |
mbligh | 5a49608 | 2009-08-03 16:44:54 +0000 | [diff] [blame] | 95 | results = action_obj.execute() |
mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 96 | except topic_common.CliError: |
| 97 | pass |
| 98 | except Exception, err: |
showard | fb64e6a | 2009-04-22 21:01:18 +0000 | [diff] [blame] | 99 | traceback.print_exc() |
mbligh | 5a49608 | 2009-08-03 16:44:54 +0000 | [diff] [blame] | 100 | action_obj.generic_error("Unexpected exception: %s" % err) |
mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 101 | else: |
mbligh | cae0da7 | 2008-10-18 14:28:13 +0000 | [diff] [blame] | 102 | try: |
mbligh | 5a49608 | 2009-08-03 16:44:54 +0000 | [diff] [blame] | 103 | action_obj.output(results) |
mbligh | cae0da7 | 2008-10-18 14:28:13 +0000 | [diff] [blame] | 104 | except Exception: |
| 105 | traceback.print_exc() |
mbligh | be630eb | 2008-08-01 16:41:48 +0000 | [diff] [blame] | 106 | finally: |
mbligh | 5a49608 | 2009-08-03 16:44:54 +0000 | [diff] [blame] | 107 | return action_obj.show_all_failures() |