-
Notifications
You must be signed in to change notification settings - Fork 354
/
cmdparser.py
182 lines (147 loc) · 5.61 KB
/
cmdparser.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
"""
Autotest command parser
@copyright: Don Zickus <dzickus@redhat.com> 2011
"""
import os, re, sys
from autotest.client import os_dep
from autotest.client.shared import global_config
GLOBAL_CONFIG = global_config.global_config
LOCALDIRTEST = "tests"
GLOBALDIRTEST = GLOBAL_CONFIG.get_config_value('COMMON',
'test_dir',
default="")
DEBUG = False
class CommandParser(object):
"""
A client-side command wrapper for the autotest client.
"""
COMMAND_LIST = ['help', 'list', 'run']
@classmethod
def _print_control_list(cls, pipe, path):
"""
Print the list of control files available.
@param pipe: Pipe opened to an output stream (may be a pager)
@param path: Path we'll walk through
"""
if not os.path.isdir(path):
pipe.write("Test directory not available\n")
return
pipe.write(" %-50s %s\n" % ("[Control]", "[Description]"))
# The strategy here is to walk the root directory
# looking for "*control*" files in some directory
# and printing them out
for root, _, files in sorted(os.walk(path)):
for name in files:
if re.search("control", name):
# strip full path
basename = re.sub(path + "/", "", root)
text = "%s/%s" % (basename, name)
desc = "None"
if name == "control":
# Imply /control by listing only directory name
text = "%s" % basename
for line in open(root + "/" + name).readlines():
if re.match("NAME", line):
# We have a description line
desc = re.split("=\s*", line,
maxsplit=1)[1].rstrip()
try:
desc = desc[1:-1]
except IndexError:
pass
break
pipe.write(' %-50s %s\n' % (text, desc))
@classmethod
def help(cls):
"""
List the commands and their usage strings.
@param args is not used here.
"""
print "Commands:"
print "help\t\t\tOutput a list of supported commands"
print "list\t\t\tOutput a list of available tests"
print "run <test> [<args>]\tFind given <test> in path and run with args"
raise SystemExit(0)
@classmethod
def list_tests(cls):
"""
List the available tests for users to choose from
"""
# One favorite feature from git :-)
try:
less_cmd = os_dep.command('less')
pipe = os.popen('%s -FRSX' % less_cmd, 'w')
except ValueError:
pipe = sys.stdout
pipe.write("List of tests available\n")
pipe.write("Unless otherwise specified, outputs imply /control files\n")
pipe.write("\n")
# Walk local ./tests directory
dirtest = os.path.join(os.path.abspath(os.path.curdir), LOCALDIRTEST)
# Don't repeat autodirtest results
if not os.environ['AUTODIRTEST']:
dirtest = os.environ['AUTODIRTEST']
pipe.write("Local tests (%s)\n" % dirtest)
cls._print_control_list(pipe, dirtest)
pipe.write("\n")
# Walk globaldirtests directory
if GLOBALDIRTEST and os.path.isdir(GLOBALDIRTEST):
dirtest = GLOBALDIRTEST
pipe.write("Globally imported tests (%s)\n" % dirtest)
cls._print_control_list(pipe, dirtest)
pipe.write("\n")
# Walk autodirtest directory
dirtest = os.environ['AUTODIRTEST']
pipe.write("Autotest prepackaged tests (%s)\n" % dirtest)
cls._print_control_list(pipe, dirtest)
pipe.close()
raise SystemExit(0)
def parse_args(self, args):
"""
Process a client side command.
@param args: Command line args.
"""
if len(args) and args[0] in self.COMMAND_LIST:
cmd = args.pop(0)
else:
# Do things the traditional way
return args
# List is a python reserved word
if cmd == 'list':
cmd = 'list_tests'
try:
try:
args = getattr(self, cmd)(args)
except TypeError:
args = getattr(self, cmd)()
except SystemExit, return_code:
sys.exit(return_code.code)
except Exception, error_detail:
if DEBUG:
raise
sys.stderr.write("Command failed: %s -> %s\n" % (cmd, error_detail))
self.help()
sys.exit(1)
# Args are cleaned up, return to process the traditional way
return args
def run(self, args):
"""
Wrap args with a path and send it back to autotest.
"""
if not len(args):
self.help()
test = args.pop(0)
# Autotest works on control files
if not re.search("control", test):
test = test + "/control"
localdir = os.path.join(os.path.abspath(os.path.curdir), LOCALDIRTEST)
globaldir = GLOBALDIRTEST
autodir = os.environ['AUTODIRTEST']
for dirtest in [localdir, globaldir, autodir]:
d = os.path.join(dirtest, test)
if os.path.isfile(d):
print d
args.insert(0, d)
return args
print "Can not find test %s" % test
raise SystemExit(1)