Traducir de a pares no escala: con nginx, apache, caddy, haproxy y lighttpd son 20 traductores, y cada formato nuevo agrega 2N. Con un modelo intermedio son N lectores + M escritores: un formato nuevo cuesta uno o dos plugins y estrena todos los pares de golpe. **Probado, no argumentado**: el lector de apache se agregó SIN TOCAR el escritor de Caddy, y con eso `apache → caddy` funciona sin que exista ningún traductor de ese par. Las dos salidas las valida el caddy del propio corpus: `Valid configuration` en las dos. Los plugins se DESCUBREN (`formatos/` + `@lector` / `@escritor`): una lista mantenida a mano se desincroniza y el formato nuevo «no existe» sin que nada falle. `--list` dice qué pares habilita. **El acta viaja DENTRO del modelo**, y es la decisión que hace que el pivote no mienta: si fuera un efecto de cada traductor, lo que el LECTOR no entendió se perdería antes de llegar al escritor. El escritor además puede agregarle — Caddy no tiene equivalente de `location ~`, así que en vez de emitir un `handle` de prefijo que SE PARECE, lo manda al acta. Parecerse es peor que faltar. Y un bug del lector de apache, encontrado probando: `ProxyPass` tiene dos formas y dentro de `<Location>` lleva sólo la URL. Mirar sólo la de tres tokens dejaba sin traducir la forma más común y el acta la reportaba como «no reconocida» — un falso negativo que manda a escribir a mano algo que el lector sí sabe hacer. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RomoxEGZUhaT4pob1QSX5x
38 lines
1.0 KiB
Python
38 lines
1.0 KiB
Python
"""Registro de PLUGINS de formato (SDD 29).
|
|
|
|
Un formato se agrega dejando un fichero en este directorio que decore sus funciones con `@lector` y
|
|
`@escritor`. No hay que tocar el centro ni ningún otro plugin: ése es el punto de tener un pivote.
|
|
|
|
@lector("nginx")
|
|
def leer(texto) -> Config: ...
|
|
|
|
@escritor("caddy")
|
|
def escribir(cfg) -> str: ...
|
|
"""
|
|
import importlib, pkgutil, pathlib
|
|
|
|
LECTORES, ESCRITORES = {}, {}
|
|
|
|
|
|
def lector(nombre):
|
|
def deco(f):
|
|
LECTORES[nombre] = f
|
|
return f
|
|
return deco
|
|
|
|
|
|
def escritor(nombre):
|
|
def deco(f):
|
|
ESCRITORES[nombre] = f
|
|
return f
|
|
return deco
|
|
|
|
|
|
def cargar():
|
|
"""Importa todos los plugins del directorio. Descubrimiento, no lista cableada: una lista que hay
|
|
que editar a mano se desincroniza y el formato nuevo 'no existe' sin que nada falle."""
|
|
for m in pkgutil.iter_modules([str(pathlib.Path(__file__).parent)]):
|
|
if not m.name.startswith("_"):
|
|
importlib.import_module(f"{__name__}.{m.name}")
|
|
return LECTORES, ESCRITORES
|