40
40
from plainbox import __version__ as version
41
41
from plainbox.impl.checkbox import CheckBox
42
from plainbox.impl.exporter import get_all_exporters
42
43
from plainbox.impl.job import JobDefinition
43
44
from plainbox.impl.result import JobResult
44
45
from plainbox.impl.rfc822 import load_rfc822_records
58
59
self._checkbox = CheckBox()
60
61
def main(self, argv=None):
61
basicConfig(level="WARNING")
62
62
# TODO: setup sane logging system that works just as well for Joe user
63
63
# that runs checkbox from the CD as well as for checkbox developers and
64
64
# custom debugging needs. It would be perfect^Hdesirable not to create
65
65
# another broken, never-rotated, uncapped logging crap that kills my
66
66
# SSD by writing junk to ~/.cache/
67
basicConfig(level="WARNING")
68
parser = self._construct_parser()
69
ns = parser.parse_args(argv)
70
# Set the desired log level
72
getLogger("").setLevel(ns.log_level)
73
# Load built-in job definitions
74
job_list = self.get_builtin_jobs()
75
# Load additional job definitions
76
job_list.extend(self._load_jobs(ns.load_extra))
77
# Now either do a special action or run the jobs
78
if ns.special == "list-jobs":
79
self._print_job_list(ns, job_list)
80
elif ns.special == "list-expr":
81
self._print_expression_list(ns, job_list)
82
elif ns.special == "dep-graph":
83
self._print_dot_graph(ns, job_list)
85
if ns.output_format == '?':
86
self._print_output_format_list(ns)
88
exporter_cls = get_all_exporters()[ns.output_format]
90
option_list = ns.output_options.split(',')
94
exporter = exporter_cls(option_list)
95
except ValueError as exc:
96
raise SystemExit(str(exc))
98
self._run_jobs(ns, job_list, exporter)
100
def _construct_parser(self):
67
101
parser = ArgumentParser(prog="plainbox")
68
102
parser.add_argument(
69
103
"-v", "--version", action="version",
99
133
group.add_argument(
100
134
'-n', '--dry-run', action='store_true',
101
135
help="Don't actually run any jobs")
136
group = parser.add_argument_group("output options")
137
assert 'text' in get_all_exporters()
139
'-f', '--output-format', default='text',
140
metavar='FORMAT', choices=['?',] + list(get_all_exporters().keys()),
141
help='Save test results in the specified FORMAT')
143
'-p', '--output-options', default='',
145
help='Comma-separated list of options for the export mechanism')
147
'-o', '--output-file', default='-',
148
metavar='FILE', type=FileType("wt"),
149
help=('Save test results to the specified FILE'
150
' (or to stdout if FILE is -)'))
102
151
group = parser.add_argument_group("special options")
103
152
group.add_argument(
104
153
'--list-jobs', help="List jobs instead of running them",
112
161
group.add_argument(
113
162
'--dot-resources', action='store_true',
114
163
help="Render resource relationships (for --dot)")
115
ns = parser.parse_args(argv)
117
# Set the desired log level
119
getLogger("").setLevel(ns.log_level)
120
# Load built-in job definitions
121
job_list = self.get_builtin_jobs()
122
# Load additional job definitions
123
job_list.extend(self._load_jobs(ns.load_extra))
124
# Now either do a special action or run the jobs
125
if ns.special == "list-jobs":
126
self._print_job_list(ns, job_list)
127
elif ns.special == "list-expr":
128
self._print_expression_list(ns, job_list)
129
elif ns.special == "dep-graph":
130
self._print_dot_graph(ns, job_list)
132
self._run_jobs(ns, job_list)
166
def _print_output_format_list(self, ns):
167
print("Available output formats: {}".format(
168
', '.join(get_all_exporters())))
134
170
def _get_matching_job_list(self, ns, job_list):
135
171
# Find jobs that matched patterns
195
231
expression.text.replace('"', "'")))
198
def _run_jobs(self, ns, job_list):
234
def _run_jobs(self, ns, job_list, exporter):
199
235
# Compute the run list, this can give us notification about problems in
200
236
# the selected jobs. Currently we just display each problem
201
237
matching_job_list = self._get_matching_job_list(ns, job_list)
212
248
runner = JobRunner(self._checkbox, session.session_dir,
213
249
outcome_callback=outcome_callback)
214
250
self._run_jobs_with_session(ns, session, runner)
215
print("[ Results ]".center(80, '='))
216
for job_name in sorted(session.job_state_map):
217
job_state = session.job_state_map[job_name]
218
if job_state.result.outcome != JobResult.OUTCOME_NONE:
219
print("{}: {}".format(job_name, job_state.result.outcome))
251
self._save_results(ns, session, exporter)
253
def _save_results(self, ns, session, exporter):
254
if ns.output_file is sys.stdout:
255
print("[ Results ]".center(80, '='))
257
print("Saving results to {}".format(ns.output_file.name))
258
data = exporter.get_session_data_subset(session)
259
with ns.output_file as stream:
260
exporter.dump(data, stream)
221
262
def ask_for_outcome(self, prompt=None, allowed=None):
222
263
if prompt is None: