|
| 1 | +#!/usr/bin/env python3 |
| 2 | +import json |
| 3 | +import glob |
| 4 | +from pathlib import Path |
| 5 | + |
| 6 | +# Collect all status JSON files |
| 7 | +status_files = glob.glob("badge-status/status-*.json") |
| 8 | + |
| 9 | +matrix = {} |
| 10 | +oses, compilers = set(), set() |
| 11 | + |
| 12 | +for f in status_files: |
| 13 | + with open(f) as fh: |
| 14 | + data = json.load(fh) |
| 15 | + os = data["os"] |
| 16 | + compiler = data["compiler"] |
| 17 | + status = data["status"] |
| 18 | + matrix[(os, compiler)] = status |
| 19 | + oses.add(os) |
| 20 | + compilers.add(compiler) |
| 21 | + |
| 22 | +# Sort for consistent layout |
| 23 | +oses = sorted(oses) |
| 24 | +compilers = sorted(compilers) |
| 25 | + |
| 26 | +# SVG layout parameters |
| 27 | +cell_w, cell_h = 60, 40 |
| 28 | +header_h = 100 |
| 29 | +row_label_w = 150 |
| 30 | +svg_w = row_label_w + len(compilers) * cell_w + 50 |
| 31 | +svg_h = header_h + len(oses) * cell_h + 50 |
| 32 | + |
| 33 | +def status_color_symbol(status): |
| 34 | + if status == "success": |
| 35 | + return "green", "✔" |
| 36 | + elif status == "failure": |
| 37 | + return "red", "✘" |
| 38 | + else: # default: skipped or missing |
| 39 | + return "gray", "○" |
| 40 | + |
| 41 | +# Start SVG |
| 42 | +svg = [ |
| 43 | + f'<svg xmlns="http://www.w3.org/2000/svg" width="{svg_w}" height="{svg_h}" font-family="monospace">' |
| 44 | +] |
| 45 | + |
| 46 | +# Column headers (rotated -45° for readability) |
| 47 | +for j, comp in enumerate(compilers): |
| 48 | + x = row_label_w + j * cell_w + cell_w // 2 |
| 49 | + y = header_h - 30 |
| 50 | + svg.append( |
| 51 | + f'<text x="{x}" y="{y}" transform="rotate(-45,{x},{y})" font-size="12">{comp}</text>' |
| 52 | + ) |
| 53 | + |
| 54 | +# Row headers |
| 55 | +for i, os in enumerate(oses): |
| 56 | + y = header_h + i * cell_h + cell_h // 2 + 5 |
| 57 | + svg.append(f'<text x="10" y="{y}" font-size="14">{os}</text>') |
| 58 | + |
| 59 | +# Grid cells |
| 60 | +for i, os in enumerate(oses): |
| 61 | + for j, comp in enumerate(compilers): |
| 62 | + status = matrix.get((os, comp), "skipped") |
| 63 | + color, symbol = status_color_symbol(status) |
| 64 | + x = row_label_w + j * cell_w |
| 65 | + y = header_h + i * cell_h |
| 66 | + svg.append( |
| 67 | + f'<rect x="{x}" y="{y}" width="{cell_w}" height="{cell_h}" ' |
| 68 | + f'fill="{color}" fill-opacity="0.3" stroke="black"/>' |
| 69 | + ) |
| 70 | + svg.append( |
| 71 | + f'<text x="{x + cell_w/2}" y="{y + cell_h/2 + 5}" ' |
| 72 | + f'text-anchor="middle" font-size="18">{symbol}</text>' |
| 73 | + ) |
| 74 | + |
| 75 | +svg.append("</svg>") |
| 76 | + |
| 77 | +# Write output |
| 78 | +Path("dashboard.svg").write_text("\n".join(svg)) |
| 79 | +print("✅ Generated dashboard.svg") |
0 commit comments