Salió de barrer la máquina del usuario y cruzar sus 481 paquetes explícitos contra las 1181 recetas del corpus y las cuatro colas. zsh es su shell —medido en su historial: 1611 `cd`, 1054 `cargo`, 134 `zellij`— y no estaba en ningún lado. Una imagen de takana instalada en su laptop lo dejaba en bash: funciona, pero no es su máquina. Es el mismo hueco de RUNTIME que bash-completion: nadie lo alcanza por deps de build, así que ninguna métrica de deuda puede verlo. Sólo se ve mirando la máquina de quien la usa. Sus tres deps ya estaban selladas (ncurses, pcre2, libcap) ⇒ no arrastra tanda. Los seis parches son de main/zsh de aports y son el trabajo de portabilidad a musl que un import de nix pierde. implicit.patch (16 K) es el gordo: declaraciones implícitas que gcc14/clang rechazan como error. ⚠ RIESGO CONOCIDO para el primer build, heredado de bash.toml: si el configure mete -rdynamic en la línea de enlace, el wrapper de cc del lab tira el -static y el binario sale contra libncursesw.so.6, que NINGÚN artefacto del corpus provee ⇒ arrancaría en el sandbox de Alpine y no dentro de una imagen de takana. Síntoma: `Error relocating ... symbol not found`. El arreglo de bash fue `make LOCAL_LDFLAGS=` y vale igual. Verificar el primer artefacto con `file`: debe decir `statically linked`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
99 lines
4.6 KiB
TOML
99 lines
4.6 KiB
TOML
# zsh 5.9 — **el shell del usuario**, y por eso entra al piso y no a los extras.
|
|
#
|
|
# ══ POR QUÉ ESTA RECETA EXISTE ═════════════════════════════════════════════════════════════════
|
|
# Barrido del 2026-09-16 sobre la laptop del usuario: su shell de login es zsh (1611 `cd`, 1054
|
|
# `cargo`, 134 `zellij` en el historial), y zsh **no tenía receta en el corpus ni en ninguna de las
|
|
# cuatro colas**. Una imagen de takana instalada en esa máquina la dejaba en `bash` — funciona, pero
|
|
# no es su máquina. Es el mismo hueco de RUNTIME que `bash-completion` en `[perfil.base]`: nadie lo
|
|
# alcanza por deps de build, así que ninguna métrica de deuda podía verlo.
|
|
#
|
|
# ⚠ **PUNTO DE PARTIDA, NO SELLADA.** Escrita en el laptop, que no tiene lab ni store (su
|
|
# `.dev-fs/alpine` tiene 104 paquetes contra los 110 de `lab-toolchain.lock`, así que ni siquiera
|
|
# calcula hashes comparables). El primer build va en el worker. Lo que sigue son las trampas
|
|
# conocidas de hermanos ya sellados, anotadas para que el primer build no las redescubra.
|
|
#
|
|
# ══ LOS SEIS PARCHES SON DE ALPINE, Y NO SON OPCIONALES ════════════════════════════════════════
|
|
# Vienen de `main/zsh` de aports y son el trabajo de portabilidad a musl que un import de nix
|
|
# pierde. `implicit.patch` (16 K) es el gordo: declaraciones implícitas que gcc14/clang rechazan
|
|
# como error. Los otros cinco son tests que no aplican fuera de glibc, el instalador de usuario
|
|
# nuevo de Alpine, punteros incompatibles de gcc14 y el cacheo de `man -w`.
|
|
#
|
|
# ══ RIESGO CONOCIDO PARA EL PRIMER BUILD (heredado de bash.toml) ═══════════════════════════════
|
|
# `link = "static"` puede salir DINÁMICO igual, como le pasó a bash: si el `configure` mete
|
|
# `-rdynamic` en la línea de enlace, el wrapper de cc del lab (`sandbox.rs:597`) tira el `-static`
|
|
# inyectado y el binario sale contra `libncursesw.so.6` — que **ningún artefacto del corpus
|
|
# provee**, así que arrancaría en el sandbox de Alpine y no dentro de una imagen de takana. El
|
|
# síntoma exacto a buscar es `Error relocating ... symbol not found`. Si pasa, el arreglo de bash
|
|
# fue `make LOCAL_LDFLAGS=` y vale acá igual.
|
|
# Verificar el primer artefacto con `file`: debe decir `statically linked`.
|
|
name = "zsh"
|
|
version = "5.9"
|
|
license = "MIT"
|
|
|
|
[source]
|
|
tarball = "https://sourceforge.net/projects/zsh/files/zsh/5.9/zsh-5.9.tar.xz"
|
|
# sha256 calculado sobre el tarball bajado el 2026-09-16 (Alpine publica sha512, no sha256).
|
|
sha256 = "9b8d1ecedd5b5e81fbf1918e876752a7dd948e05c1a0dba10ab863842d45acd5"
|
|
patches = [
|
|
"implicit.patch",
|
|
"fix-gcc14-incompatible-pointer-types.patch",
|
|
"zsh-newuser-install-alpine.patch",
|
|
"0001-50278-use-man-w-in-preference-to-manpath-fix-caching.patch",
|
|
"skip-test-failing-on-musl.patch",
|
|
"tests-user.patch",
|
|
]
|
|
|
|
[build]
|
|
compiler = "zig-cc"
|
|
target = "x86_64-linux-musl"
|
|
link = "static"
|
|
# Split de la info de depuración (SDD 23 etapa 4). Entra en `hash_inputs`.
|
|
strip_debug = true
|
|
flags = []
|
|
|
|
[build.phases]
|
|
# de build() de Alpine (traducido; el lab provee $CBUILD/$CHOST).
|
|
#
|
|
# `--enable-function-subdirs` + `--enable-fndir`: zsh instala ~1200 ficheros de funciones en
|
|
# `/usr/share/zsh/functions`. NO se recortan: sin ellas no hay `compinit`, y un zsh sin completado
|
|
# es justamente lo que el usuario no tiene hoy. Es la lección de CLAUDE.md §3 al revés — acá el
|
|
# artefacto "completo" son los datos, no el binario.
|
|
#
|
|
# `--disable-gdbm` es deliberado: gdbm no está en el corpus y sólo aporta el módulo `zsh/db/gdbm`.
|
|
# Encenderlo pediría una receta más para una capacidad que nadie pidió.
|
|
compile = '''
|
|
_abuild_phase() {
|
|
./configure \
|
|
--build=$CBUILD \
|
|
--host=$CHOST \
|
|
--prefix=/usr \
|
|
--bindir=/bin \
|
|
--enable-etcdir=/etc/zsh \
|
|
--enable-pcre \
|
|
--enable-cap \
|
|
--enable-multibyte \
|
|
--enable-function-subdirs \
|
|
--enable-fndir=/usr/share/zsh/functions \
|
|
--enable-zsh-secure-free \
|
|
--disable-gdbm \
|
|
--sysconfdir=/etc \
|
|
--mandir=/usr/share/man \
|
|
--infodir=/usr/share/info \
|
|
--with-tcsetpgrp
|
|
make
|
|
}
|
|
_abuild_phase
|
|
'''
|
|
# de package() de Alpine (traducido $pkgdir→/out). Sin locales: el corpus no los hidrata y pesan.
|
|
install = '''
|
|
_abuild_phase() {
|
|
make DESTDIR="/out" install install.info
|
|
rm -rf "/out"/usr/share/locale
|
|
# `/etc/shells` no se escribe acá: es estado del sistema instalado, no del artefacto.
|
|
}
|
|
_abuild_phase
|
|
'''
|
|
|
|
[deps]
|
|
build = ["binutils", "ncurses", "pcre2", "libcap", "linux-headers", "make"]
|