From cb5bb69fa80aadff9cc8c7b5148f79ea6495be61 Mon Sep 17 00:00:00 2001 From: Evan Rusackas Date: Tue, 12 May 2026 17:06:30 -0700 Subject: [PATCH] =?UTF-8?q?feat(country-map):=20build=20script=20=E2=80=94?= =?UTF-8?q?=20emit=20manifest.json=20describing=20outputs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a manifest.json output the plugin can fetch at runtime to populate worldview / country / region-set / composite dropdowns dynamically. Adding a new entry to the YAML configs no longer requires a plugin code change — re-run build.sh, manifest updates, plugin controls reflect the new options. Manifest schema: ne_pinned_tag, ne_pinned_sha, build_timestamp_utc worldviews: [, ...] admin_levels: [0, 1] countries_by_worldview: {: [, ...]} regional_aggregations: [{country, set_id, worldview, size_bytes}, ...] composites: [{id, worldview, size_bytes}, ...] Sample current output: 1 worldview (ukr), 211 countries with subdivisions, 4 regional sets, 1 composite (france_overseas). Build pinned to NE v5.1.2. Follow-up commit will replace the hardcoded choice tables in controlPanel.tsx with manifest-driven options. Co-Authored-By: Claude Opus 4.7 --- .../plugin-chart-country-map/scripts/build.py | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/superset-frontend/plugins/plugin-chart-country-map/scripts/build.py b/superset-frontend/plugins/plugin-chart-country-map/scripts/build.py index 3025874af23..7dc44626dff 100755 --- a/superset-frontend/plugins/plugin-chart-country-map/scripts/build.py +++ b/superset-frontend/plugins/plugin-chart-country-map/scripts/build.py @@ -799,6 +799,77 @@ def _write_admin1_per_country( return outputs +def write_manifest(targets: list[tuple[str, int]]) -> Path: + """Emit manifest.json describing what the build produced. + + The plugin's control panel reads this at runtime to populate + worldview / country / region-set / composite dropdowns dynamically, + so adding a new entry to the YAML configs doesn't require a plugin + code change. + """ + from datetime import datetime, timezone + + # Walk the OUTPUT_DIR for everything we wrote + worldviews = sorted({wv or "default" for wv, _ in targets}) + admin_levels = sorted({al for _, al in targets}) + + countries_by_wv: dict[str, list[str]] = {wv: [] for wv in worldviews} + regional_sets: list[dict] = [] + composites: list[dict] = [] + + for path in sorted(OUTPUT_DIR.glob("*.geo.json")): + name = path.stem.replace(".geo", "") + # ukr_admin1_FRA → worldview=ukr, admin1=FRA + for wv in worldviews: + prefix = f"{wv}_admin1_" + if name.startswith(prefix): + countries_by_wv[wv].append(name[len(prefix):]) + # regional_TUR_nuts_1_ukr + if name.startswith("regional_"): + parts = name.split("_") + wv = parts[-1] + country = parts[1] + set_name = "_".join(parts[2:-1]) + regional_sets.append({ + "country": country, + "set_id": set_name, + "worldview": wv, + "size_bytes": path.stat().st_size, + }) + # composite_france_overseas_ukr + elif name.startswith("composite_"): + parts = name.split("_") + wv = parts[-1] + cid = "_".join(parts[1:-1]) + composites.append({ + "id": cid, + "worldview": wv, + "size_bytes": path.stat().st_size, + }) + + manifest = { + "ne_pinned_tag": NE_PINNED_TAG, + "ne_pinned_sha": NE_PINNED_SHA, + "build_timestamp_utc": datetime.now(timezone.utc).isoformat(), + "worldviews": worldviews, + "admin_levels": admin_levels, + "countries_by_worldview": { + wv: sorted(set(codes)) for wv, codes in countries_by_wv.items() + }, + "regional_aggregations": regional_sets, + "composites": composites, + } + + manifest_path = OUTPUT_DIR / "manifest.json" + manifest_path.write_text(json.dumps(manifest, indent=2)) + log( + f"\nWrote manifest.json — {len(worldviews)} worldview(s), " + f"{sum(len(v) for v in countries_by_wv.values())} country files, " + f"{len(regional_sets)} regional sets, {len(composites)} composites" + ) + return manifest_path + + def main() -> int: OUTPUT_DIR.mkdir(exist_ok=True) @@ -850,6 +921,8 @@ def main() -> int: composite_maps, ) + write_manifest(targets) + log("\nDone.") return 0