scripts: Changed -o/-O to an exclusive operation

So:

  $ ./scripts/code.py lfs.o -o- -q

Becomes:

  $ ./scripts/code.py lfs.o -o-

The original intention of -o/-O _not_ being exclusive (aka table is
still rendered unless disabled with -q/--quiet), was to allow results to
be written to csv files and rendered to tables in a single pass.

But this was never useful. Heck, we're not even using this in our
Makefile right now because it would make the rule dependencies more
complicated than it's worth. Even for long-running result scripts
(perf.py, perfbd.py, etc), most of the work is building that csv file,
the cost of rendering a table in a second pass is negligible.

In every case I've used -o/-O, I've also wanted -q/--quiet, and almost
always forget this on the first run. So might as well make the expected
behavior the actual behavior.

---

As a plus, this let us simplify some of the scripts a bit, by replacing
visibility filters with -o/-O dependent by-fields.
This commit is contained in:
Christopher Haster
2025-03-01 03:21:06 -06:00
parent e71aca65d9
commit 299e2604c6
9 changed files with 202 additions and 232 deletions
+13 -17
View File
@@ -1027,18 +1027,6 @@ def main(obj_paths, *,
by=by, by=by,
defines=defines) defines=defines)
# write results to CSV/JSON
if args.get('output'):
write_csv(args['output'], CodeResult, results,
by=by,
fields=fields,
**args)
if args.get('output_json'):
write_csv(args['output_json'], CodeResult, results, json=True,
by=by,
fields=fields,
**args)
# find previous results? # find previous results?
diff_results = None diff_results = None
if args.get('diff') or args.get('percent'): if args.get('diff') or args.get('percent'):
@@ -1055,8 +1043,20 @@ def main(obj_paths, *,
by=by, by=by,
defines=defines) defines=defines)
# write results to JSON
if args.get('output_json'):
write_csv(args['output_json'], CodeResult, results, json=True,
by=by,
fields=fields,
**args)
# write results to CSV
elif args.get('output'):
write_csv(args['output'], CodeResult, results,
by=by,
fields=fields,
**args)
# print table # print table
if not args.get('quiet'): else:
table(CodeResult, results, diff_results, table(CodeResult, results, diff_results,
by=by, by=by,
fields=fields, fields=fields,
@@ -1078,10 +1078,6 @@ if __name__ == "__main__":
'-v', '--verbose', '-v', '--verbose',
action='store_true', action='store_true',
help="Output commands that run behind the scenes.") help="Output commands that run behind the scenes.")
parser.add_argument(
'-q', '--quiet',
action='store_true',
help="Don't show anything, useful with -o.")
parser.add_argument( parser.add_argument(
'-o', '--output', '-o', '--output',
help="Specify CSV file to store results.") help="Specify CSV file to store results.")
+32 -34
View File
@@ -953,13 +953,17 @@ def main(gcda_paths, *,
else: else:
by = ['function'] by = ['function']
visible = None
if fields is None: if fields is None:
fields = ['calls', 'hits', 'funcs', 'lines', 'branches'] if (args.get('annotate')
if not hits: or args.get('lines')
visible = ['lines', 'branches'] or args.get('branches')
or args.get('output')
or args.get('output_json')):
fields = ['calls', 'hits', 'funcs', 'lines', 'branches']
elif not hits:
fields = ['lines', 'branches']
else: else:
visible = ['calls', 'hits'] fields = ['calls', 'hits']
# find sizes # find sizes
if not args.get('use', None): if not args.get('use', None):
@@ -982,18 +986,6 @@ def main(gcda_paths, *,
by=by, by=by,
defines=defines) defines=defines)
# write results to CSV/JSON
if args.get('output'):
write_csv(args['output'], CovResult, results,
by=by,
fields=fields,
**args)
if args.get('output_json'):
write_csv(args['output_json'], CovResult, results, json=True,
by=by,
fields=fields,
**args)
# find previous results? # find previous results?
diff_results = None diff_results = None
if args.get('diff') or args.get('percent'): if args.get('diff') or args.get('percent'):
@@ -1010,20 +1002,30 @@ def main(gcda_paths, *,
by=by, by=by,
defines=defines) defines=defines)
# annotate sources
if (args.get('annotate')
or args.get('lines')
or args.get('branches')):
annotate(CovResult, results, **args)
# write results to JSON
elif args.get('output_json'):
write_csv(args['output_json'], CovResult, results, json=True,
by=by,
fields=fields,
**args)
# write results to CSV
elif args.get('output'):
write_csv(args['output'], CovResult, results,
by=by,
fields=fields,
**args)
# print table # print table
if not args.get('quiet'): else:
if (args.get('annotate') table(CovResult, results, diff_results,
or args.get('lines') by=by,
or args.get('branches')): fields=fields,
# annotate sources sort=sort,
annotate(CovResult, results, **args) **args)
else:
# print table
table(CovResult, results, diff_results,
by=by,
fields=visible if visible is not None else fields,
sort=sort,
**args)
# catch lack of coverage # catch lack of coverage
if args.get('error_on_lines') and any( if args.get('error_on_lines') and any(
@@ -1048,10 +1050,6 @@ if __name__ == "__main__":
'-v', '--verbose', '-v', '--verbose',
action='store_true', action='store_true',
help="Output commands that run behind the scenes.") help="Output commands that run behind the scenes.")
parser.add_argument(
'-q', '--quiet',
action='store_true',
help="Don't show anything, useful with -o.")
parser.add_argument( parser.add_argument(
'-o', '--output', '-o', '--output',
help="Specify CSV file to store results.") help="Specify CSV file to store results.")
+20 -23
View File
@@ -2206,10 +2206,11 @@ def main(csv_paths, *,
if by is not None: if by is not None:
labels = [k for (k, v), hidden in by if not hidden] labels = [k for (k, v), hidden in by if not hidden]
by = [k for (k, v), hidden in by] by = [k for (k, v), hidden in by]
visible = None
if fields is not None: if fields is not None:
visible = [k for (k, v), hidden in fields if not hidden] fields = [k for (k, v), hidden in fields
fields = [k for (k, v), hidden in fields] if not hidden
or args.get('output')
or args.get('output_json')]
if sort is not None: if sort is not None:
sort = [(k, reverse) for (k, v), reverse in sort] sort = [(k, reverse) for (k, v), reverse in sort]
if hot is not None: if hot is not None:
@@ -2293,20 +2294,6 @@ def main(csv_paths, *,
depth=depth, depth=depth,
hot=hot) hot=hot)
# write results to CSV/JSON
if args.get('output'):
write_csv(args['output'], Result, results,
by=by,
fields=fields,
depth=depth,
**args)
if args.get('output_json'):
write_csv(args['output_json'], Result, results, json=True,
by=by,
fields=fields,
depth=depth,
**args)
# find previous results? # find previous results?
diff_results = None diff_results = None
if args.get('diff') or args.get('percent'): if args.get('diff') or args.get('percent'):
@@ -2343,11 +2330,25 @@ def main(csv_paths, *,
depth=depth, depth=depth,
hot=hot) hot=hot)
# write results to JSON
if args.get('output_json'):
write_csv(args['output_json'], Result, results, json=True,
by=by,
fields=fields,
depth=depth,
**args)
# write results to CSV
elif args.get('output'):
write_csv(args['output'], Result, results,
by=by,
fields=fields,
depth=depth,
**args)
# print table # print table
if not args.get('quiet'): else:
table(Result, results, diff_results, table(Result, results, diff_results,
by=by, by=by,
fields=visible if visible is not None else fields, fields=fields,
sort=sort, sort=sort,
labels=labels, labels=labels,
depth=depth, depth=depth,
@@ -2372,10 +2373,6 @@ if __name__ == "__main__":
'--help-exprs', '--help-exprs',
action='store_true', action='store_true',
help="Show what field exprs are available.") help="Show what field exprs are available.")
parser.add_argument(
'-q', '--quiet',
action='store_true',
help="Don't show anything, useful with -o.")
parser.add_argument( parser.add_argument(
'-o', '--output', '-o', '--output',
help="Specify CSV file to store results.") help="Specify CSV file to store results.")
+21 -23
View File
@@ -1268,10 +1268,12 @@ def main(obj_paths, *,
else: else:
by = ['function'] by = ['function']
visible = None
if fields is None: if fields is None:
fields = ['off', 'size'] if (args.get('output')
visible = ['size'] or args.get('output_json')):
fields = ['off', 'size']
else:
fields = ['size']
# figure out depth # figure out depth
if depth is None: if depth is None:
@@ -1309,20 +1311,6 @@ def main(obj_paths, *,
depth=depth, depth=depth,
hot=hot) hot=hot)
# write results to CSV/JSON
if args.get('output'):
write_csv(args['output'], CtxResult, results,
by=by,
fields=fields,
depth=depth,
**args)
if args.get('output_json'):
write_csv(args['output_json'], CtxResult, results, json=True,
by=by,
fields=fields,
depth=depth,
**args)
# find previous results? # find previous results?
diff_results = None diff_results = None
if args.get('diff') or args.get('percent'): if args.get('diff') or args.get('percent'):
@@ -1347,11 +1335,25 @@ def main(obj_paths, *,
depth=depth, depth=depth,
hot=hot) hot=hot)
# write results to JSON
if args.get('output_json'):
write_csv(args['output_json'], CtxResult, results, json=True,
by=by,
fields=fields,
depth=depth,
**args)
# write results to CSV
elif args.get('output'):
write_csv(args['output'], CtxResult, results,
by=by,
fields=fields,
depth=depth,
**args)
# print table # print table
if not args.get('quiet'): else:
table(CtxResult, results, diff_results, table(CtxResult, results, diff_results,
by=by, by=by,
fields=visible if visible is not None else fields, fields=fields,
sort=sort, sort=sort,
labels=labels, labels=labels,
depth=depth, depth=depth,
@@ -1372,10 +1374,6 @@ if __name__ == "__main__":
'-v', '--verbose', '-v', '--verbose',
action='store_true', action='store_true',
help="Output commands that run behind the scenes.") help="Output commands that run behind the scenes.")
parser.add_argument(
'-q', '--quiet',
action='store_true',
help="Don't show anything, useful with -o.")
parser.add_argument( parser.add_argument(
'-o', '--output', '-o', '--output',
help="Specify CSV file to store results.") help="Specify CSV file to store results.")
+13 -17
View File
@@ -1027,18 +1027,6 @@ def main(obj_paths, *,
by=by, by=by,
defines=defines) defines=defines)
# write results to CSV/JSON
if args.get('output'):
write_csv(args['output'], DataResult, results,
by=by,
fields=fields,
**args)
if args.get('output_json'):
write_csv(args['output_json'], DataResult, results, json=True,
by=by,
fields=fields,
**args)
# find previous results? # find previous results?
diff_results = None diff_results = None
if args.get('diff') or args.get('percent'): if args.get('diff') or args.get('percent'):
@@ -1055,8 +1043,20 @@ def main(obj_paths, *,
by=by, by=by,
defines=defines) defines=defines)
# write results to JSON
if args.get('output_json'):
write_csv(args['output_json'], DataResult, results, json=True,
by=by,
fields=fields,
**args)
# write results to CSV
elif args.get('output'):
write_csv(args['output'], DataResult, results,
by=by,
fields=fields,
**args)
# print table # print table
if not args.get('quiet'): else:
table(DataResult, results, diff_results, table(DataResult, results, diff_results,
by=by, by=by,
fields=fields, fields=fields,
@@ -1078,10 +1078,6 @@ if __name__ == "__main__":
'-v', '--verbose', '-v', '--verbose',
action='store_true', action='store_true',
help="Output commands that run behind the scenes.") help="Output commands that run behind the scenes.")
parser.add_argument(
'-q', '--quiet',
action='store_true',
help="Don't show anything, useful with -o.")
parser.add_argument( parser.add_argument(
'-o', '--output', '-o', '--output',
help="Specify CSV file to store results.") help="Specify CSV file to store results.")
+38 -41
View File
@@ -1484,15 +1484,18 @@ def report(perf_paths, *,
else: else:
by = ['function'] by = ['function']
visible = None
if fields is None: if fields is None:
fields = ['cycles', 'bmisses', 'branches', 'cmisses', 'caches'] if (args.get('annotate')
if not branches and not caches: or args.get('threshold')
visible = ['cycles'] or args.get('output')
or args.get('output_json')):
fields = ['cycles', 'bmisses', 'branches', 'cmisses', 'caches']
elif not branches and not caches:
fields = ['cycles']
elif branches: elif branches:
visible = ['bmisses', 'branches'] fields = ['bmisses', 'branches']
else: else:
visible = ['cmisses', 'caches'] fields = ['cmisses', 'caches']
# figure out depth # figure out depth
if depth is None: if depth is None:
@@ -1530,20 +1533,6 @@ def report(perf_paths, *,
depth=depth, depth=depth,
hot=hot) hot=hot)
# write results to CSV/JSON
if args.get('output'):
write_csv(args['output'], PerfResult, results,
by=by,
fields=fields,
depth=depth,
**args)
if args.get('output_json'):
write_csv(args['output_json'], PerfResult, results, json=True,
by=by,
fields=fields,
depth=depth,
**args)
# find previous results? # find previous results?
diff_results = None diff_results = None
if args.get('diff') or args.get('percent'): if args.get('diff') or args.get('percent'):
@@ -1569,23 +1558,35 @@ def report(perf_paths, *,
hot=hot) hot=hot)
# print table # print table
if not args.get('quiet'): if (args.get('annotate')
if (args.get('annotate') or args.get('threshold')):
or args.get('threshold')): annotate(PerfResult, results,
# annotate sources branches=branches,
annotate(PerfResult, results, caches=caches,
branches=branches, **args)
caches=caches, # write results to JSON
**args) elif args.get('output_json'):
else: write_csv(args['output_json'], PerfResult, results, json=True,
# print table by=by,
table(PerfResult, results, diff_results, fields=fields,
by=by, depth=depth,
fields=visible if visible is not None else fields, **args)
sort=sort, # write results to CSV
labels=labels, elif args.get('output'):
depth=depth, write_csv(args['output'], PerfResult, results,
**args) by=by,
fields=fields,
depth=depth,
**args)
else:
# print table
table(PerfResult, results, diff_results,
by=by,
fields=fields,
sort=sort,
labels=labels,
depth=depth,
**args)
def main(**args): def main(**args):
@@ -1621,10 +1622,6 @@ if __name__ == "__main__":
'-v', '--verbose', '-v', '--verbose',
action='store_true', action='store_true',
help="Output commands that run behind the scenes.") help="Output commands that run behind the scenes.")
parser.add_argument(
'-q', '--quiet',
action='store_true',
help="Don't show anything, useful with -o.")
parser.add_argument( parser.add_argument(
'-o', '--output', '-o', '--output',
help="Specify CSV file to store results.") help="Specify CSV file to store results.")
+29 -35
View File
@@ -1525,20 +1525,6 @@ def report(paths, *,
depth=depth, depth=depth,
hot=hot) hot=hot)
# write results to CSV/JSON
if args.get('output'):
write_csv(args['output'], PerfBdResult, results,
by=by,
fields=fields,
depth=depth,
**args)
if args.get('output_json'):
write_csv(args['output_json'], PerfBdResult, results, json=True,
by=by,
fields=fields,
depth=depth,
**args)
# find previous results? # find previous results?
diff_results = None diff_results = None
if args.get('diff') or args.get('percent'): if args.get('diff') or args.get('percent'):
@@ -1564,23 +1550,35 @@ def report(paths, *,
hot=hot) hot=hot)
# print table # print table
if not args.get('quiet'): if (args.get('annotate')
if (args.get('annotate') or args.get('threshold')
or args.get('threshold') or args.get('read_threshold')
or args.get('read_threshold') or args.get('prog_threshold')
or args.get('prog_threshold') or args.get('erase_threshold')):
or args.get('erase_threshold')): annotate(PerfBdResult, results, **args)
# annotate sources # write results to JSON
annotate(PerfBdResult, results, **args) elif args.get('output_json'):
else: write_csv(args['output_json'], PerfBdResult, results, json=True,
# print table by=by,
table(PerfBdResult, results, diff_results, fields=fields,
by=by, depth=depth,
fields=fields, **args)
sort=sort, # write results to CSV
labels=labels, elif args.get('output'):
depth=depth, write_csv(args['output'], PerfBdResult, results,
**args) by=by,
fields=fields,
depth=depth,
**args)
# print table
else:
table(PerfBdResult, results, diff_results,
by=by,
fields=fields,
sort=sort,
labels=labels,
depth=depth,
**args)
def main(**args): def main(**args):
@@ -1621,10 +1619,6 @@ if __name__ == "__main__":
'-v', '--verbose', '-v', '--verbose',
action='store_true', action='store_true',
help="Output commands that run behind the scenes.") help="Output commands that run behind the scenes.")
parser.add_argument(
'-q', '--quiet',
action='store_true',
help="Don't show anything, useful with -o.")
parser.add_argument( parser.add_argument(
'-o', '--output', '-o', '--output',
help="Specify CSV file to store results.") help="Specify CSV file to store results.")
+15 -19
View File
@@ -1053,20 +1053,6 @@ def main(ci_paths,
depth=depth, depth=depth,
hot=hot) hot=hot)
# write results to CSV/JSON
if args.get('output'):
write_csv(args['output'], StackResult, results,
by=by,
fields=fields,
depth=depth,
**args)
if args.get('output_json'):
write_csv(args['output_json'], StackResult, results, json=True,
by=by,
fields=fields,
depth=depth,
**args)
# find previous results? # find previous results?
diff_results = None diff_results = None
if args.get('diff') or args.get('percent'): if args.get('diff') or args.get('percent'):
@@ -1091,8 +1077,22 @@ def main(ci_paths,
depth=depth, depth=depth,
hot=hot) hot=hot)
# write results to JSON
if args.get('output_json'):
write_csv(args['output_json'], StackResult, results, json=True,
by=by,
fields=fields,
depth=depth,
**args)
# write results to CSV
elif args.get('output'):
write_csv(args['output'], StackResult, results,
by=by,
fields=fields,
depth=depth,
**args)
# print table # print table
if not args.get('quiet'): else:
table(StackResult, results, diff_results, table(StackResult, results, diff_results,
by=by, by=by,
fields=fields, fields=fields,
@@ -1121,10 +1121,6 @@ if __name__ == "__main__":
'-v', '--verbose', '-v', '--verbose',
action='store_true', action='store_true',
help="Output commands that run behind the scenes.") help="Output commands that run behind the scenes.")
parser.add_argument(
'-q', '--quiet',
action='store_true',
help="Don't show anything, useful with -o.")
parser.add_argument( parser.add_argument(
'-o', '--output', '-o', '--output',
help="Specify CSV file to store results.") help="Specify CSV file to store results.")
+21 -23
View File
@@ -1088,10 +1088,12 @@ def main(obj_paths, *,
else: else:
by = ['struct'] by = ['struct']
visible = None
if fields is None: if fields is None:
fields = ['off', 'size', 'align'] if (args.get('output')
visible = ['size', 'align'] or args.get('output_json')):
fields = ['off', 'size', 'align']
else:
fields = ['size', 'align']
# figure out depth # figure out depth
if depth is None: if depth is None:
@@ -1129,20 +1131,6 @@ def main(obj_paths, *,
depth=depth, depth=depth,
hot=hot) hot=hot)
# write results to CSV/JSON
if args.get('output'):
write_csv(args['output'], StructResult, results,
by=by,
fields=fields,
depth=depth,
**args)
if args.get('output_json'):
write_csv(args['output_json'], StructResult, results, json=True,
by=by,
fields=fields,
depth=depth,
**args)
# find previous results? # find previous results?
diff_results = None diff_results = None
if args.get('diff') or args.get('percent'): if args.get('diff') or args.get('percent'):
@@ -1167,11 +1155,25 @@ def main(obj_paths, *,
depth=depth, depth=depth,
hot=hot) hot=hot)
# write results to JSON
if args.get('output_json'):
write_csv(args['output_json'], StructResult, results, json=True,
by=by,
fields=fields,
depth=depth,
**args)
# write results to CSV
elif args.get('output'):
write_csv(args['output'], StructResult, results,
by=by,
fields=fields,
depth=depth,
**args)
# print table # print table
if not args.get('quiet'): else:
table(StructResult, results, diff_results, table(StructResult, results, diff_results,
by=by, by=by,
fields=visible if visible is not None else fields, fields=fields,
sort=sort, sort=sort,
labels=labels, labels=labels,
depth=depth, depth=depth,
@@ -1192,10 +1194,6 @@ if __name__ == "__main__":
'-v', '--verbose', '-v', '--verbose',
action='store_true', action='store_true',
help="Output commands that run behind the scenes.") help="Output commands that run behind the scenes.")
parser.add_argument(
'-q', '--quiet',
action='store_true',
help="Don't show anything, useful with -o.")
parser.add_argument( parser.add_argument(
'-o', '--output', '-o', '--output',
help="Specify CSV file to store results.") help="Specify CSV file to store results.")