sergio/takana
> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…
⎇ 282a4ea0e22a7618960605bc02fe3f57a3f0be75
scripts/atuq-xpi.py
Ñawpa willay
Pi imata llamkarqan
ch'uya
atuq: los .xpi sin construir el navegador, y qué se pierde con una extensión «temporal»
1#!/usr/bin/env python3
2"""Empaqueta las extensiones de atuq en `.xpi` SIN construir el navegador.
3
4Uso: atuq-xpi.py [--out <dir>] (por defecto: work/atuq-xpi)
5
6POR QUÉ NO REPITE EL EMPAQUETADOR
7---------------------------------
8El zip determinista vive en `recipes/atuq/tools/rebrand.py` (`empaquetar_extensiones`) y es el que
9entra en el artefacto sellado. Copiarlo acá daría dos empaquetadores que derivan: el día que uno
10cambie el `date_time` o el orden de las entradas, el `.xpi` que te instalás a mano deja de ser el
11mismo que trae la imagen, y eso NO se nota — se instala igual. Así que este script IMPORTA ese
12módulo y llama a su función; lo único que aporta es el andamio de directorios que `rebrand.py`
13espera (que normalmente es el árbol de firefox a medio construir) y que acá es un temporal.
14
15⚠ `rebrand.py` no tiene `if __name__`: lee `sys.argv` y **llama a `main()`** al importarse, y
16`main()` exige el árbol de firefox entero (se muere en `application.ini`). Así que no se importa —
17se ejecuta su fuente con esa última llamada quitada, y se comprueba que estaba antes de quitarla:
18si alguien le pone un `if __name__` algún día, este script falla RUIDOSAMENTE en vez de empaquetar
19con un módulo que ya no es el que creía.
20
21Y no se le agrega el `if __name__` a `rebrand.py` a propósito: ese fichero está DENTRO del overlay
22cuya huella es el `BuildID` (`huella_overlay`), así que tocarlo invalida el hash de atuq y obliga a
23reconstruir firefox con PGO. Un `if __name__` no vale ese precio.
24"""
25import os
26import shutil
27import sys
28import tempfile
29
30RAIZ = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
31OVERLAY = os.path.join(RAIZ, "recipes", "atuq")
32
33destino = os.path.join(RAIZ, "work", "atuq-xpi")
34if len(sys.argv) > 2 and sys.argv[1] == "--out":
35 destino = os.path.abspath(sys.argv[2])
36elif len(sys.argv) > 1:
37 print(__doc__, file=sys.stderr)
38 raise SystemExit(2)
39
40tmp = tempfile.mkdtemp(prefix="atuq-xpi.")
41try:
42 appdir = os.path.join(tmp, "usr", "lib", "atuq")
43 os.makedirs(appdir)
44 sys.argv = ["rebrand.py", appdir, OVERLAY, tmp]
45 fuente = os.path.join(OVERLAY, "tools", "rebrand.py")
46 with open(fuente, encoding="utf-8") as fh:
47 codigo = fh.read()
48 if not codigo.rstrip().endswith("main()"):
49 print(f"atuq-xpi: {fuente} ya no termina en main() — revisá este script antes de confiar en él",
50 file=sys.stderr)
51 raise SystemExit(1)
52 codigo = codigo.rstrip()[: -len("main()")]
53 mod = {"__name__": "rebrand", "__file__": fuente}
54 exec(compile(codigo, fuente, "exec"), mod)
55
56 resultados = mod["empaquetar_extensiones"]()
57 os.makedirs(destino, exist_ok=True)
58 for nombre, ext_id, n_ficheros, tamano, _url in resultados:
59 origen = os.path.join(appdir, "distribution", "extensions", f"{ext_id}.xpi")
60 shutil.copy2(origen, os.path.join(destino, f"{ext_id}.xpi"))
61 print(f"{ext_id}.xpi {tamano:>7} B {n_ficheros} ficheros ({nombre})")
62 print(f"\n{len(resultados)} extensiones en {destino}")
63finally:
64 shutil.rmtree(tmp, ignore_errors=True)