═══ LA CORRECCIÓN DE FONDO: no es `pack`, son las IMÁGENES ═══
El SDD 19 y el 20 decían «inyectar el texto de la licencia en `hammer pack`, que es aguas
abajo del ArtifactHash y sale gratis». La conclusión sobre el coste era correcta pero el
SITIO estaba mal, y por una razón que sólo se ve leyendo el código: `pack` produce un
`.swm`, que es una RECETA DE TRANSFORMACIÓN sobre fuente pública y por diseño explícito
«NUNCA transporta binarios cocidos»; e `install` REPRODUCE construyendo, con cache-hit del
corpus, en vez de bajar binarios. O sea que **el canal de paquetes de hammer no distribuye
binarios** y la obligación de acompañar-el-binario ahí casi no aplica.
Donde sí aplica, con toda su fuerza, es en la IMAGEN INSTALABLE: su rootfs se puebla con
`hammer install` sobre un prefix y de ahí sale un USB/ISO lleno de binarios que se le da a
alguien. Ése es el punto de entrega. (La obligación del espejo de FUENTES es otra y sigue
entera: las recetas apuntan a URLs de terceros que se caen.)
═══ LO QUE ENTRA ═══
· `scripts/licencias-textos.sh` + `licenses/`: los 44 textos CANÓNICOS de SPDX
(spdx/license-list-data), uno por identificador realmente en uso — la lista se saca de las
recetas, no de un fichero escrito a mano que se desincroniza. 764K.
· `scripts/licencias-rootfs.sh`: escribe /usr/share/licenses/<pkg>/ con el texto de CADA
licencia de la expresión (`Unlicense OR MIT` ⇒ los DOS textos: en un OR el destinatario
elige, y entregar uno solo le quita una opción que el autor le concedió), más un
MANIFEST.tsv. Medido: 1,0 MB para el perfil `cli` de 44 paquetes.
═══ Y SOBRE TODO: ES UN VETO ═══
Sale ≠0 si algún paquete del rootfs no declara licencia. Un informe que no puede bloquear no
cambia lo que ocurre; esto corta el paso. Y se ganó el sueldo al primer intento: reveló que
los perfiles `base` y `cli` —los dos más simples, los que primero se publicarían— llevaban
10 y 12 paquetes con binarios y licencia desconocida. Curados los 10 que se podían afirmar
(doas, iputils, less, mandoc, procps-ng, rsync, strace, sudo, tree, usbutils); ambos perfiles
bajan a 2.
Esos 2 NO se rellenan a propósito, y quedan vetando:
· lsof — licencia propia del proyecto, sin identificador SPDX. Toca `LicenseRef-lsof` con
su texto, que ya viaja en el tarball (la receta instala su COPYING).
· tzdata — dominio público por declaración de sus autores, y SPDX no tiene identificador
para eso (es una AUSENCIA de licencia, no una licencia). Toca
`LicenseRef-PublicDomain` documentado, no forzar uno de la lista.
De paso: normalizado `GPL-3.0+` (sufijo antiguo) a `GPL-3.0-or-later`, misma equivalencia
documentada que la barra de Cargo. Y el caso especial que puse para `Linux-syscall-note`
(«las excepciones viven en exceptions/») era una suposición razonable y FALSA: SPDX las
publica en el mismo `text/`; ese directorio no existe.
1063 de 1141 (93%). Hashes verificados: 0 movidos.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
75 lines
4.4 KiB
Bash
Executable File
75 lines
4.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# licencias-textos.sh — baja los textos CANÓNICOS de las licencias que el catálogo usa, a `licenses/`.
|
|
#
|
|
# ── POR QUÉ HACEN FALTA LOS TEXTOS, NO SÓLO EL IDENTIFICADOR ───────────────────────────────────
|
|
# Saber que un paquete es GPL-2.0-or-later no cumple la GPL. La obligación al distribuir binarios es
|
|
# **acompañarlos del texto de la licencia**. El identificador sirve para razonar (compatibilidad,
|
|
# informes por imagen); el TEXTO es lo que hay que entregar.
|
|
#
|
|
# ── ⚠ DÓNDE SE ENTREGA, QUE NO ES DONDE YO CREÍA ───────────────────────────────────────────────
|
|
# El SDD 19/20 decía «inyectar el texto en `hammer pack`». **Está mal, y por una razón de fondo**:
|
|
# `pack` produce un `.swm`, que es una RECETA DE TRANSFORMACIÓN sobre fuente pública y —por diseño
|
|
# explícito— «NUNCA transporta binarios cocidos»; e `install` REPRODUCE construyendo, con cache-hit
|
|
# del corpus, en vez de bajar binarios. O sea que el canal de paquetes de hammer **no distribuye
|
|
# binarios**, y la obligación de acompañar-el-binario ahí casi no aplica.
|
|
#
|
|
# Donde SÍ aplica, y con toda su fuerza, es en **las IMÁGENES INSTALABLES**: el rootfs se puebla con
|
|
# `hammer install` sobre un prefix y de ahí sale un USB/ISO lleno de binarios que se le da a alguien.
|
|
# Ése es el punto de entrega, y por eso el consumidor de estos textos es el armado del rootfs.
|
|
# (La otra obligación, el espejo de FUENTES, no la toca esto y sigue pendiente: las recetas apuntan a
|
|
# URLs de terceros que se caen.)
|
|
#
|
|
# ── LA FUENTE: el repo canónico de SPDX ────────────────────────────────────────────────────────
|
|
# `spdx/license-list-data`, `text/<ID>.txt`. Es la referencia normativa del identificador que ya
|
|
# usamos, así que texto e identificador no pueden divergir.
|
|
#
|
|
# Nota sobre los identificadores OBSOLETOS (`GPL-3.0`, `LGPL-2.1`…): SPDX no publica un texto propio
|
|
# para ellos porque **el texto es el mismo** que el de la variante moderna — lo que distingue
|
|
# `-only` de `-or-later` es la CONCESIÓN, no el documento. Así que para esos se guarda el texto de la
|
|
# variante base y se anota. No confundir: eso NO resuelve la ambigüedad del identificador, que sigue
|
|
# siendo trabajo humano (`scripts/licencias.sh --revisar`).
|
|
#
|
|
# Uso: scripts/licencias-textos.sh
|
|
set -uo pipefail
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT"
|
|
DEST="${DEST:-licenses}"
|
|
command -v gh >/dev/null && gh auth status >/dev/null 2>&1 || { echo "!! 'gh' ausente o sin auth"; exit 1; }
|
|
mkdir -p "$DEST"
|
|
|
|
# Los identificadores realmente en uso, sacados de las recetas (no de una lista escrita a mano, que
|
|
# se desincroniza). Se parten las expresiones compuestas: `MIT OR Apache-2.0` son dos textos.
|
|
for f in recipes/*.toml recipes/incoming-*/*.toml; do
|
|
[ -f "$f" ] || continue
|
|
awk -F'"' '/^\[/{exit} /^[[:space:]]*license[[:space:]]*=/{print $2; exit}' "$f" 2>/dev/null
|
|
done | tr ' ' '\n' | grep -E '^[A-Za-z0-9]' | grep -vE '^(OR|AND|WITH)$' | sort -u > /tmp/.spdx-uso
|
|
|
|
# `Linux-syscall-note` es una EXCEPCIÓN (va tras `WITH`), no una licencia — pero SPDX la publica en
|
|
# el mismo `text/` que las licencias, no en un `exceptions/` aparte (comprobado: ese directorio no
|
|
# existe en el repo). O sea que no necesita caso especial: la suposición razonable era falsa.
|
|
ok=0; falta=0; sinfich=""
|
|
while IFS= read -r id; do
|
|
[ -z "$id" ] && continue
|
|
[ -s "$DEST/$id.txt" ] && { ok=$((ok+1)); continue; }
|
|
base="$id"
|
|
case "$id" in
|
|
GPL-2.0) base="GPL-2.0-only" ;; # obsoletos: mismo TEXTO que la variante base (ver cabecera)
|
|
GPL-3.0) base="GPL-3.0-only" ;;
|
|
LGPL-2.1) base="LGPL-2.1-only" ;;
|
|
LGPL-3.0) base="LGPL-3.0-only" ;;
|
|
AGPL-3.0) base="AGPL-3.0-only" ;;
|
|
esac
|
|
ruta="text/$base.txt"
|
|
if gh api "repos/spdx/license-list-data/contents/$ruta" --jq '.content' 2>/dev/null \
|
|
| base64 -d > "$DEST/$id.txt" 2>/dev/null && [ -s "$DEST/$id.txt" ]; then
|
|
ok=$((ok+1))
|
|
else
|
|
rm -f "$DEST/$id.txt"; falta=$((falta+1)); sinfich="$sinfich $id"
|
|
fi
|
|
done < /tmp/.spdx-uso
|
|
|
|
echo "==> textos en $DEST/: $ok · sin texto canónico: $falta"
|
|
[ -n "$sinfich" ] && {
|
|
echo "!! sin texto:$sinfich"
|
|
echo "!! (identificadores propios del proyecto o no publicados por SPDX — hay que ponerlos a mano)"
|
|
}
|