Ehundu 0.15.0
El contrato, repasado antes de congelarlo. La 0.15 no trae funciones nuevas: es la versión en la que se ha leído el contrato entero contra el código, para que lo que la 1.0 vaya a prometer sea cierto. Salen de ahí las decisiones 128 a 140 de docs/formato.md (se abre en una pestaña nueva). Lo que el motor hacía y solo estaba en el código queda escrito (las reglas exactas de los atajos, qué es un enlace a otro dominio, el orden de los textos, la tabla de letras del filtro slug, lo que el motor escribe en salida/), y lo que se tomaba a ciegas, por ser peligroso o ambiguo, ahora se avisa o detiene el build. Compilados con la 0.14.0 y con esta, los veintitrés sitios de prueba dan los mismos ficheros, uno a uno, sin avisos nuevos.
Lo que ahora detiene el build (con el fichero y la línea, en el error). Un formato que no es un entero mayor que cero ("2" entre comillas, 0): antes se avisaba y se tomaba por 1, y podía hacer pasar por bueno un proyecto de otro formato. Una url de sitio.yml con ruta o con parámetros (https://ejemplo.com/sub/): el motor la aceptaba y dejaba el sitio a medias, y la url es la del dominio, con o sin la barra final (decisiones 130 y 136). Un punto en el nombre de una página, de un fichero de datos/ o de un _datos.yml cuando lo que va tras el último punto no tiene forma de código de idioma (guia.v2.md, 2024.10.01-titulo.md): antes se saltaba el fichero con un aviso y el siguiente despliegue borraba la página del servidor (decisión 135).
Lo que ahora avisa. Una fecha (fecha, publicar) escrita con hora o con zona avisa y se toma solo el día, desde su medianoche en la zona del sitio: una fecha es un día (decisión 129). Los cinco campos que el motor escribe siempre en pagina (ruta, contenido, markdown, encabezados y traducciones) avisan si el front matter los usa, y el campo se ignora, como ya hacía idioma; antes los tapaban en silencio (decisión 133). componentes, reservado desde hace tiempo, avisa si un sitio lo usa como campo propio, aunque sigue llegando a la plantilla (decisión 138).
Lo que cambia en la salida. Una imagen enlazada a otro dominio lleva target="_blank" y rel, como cualquier enlace escrito en Markdown: la figura de una imagen sola enlazada y el atajo imagen con enlace. La plantilla imagen recibe dos variables nuevas, externo y rel; una plantilla imagen del sitio que no las use queda como la escribió (decisión 131). La carpeta publico/ deja de copiar lo que dejan el sistema y Git (.DS_Store, .gitkeep, Thumbs.db, desktop.ini y cualquier .git), y contenido/ ignora Thumbs.db y desktop.ini; .htaccess y .well-known/ se siguen copiando (decisión 138). Ninguno de los sitios de prueba cambia.
La compilación incremental persistida, más segura. La huella que decide si la memoria de .ehundu/ sirve para este motor mira ahora el contenido de los ficheros del motor y las versiones de sus dependencias instaladas (y la versión menor de PHP), no solo la fecha de los ficheros: un composer update que cambia Twig o CommonMark ya no reaprovecha páginas hechas con la versión anterior. Cada huella de un fichero anota cuándo se tomó, para que un fichero modificado mientras se compilaba no se dé por visto. La espera al cerrojo de .ehundu/ tiene un tope de un minuto, y un presupuesto de tiempo enorme en avanzar o en el despliegue ya no acaba tras la primera tarea. Ordenar por texto calcula la clave de cada página una vez, en vez de en cada comparación. Al actualizar, la primera compilación es completa (la memoria de la 0.14 no vale para esta): ocurre una vez.
Lo que la 1.0 promete y lo que no. La compilación por lotes (CompiladorPorLotes y su estado en .ehundu/lote.json) pasa a @internal: lo que se promete para repartir una compilación en llamadas es CompiladorIncrementalEnProceso::avanzar, que devuelve el mismo Lote. Si la usabas, sigue funcionando; solo deja de estar prometida (decisión 128). docs/biblioteca.md precisa los parámetros por nombre de Desplegador::desplegar y lo que hay dentro de Pagina::$campos y de Lectura::$datos. El contrato promete el mismo HTML con la misma versión del motor y de sus dependencias, y no entre versiones: lo que cambie al actualizar se anotará aquí (decisión 137).
Para quien incruste la biblioteca. Formato::leer ya no recibe los avisos: lanza ErrorDeProyecto si el valor no vale. Informe::$rehechas vale siempre un número (en una compilación completa, el de páginas), no null. Para un despliegue propio, Configuracion::abrir abre el destino que dice la configuración, y PlanDeDespliegue::deSalida y PlanDeDespliegue::ficheros trazan o leen los ficheros de salida/ sin repetir el código del despliegue. Y Manifiesto::leer rechaza las rutas que salen del sitio (.., una barra inicial, una letra de unidad): el manifiesto vive en el destino, y quien pudiera escribirlo allí no debe poder hacer que Ehundu borre otra cosa. Con --todo se rehace.
Documentación. El registro de decisiones pasa al final de formato.md, como apéndice A, para que quien lee el contrato encuentre la norma antes que su historia (las secciones no se renumeran). El esquema de los editores tiene su documento, docs/esquema.md (se abre en una pestaña nueva), que separa lo que es formato de cómo se comporta un editor. La documentación seguirá en español, como el formato: no se promete en inglés. Y ehundu --version (o -V) dice qué versión es.
Esta versión en GitHub (se abre en una pestaña nueva), con el ehundu.phar.