diff --git a/docs/state/repro-verificado.tsv b/docs/state/repro-verificado.tsv index 5ee58fbb..108ac495 100644 --- a/docs/state/repro-verificado.tsv +++ b/docs/state/repro-verificado.tsv @@ -233,3 +233,4 @@ ksvg 05e2b73bac4834d960374052796d24ff28fa5d093baf6d4e59169e70001da7c0 2026-09-14 qqc2-desktop-style 215bdf3d07e98d5585254060e2cc574c4247b6656e2c221274a0478e5734da49 2026-09-14 reproduce kirigami-addons d826d6b1bddbaa0b78529ca82e915ac92a64ab3148a913fed2ace4958d8a94c1 2026-09-14 reproduce libplasma 73ec5fb279ea44e6bcfdf4c58d8703ed1307ae7985e56ce55a5da078ea098b7e 2026-09-14 reproduce +syntax-highlighting 3db73c19bdbddcb046a80d11ec112bc7dc60134eeec75b26e907cc756d25d081 2026-09-14 reproduce diff --git a/recipes/incoming-kde/syntax-highlighting-jinja-reproducible.patch b/recipes/incoming-kde/syntax-highlighting-jinja-reproducible.patch new file mode 100644 index 00000000..6abe7fd6 --- /dev/null +++ b/recipes/incoming-kde/syntax-highlighting-jinja-reproducible.patch @@ -0,0 +1,50 @@ +Hacer determinista generate_jinja.py (reproducibilidad — SDD 23) + +El generador de las definiciones Jinja tenía TRES dependencias del azar, y entre +ellas hacían que `libKF6SyntaxHighlighting.so` saliera distinto en cada build +(8.800.310 bytes distintos y hasta el tamaño cambiaba): + +1. `to_do.pop()` sobre un `set` saca un elemento ARBITRARIO. En `--dry-run` el + orden de los `print(out_file)` es lo que CMake usa para `out_xmls`, que acaba + siendo el ORDEN DE LAS ENTRADAS DEL .qrc ⇒ el recurso compilado cambiaba de + disposición entera. Se toma el menor: mismo conjunto, orden fijo. + +2. `version = str(round(time.time()))` hornea la HORA DEL BUILD en el XML + generado. Se honra `SOURCE_DATE_EPOCH` (que el sandbox de takana ya fija), + que es la convención de reproducible-builds; fuera del sandbox se comporta + igual que antes. + +3. `os.listdir()` devuelve el orden del sistema de ficheros. Sólo importa si dos + ficheros declaran el mismo lenguaje (gana el último), pero ordenarlo cuesta + nada y quita la última dependencia del orden de readdir. + +--- a/data/generators/generate_jinja.py ++++ b/data/generators/generate_jinja.py +@@ -113,7 +113,7 @@ + to_visit = set() + + for grammar_dir in grammar_dirs: +- for file_name in os.listdir(grammar_dir): ++ for file_name in sorted(os.listdir(grammar_dir)): + if not file_name.lower().endswith('.xml'): + continue + file_path = os.path.join(grammar_dir, file_name) +@@ -151,7 +151,7 @@ + lang_tag = grammar.getroot() + lang_tag.set('name', jinja_tag.get('name') + '/' + lang_tag.get('name')) + lang_tag.set('section', jinja_tag.get('section')) +- lang_tag.set('version', str(round(time.time()))) ++ lang_tag.set('version', os.environ.get('SOURCE_DATE_EPOCH') or str(round(time.time()))) + lang_tag.set('license', jinja_tag.get('license')) + lang_tag.set('priority', lang_tag.get('priority', '0')) + lang_tag.set('kateversion', max(lang_tag.get('kateversion'), +@@ -265,7 +265,8 @@ + sys.exit(2) + + while to_do: +- lang = to_do.pop() ++ lang = min(to_do) ++ to_do.remove(lang) + out_file = os.path.join(args.output_dir, + args.prefix + os.path.basename(xmls[lang])) + infuse_header(grammars[lang], jinja.getroot(), args.xtra_ext) diff --git a/recipes/incoming-kde/syntax-highlighting.toml b/recipes/incoming-kde/syntax-highlighting.toml index 3c3bc2d5..08a396ce 100644 --- a/recipes/incoming-kde/syntax-highlighting.toml +++ b/recipes/incoming-kde/syntax-highlighting.toml @@ -12,6 +12,34 @@ # # rm -rf po poqm: no hay carpeta po en 6.27.0, pero se limpia poqm defensivamente (gettext-tiny/msgfmt # crashea con catálogos grandes; ecm_install_po_files_as_qm(poqm) quedaría inerte). +# +# ══ ⚠ ERA NO-DETERMINISTA, Y SE ARREGLÓ EL 2026-09-14 (SDD 23) ══════════════════════════════════ +# Dos reconstrucciones con las MISMAS entradas y el MISMO lab daban `libKF6SyntaxHighlighting.so` +# distintos: 8.800.310 bytes diferentes desde el offset 41, y hasta el TAMAÑO cambiaba +# (10.345.888 contra 10.345.840). Las únicas cadenas que diferían eran datos comprimidos, o sea el +# recurso Qt con las definiciones de sintaxis. +# +# No era el indexer —`katehighlightingindexer` construye el índice con `QVariantMap`, que es QMap y +# va ordenado— ni los generadores de Perl, que no iteran hashes. Era `data/generators/ +# generate_jinja.py`, con TRES dependencias del azar: +# +# 1. `to_do.pop()` sobre un `set` saca un elemento ARBITRARIO. En `--dry-run` el orden de los +# `print(out_file)` es lo que CMake recoge en `out_xmls` y acaba siendo **el orden de las +# entradas del `.qrc`** ⇒ el recurso compilado cambiaba de disposición entera. +# 2. `version = str(round(time.time()))` hornea la HORA DEL BUILD dentro del XML generado. +# 3. `os.listdir()` sin ordenar (sólo importa si dos ficheros declaran el mismo lenguaje, pero +# es una dependencia del readdir y no cuesta nada quitarla). +# +# El parche `syntax-highlighting-jinja-reproducible.patch` arregla las tres. MEDIDO en los dos +# sentidos antes de tocar la receta, corriendo el generador a mano: +# +# · antes: tres `PYTHONHASHSEED` distintos ⇒ TRES órdenes distintos de ficheros +# (`jinja-json, jinja-yaml, jinja-toml…` contra `jinja-qml, jinja-dockerfile, jinja-typescript…`) +# · después: las mismas tres semillas ⇒ el MISMO md5 +# · y generando de verdad con semillas y momentos distintos: los 35 XML salen IDÉNTICOS, +# con `version="1"` (de `SOURCE_DATE_EPOCH`, que el sandbox fija) +# · control negativo: sin `SOURCE_DATE_EPOCH` sigue poniendo la hora actual, o sea que fuera del +# sandbox se comporta igual que antes name = "syntax-highlighting" version = "6.27.0" license = "LGPL-2.1-or-later OR LGPL-3.0-or-later" @@ -19,6 +47,7 @@ license = "LGPL-2.1-or-later OR LGPL-3.0-or-later" [source] tarball = "https://download.kde.org/stable/frameworks/6.27/syntax-highlighting-6.27.0.tar.xz" sha256 = "cbff001b9f00d032feb254313ecfee9a6e0a0b3c5a8c82a7e0806c5f1915a545" +patches = ["syntax-highlighting-jinja-reproducible.patch"] [build] compiler = "zig-cc"