mirror of
https://github.com/hathach/tinyusb.git
synced 2026-02-04 09:35:39 +00:00
fix metrics.py compare with verbose json. add print compare summary
This commit is contained in:
@ -15,7 +15,7 @@ deps_mandatory = {
|
||||
'159e31b689577dbf69cf0683bbaffbd71fa5ee10',
|
||||
'all'],
|
||||
'tools/linkermap': ['https://github.com/hathach/linkermap.git',
|
||||
'8a8206c39d0dfd7abfa615a676b3291165fcd65c',
|
||||
'5f2956943beb76b98fec78d702d8197daa730117',
|
||||
'all'],
|
||||
'tools/uf2': ['https://github.com/microsoft/uf2.git',
|
||||
'c594542b2faa01cc33a2b97c9fbebc38549df80a',
|
||||
|
||||
@ -43,6 +43,22 @@ def combine_maps(map_files, filters=None):
|
||||
filters = filters or []
|
||||
all_json_data = {"mapfiles": [], "data": []}
|
||||
|
||||
def _normalize_json(json_data):
|
||||
"""Flatten verbose linkermap JSON (per-symbol dicts) to per-section totals."""
|
||||
|
||||
for f in json_data.get("files", []):
|
||||
collapsed = {}
|
||||
for section, val in f.get("sections", {}).items():
|
||||
collapsed[section] = sum(val.values()) if isinstance(val, dict) else val
|
||||
|
||||
# Replace sections with collapsed totals
|
||||
f["sections"] = collapsed
|
||||
|
||||
# Ensure total is a number derived from sections
|
||||
f["total"] = sum(collapsed.values())
|
||||
|
||||
return json_data
|
||||
|
||||
for map_file in map_files:
|
||||
if not os.path.exists(map_file):
|
||||
print(f"Warning: {map_file} not found, skipping", file=sys.stderr)
|
||||
@ -52,6 +68,9 @@ def combine_maps(map_files, filters=None):
|
||||
if map_file.endswith('.json'):
|
||||
with open(map_file, 'r', encoding='utf-8') as f:
|
||||
json_data = json.load(f)
|
||||
|
||||
json_data = _normalize_json(json_data)
|
||||
|
||||
# Apply path filters to JSON data
|
||||
if filters:
|
||||
filtered_files = [
|
||||
@ -343,6 +362,77 @@ def write_compare_markdown(comparison, path, sort_order='size'):
|
||||
f.write("\n".join(md_lines))
|
||||
|
||||
|
||||
def print_compare_summary(comparison, sort_order='name+'):
|
||||
"""Print diff report to stdout in table form."""
|
||||
|
||||
sections = comparison["sections"]
|
||||
files = comparison["files"]
|
||||
|
||||
def sort_key(file_row):
|
||||
if sort_order == 'size-':
|
||||
return abs(file_row["total"]["diff"])
|
||||
if sort_order in ('size', 'size+'):
|
||||
return abs(file_row["total"]["diff"])
|
||||
if sort_order == 'name-':
|
||||
return file_row['file']
|
||||
return file_row['file']
|
||||
|
||||
reverse = sort_order in ('size-', 'name-')
|
||||
files_sorted = sorted(files, key=sort_key, reverse=reverse)
|
||||
|
||||
# Build formatted rows first to compute column widths precisely
|
||||
rows = []
|
||||
value_lengths = []
|
||||
for f in files_sorted:
|
||||
section_vals = {}
|
||||
for s in sections:
|
||||
sd = f["sections"][s]
|
||||
text = format_diff(sd['base'], sd['new'], sd['diff'])
|
||||
section_vals[s] = text
|
||||
value_lengths.append(len(text))
|
||||
td = f["total"]
|
||||
total_text = format_diff(td['base'], td['new'], td['diff'])
|
||||
value_lengths.append(len(total_text))
|
||||
rows.append({"file": f['file'], "sections": section_vals, "total": total_text, "raw": f})
|
||||
|
||||
# Column widths
|
||||
name_width = max(len(r["file"]) for r in rows) if rows else len("File")
|
||||
name_width = max(name_width, len("File"), 3) # at least width of SUM
|
||||
col_width = max(12, *(len(s) for s in sections), len("Total"), *(value_lengths or [0]))
|
||||
|
||||
ffmt = '{:' + f'>{name_width}' + '} |'
|
||||
col_fmt = '{:' + f'>{col_width}' + '}'
|
||||
|
||||
header = ffmt.format('File') + ''.join(col_fmt.format(s) + ' |' for s in sections) + col_fmt.format('Total')
|
||||
print(header)
|
||||
print('-' * len(header))
|
||||
|
||||
sum_base = {s: 0 for s in sections}
|
||||
sum_new = {s: 0 for s in sections}
|
||||
|
||||
for row in rows:
|
||||
line = ffmt.format(row['file'])
|
||||
for s in sections:
|
||||
sd = row["raw"]["sections"][s]
|
||||
sum_base[s] += sd["base"]
|
||||
sum_new[s] += sd["new"]
|
||||
line += col_fmt.format(row['sections'][s]) + ' |'
|
||||
|
||||
line += col_fmt.format(row['total'])
|
||||
print(line)
|
||||
|
||||
# Sum row
|
||||
sum_row = ffmt.format('SUM')
|
||||
for s in sections:
|
||||
diff = sum_new[s] - sum_base[s]
|
||||
sum_row += col_fmt.format(format_diff(sum_base[s], sum_new[s], diff)) + ' |'
|
||||
total_base = sum(sum_base.values())
|
||||
total_new = sum(sum_new.values())
|
||||
sum_row += col_fmt.format(format_diff(total_base, total_new, total_new - total_base))
|
||||
print('-' * len(header))
|
||||
print(sum_row)
|
||||
|
||||
|
||||
def cmd_combine(args):
|
||||
"""Handle combine subcommand."""
|
||||
map_files = expand_files(args.files)
|
||||
@ -370,7 +460,10 @@ def cmd_compare(args):
|
||||
print("Failed to compare files", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
if not args.quiet:
|
||||
print_compare_summary(comparison, args.sort)
|
||||
write_compare_markdown(comparison, args.out + '.md', args.sort)
|
||||
if not args.quiet:
|
||||
print(f"Comparison written to {args.out}.md")
|
||||
|
||||
|
||||
@ -406,6 +499,8 @@ def main(argv=None):
|
||||
compare_parser.add_argument('-S', '--sort', dest='sort', default='name+',
|
||||
choices=['size', 'size-', 'size+', 'name', 'name-', 'name+'],
|
||||
help='Sort order: size/size- (descending), size+ (ascending), name/name+ (ascending), name- (descending). Default: name+')
|
||||
compare_parser.add_argument('-q', '--quiet', dest='quiet', action='store_true',
|
||||
help='Suppress stdout summary output')
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user