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)