|
4 | 4 | already has a row in docs/variants/overview.md's "Openness comparison" table, |
5 | 5 | without that row being updated to reference the new version. |
6 | 6 |
|
| 7 | +How it works: |
| 8 | +- Checks if a changed file is an "*_openness_chart.png". |
| 9 | +- For each table row, resolves its ROM filename to a variant directory. |
| 10 | +- Skips rows whose directory wasn't touched by this commit. |
| 11 | +- Flags a row if its own filename pattern now has a newer chart, or if a |
| 12 | + different pattern in the same directory (that no other row matches to) does. |
| 13 | +
|
7 | 14 | Usage: |
8 | | - check_openness_score_freshness.py <changed-file-path> [...] |
| 15 | + check_openness_score_freshness.py <changed-file-path> |
9 | 16 |
|
10 | 17 | Changed file paths should be relative to the repo root. |
11 | 18 | """ |
@@ -57,6 +64,35 @@ def latest_version_on_disk(directory, family_key): |
57 | 64 | return best |
58 | 65 |
|
59 | 66 |
|
| 67 | +def newest_other_family( |
| 68 | + directory, own_family, row_version, claimed_families=frozenset() |
| 69 | +): |
| 70 | + """Return the newest (family, version) other than `own_family` in |
| 71 | + `directory` that beats `row_version`, ignoring `claimed_families` - |
| 72 | + families another row already tracks (e.g. a sibling DDR4/DDR5 row) - |
| 73 | + else None. |
| 74 | + """ |
| 75 | + best = None |
| 76 | + for chart in directory.glob(f"*{CHART_SUFFIX}"): |
| 77 | + rom_name = chart.name[: -len(CHART_SUFFIX)] |
| 78 | + family, version = parse_version_family(rom_name) |
| 79 | + if family is None or family == own_family or version is None: |
| 80 | + continue |
| 81 | + if family in claimed_families: |
| 82 | + continue |
| 83 | + if best is None: |
| 84 | + best = (family, version) |
| 85 | + else: |
| 86 | + a, b = normalize(version, best[1]) |
| 87 | + if a > b: |
| 88 | + best = (family, version) |
| 89 | + |
| 90 | + if best is None: |
| 91 | + return None |
| 92 | + a, b = normalize(best[1], row_version) |
| 93 | + return best if a > b else None |
| 94 | + |
| 95 | + |
60 | 96 | def parse_overview_rows(): |
61 | 97 | """Yield (line_no, platform, rom_filename) for each data row of the |
62 | 98 | "Openness comparison" table in overview.md.""" |
@@ -87,47 +123,77 @@ def parse_overview_rows(): |
87 | 123 | yield i + 1, cols[0], cols[1] |
88 | 124 |
|
89 | 125 |
|
| 126 | +def resolve_row_directory(rom_filename, family): |
| 127 | + """Resolve a table row's ROM filename to its variant directory, or None |
| 128 | + if it can't be resolved unambiguously. |
| 129 | +
|
| 130 | + Prefers an exact chart match; falls back to matching the prefix before |
| 131 | + the version number, but only when that prefix resolves to exactly one |
| 132 | + directory (sibling variants, e.g. a TU/TNX split, can share a prefix). |
| 133 | + """ |
| 134 | + exact_matches = sorted( |
| 135 | + REPO_ROOT.glob(f"docs/variants/*/{rom_filename}{CHART_SUFFIX}") |
| 136 | + ) |
| 137 | + if exact_matches: |
| 138 | + return exact_matches[0].parent |
| 139 | + |
| 140 | + prefix = family.split("_v{VER}")[0] |
| 141 | + prefix_matches = REPO_ROOT.glob(f"docs/variants/*/{prefix}*_v*{CHART_SUFFIX}") |
| 142 | + prefix_dirs = {m.parent for m in prefix_matches} |
| 143 | + if len(prefix_dirs) != 1: |
| 144 | + return None |
| 145 | + return next(iter(prefix_dirs)) |
| 146 | + |
| 147 | + |
90 | 148 | def main(changed_files): |
91 | 149 | changed_charts = [REPO_ROOT / f for f in changed_files if f.endswith(CHART_SUFFIX)] |
92 | 150 | if not changed_charts: |
93 | 151 | return 0 |
94 | 152 |
|
95 | | - changed_dirs_families = set() |
96 | | - for chart in changed_charts: |
97 | | - rom_name = chart.name[: -len(CHART_SUFFIX)] |
98 | | - family, _ = parse_version_family(rom_name) |
99 | | - if family is None: |
100 | | - continue |
101 | | - changed_dirs_families.add((chart.parent, family)) |
| 153 | + changed_dirs = {chart.parent for chart in changed_charts} |
102 | 154 |
|
103 | | - failures = [] |
| 155 | + rows = [] |
| 156 | + claimed_families_by_dir = {} |
104 | 157 | for line_no, platform, rom_filename in parse_overview_rows(): |
105 | 158 | family, row_version = parse_version_family(rom_filename) |
106 | 159 | if family is None: |
107 | 160 | continue |
108 | | - |
109 | | - matches = sorted( |
110 | | - REPO_ROOT.glob(f"docs/variants/*/{rom_filename}{CHART_SUFFIX}") |
111 | | - ) |
112 | | - if not matches: |
| 161 | + directory = resolve_row_directory(rom_filename, family) |
| 162 | + if directory is None: |
113 | 163 | continue |
114 | | - directory = matches[0].parent |
| 164 | + rows.append((line_no, platform, rom_filename, family, row_version, directory)) |
| 165 | + claimed_families_by_dir.setdefault(directory, set()).add(family) |
115 | 166 |
|
116 | | - if (directory, family) not in changed_dirs_families: |
| 167 | + failures = [] |
| 168 | + for line_no, platform, rom_filename, family, row_version, directory in rows: |
| 169 | + if directory not in changed_dirs: |
117 | 170 | continue |
118 | 171 |
|
119 | 172 | latest = latest_version_on_disk(directory, family) |
120 | | - if latest is None: |
121 | | - continue |
122 | | - |
123 | | - row_norm, latest_norm = normalize(row_version, latest) |
124 | | - if row_norm < latest_norm: |
| 173 | + if latest is not None: |
| 174 | + row_norm, latest_norm = normalize(row_version, latest) |
| 175 | + if row_norm < latest_norm: |
| 176 | + failures.append( |
| 177 | + f"docs/variants/overview.md:{line_no}: row '{platform}' " |
| 178 | + f"references {rom_filename} " |
| 179 | + f"(v{'.'.join(map(str, row_version))}), but " |
| 180 | + f"{directory.relative_to(REPO_ROOT)} now has an openness " |
| 181 | + f"score for v{'.'.join(map(str, latest))}." |
| 182 | + ) |
| 183 | + |
| 184 | + claimed = claimed_families_by_dir.get(directory, set()) |
| 185 | + other = newest_other_family(directory, family, row_version, claimed) |
| 186 | + if other is not None: |
| 187 | + other_family, other_version = other |
| 188 | + other_filename = other_family.replace( |
| 189 | + "_v{VER}", "_v" + ".".join(map(str, other_version)) |
| 190 | + ) |
125 | 191 | failures.append( |
126 | 192 | f"docs/variants/overview.md:{line_no}: row '{platform}' " |
127 | 193 | f"references {rom_filename} " |
128 | 194 | f"(v{'.'.join(map(str, row_version))}), but " |
129 | | - f"{directory.relative_to(REPO_ROOT)} now has an openness " |
130 | | - f"score for v{'.'.join(map(str, latest))}." |
| 195 | + f"{directory.relative_to(REPO_ROOT)} now has a newer " |
| 196 | + f"openness score under {other_filename}." |
131 | 197 | ) |
132 | 198 |
|
133 | 199 | if failures: |
|
0 commit comments