#!/usr/bin/env python3 """harkaq-add-deps — añade deps de build a una receta, sin romperla. (Cosecha desatendida.) harkaq-add-deps.py recipes/zlib.toml make binutils Idempotente: si la dep ya está, no toca nada y sale 1 (nada que commitear). Corre DESATENDIDO y de noche, editando ficheros que son la fuente de verdad del catálogo. Por eso la regla es: **ante la duda, no tocar**. Un fichero mal editado a las 3am no da un error, da una receta corrupta que nadie mira hasta el lunes. Cada caso que no se entiende sale sin cambios y con motivo, que es la misma disciplina de `SinEvidencia`: no afirmar lo que no se sabe. """ import re import sys def anadir(path, nuevas): with open(path) as f: s = f.read() orig = s m = re.search(r'^\[deps\]\s*$(.*?)(?=^\[|\Z)', s, re.M | re.S) if m: bloque = m.group(1) mb = re.search(r'^(\s*build\s*=\s*)\[([^\]]*)\]', bloque, re.M) if mb: ya = re.findall(r'"([^"]+)"', mb.group(2)) falta = [d for d in nuevas if d not in ya] if not falta: return False, "ya estaban declaradas" lista = ya + falta nuevo = mb.group(1) + "[" + ", ".join(f'"{d}"' for d in lista) + "]" s = s[:m.start(1)] + bloque[:mb.start()] + nuevo + bloque[mb.end():] + s[m.end(1):] else: # Hay [deps] pero sin `build = [...]` (p.ej. sólo `runtime`). Insertar la línea. linea = "build = [" + ", ".join(f'"{d}"' for d in nuevas) + "]\n" s = s[:m.start(1)] + "\n" + linea + bloque.lstrip("\n") + s[m.end(1):] else: # Sin [deps]: se añade al final. `[build.phases]` suele ser la última sección y sus strings # multilínea (''' … ''') se comerían un bloque puesto después ⇒ va ANTES de la primera # sección [build...] si existe, y si no, al final. bloque = "\n[deps]\nbuild = [" + ", ".join(f'"{d}"' for d in nuevas) + "]\n" mfase = re.search(r'^\[build\.phases\]', s, re.M) if mfase: s = s[:mfase.start()] + bloque.lstrip("\n") + "\n" + s[mfase.start():] else: s = s.rstrip("\n") + "\n" + bloque if s == orig: return False, "sin cambios" # Guarda: sólo escribir si el TOML sigue pareciendo un TOML y no perdimos nada. Un parser de # verdad sería mejor, pero tomllib no ESCRIBE y re-emitir con un writer reordenaría el fichero # entero (y con él, comentarios que valen oro en este repo). try: import tomllib tomllib.loads(s) except Exception as e: return False, f"el resultado no parsea como TOML ({e}) — NO se toca" if len(s) < len(orig): return False, "el resultado es más corto que el original — NO se toca" with open(path, "w") as f: f.write(s) return True, "ok" def main(): if len(sys.argv) < 3: print(__doc__.split("\n")[2].strip(), file=sys.stderr) return 2 path, nuevas = sys.argv[1], sys.argv[2:] ok, motivo = anadir(path, nuevas) if not ok: print(f" ·· {path}: {motivo}", file=sys.stderr) return 0 if ok else 1 if __name__ == "__main__": sys.exit(main())