#!/usr/bin/env python3 """steps_meta_backfill.py — ONE-OFF (2026-09-24 night, R-664): write `steps/.felhom.yml` beside every step file, from the NEWEST commit whose compose names that step's images — the .felhom.yml served WITH that definition — without its update_ladder block. Never overwrites.""" import os, subprocess, sys sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) import ladder # noqa: E402 ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) def git(*a): return subprocess.run(["git", "-C", ROOT] + list(a), capture_output=True, text=True, check=True).stdout def main(): n = 0 for app in sorted(os.listdir(os.path.join(ROOT, "templates"))): d = os.path.join(ROOT, "templates", app) fy = os.path.join(d, ".felhom.yml") if not os.path.isfile(fy): continue entries, _, errs = ladder.parse(open(fy, encoding="utf-8").read()) if errs or len(entries) < 2: continue commits = git("log", "--format=%H", "--", "templates/%s" % app).split() for i, e in enumerate(entries[:-1]): dst = os.path.join(d, ladder.step_meta_file(e["to"])) if os.path.exists(dst): continue for c in commits: try: comp = git("show", "%s:templates/%s/docker-compose.yml" % (c, app)) except subprocess.CalledProcessError: continue if ladder.images_in(comp) == e["to"]: meta = git("show", "%s:templates/%s/.felhom.yml" % (c, app)) open(dst, "w", encoding="utf-8").write(ladder.strip_ladder_block(meta)) print("WROTE %-10s entry %d -> %s from %s" % (app, i + 1, ladder.step_meta_file(e["to"]), c[:12])) n += 1 break else: print("MISS %-10s entry %d" % (app, i + 1)) print("steps_meta_backfill: %d written" % n) if __name__ == "__main__": main()