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