Último recurso mecánico, `scripts/licencias-texto.sh`: para las 60 recetas donde la API de GitHub devuelve NOASSERTION (el repo TIENE un LICENSE pero licensee no lo reconoce: texto retocado, encabezado propio, dos licencias en un fichero), baja el texto y lo clasifica acá. 34 identificadas — 16 MIT, 10 Apache-2.0, 7 BSD-2-Clause, 1 BSD-3-Clause. SÓLO PERMISIVAS, Y NO ES PEREZA. MIT, Apache-2.0, BSD, ISC, MPL-2.0 y Unlicense se reconocen por frases inconfundibles y NO tienen variantes -only/-or-later ⇒ reconocer el texto da el SPDX completo. La familia GPL se deja al humano A PROPÓSITO, y la razón es sutil: el COPYING de la GPL es IDÉNTICO tanto si el proyecto es «sólo v3» como «v3 o posterior» — lo que las distingue vive en las cabeceras de los fuentes. Y encima el propio COPYING incluye, en su apéndice «cómo aplicar la licencia», la frase «or (at your option) any later version», así que buscarla da SIEMPRE positivo y parecería evidencia siendo texto de plantilla. Es exactamente la trampa de la regla del `.a` no-PIC, donde grep contaba reubicaciones de .debug_* y mentía. Comprobado a mano un caso que daba mala espina: el LICENSE de `conftest` empieza «Conftest — Write tests against your config files / Copyright (C) 2019 …», que es el formato típico de una cabecera GPL. Leído entero, dice «Licensed under the Apache License, Version 2.0». La clasificación era correcta; la sospecha, barata. Hashes verificados sobre las 36 tocadas: idénticos. Quedan 88, ya sin vía mecánica: los repos donde ni la API ni el texto deciden, la familia GPL sin desambiguar, y tarballs de sitios propios (gmplib, xiph, sr.ht, codeberg…). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
76 lines
4.6 KiB
Bash
Executable File
76 lines
4.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# licencias-texto.sh — último recurso: LEER el fichero LICENSE del repo y clasificarlo por su texto.
|
|
#
|
|
# ── PARA QUÉ, SI YA ESTÁ licencias-detectar.sh ─────────────────────────────────────────────────
|
|
# Aquél pregunta a GitHub «¿qué licencia detectás?» y GitHub a veces contesta NOASSERTION: el repo
|
|
# tiene un LICENSE pero licensee no lo reconoce (texto retocado, dos licencias en un fichero, un
|
|
# encabezado propio…). Quedaron 66 recetas así. Éste baja el TEXTO y lo clasifica acá.
|
|
#
|
|
# ── SÓLO LICENCIAS PERMISIVAS, Y ESO NO ES PEREZA ──────────────────────────────────────────────
|
|
# MIT, Apache-2.0, BSD, ISC y MPL-2.0 se identifican por frases inconfundibles y **no tienen
|
|
# variantes `-only` / `-or-later`** ⇒ reconocer el texto basta para dar el SPDX completo.
|
|
#
|
|
# La familia GPL NO se clasifica acá, a propósito. El fichero COPYING de la GPL es el mismo tanto si
|
|
# el proyecto es «sólo v3» como «v3 o posterior»: lo que distingue una de otra vive en las CABECERAS
|
|
# DE LOS FUENTES, no en el COPYING. Peor todavía: el propio COPYING incluye, en su apéndice «cómo
|
|
# aplicar la licencia», la frase «either version 3 of the License, or (at your option) any later
|
|
# version» — o sea que buscar esa frase en el COPYING da SIEMPRE positivo y **parecería** evidencia
|
|
# siendo puro texto de plantilla. Es la trampa exacta de la regla del `.a` no-PIC, donde `grep`
|
|
# contaba reubicaciones de `.debug_*` y mentía. Las GPL se dejan al humano.
|
|
#
|
|
# Uso: scripts/licencias-texto.sh (escribe docs/licencias-texto.tsv)
|
|
set -uo pipefail
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT"
|
|
SALIDA="${SALIDA:-docs/licencias-texto.tsv}"
|
|
JOBS="${JOBS:-12}"
|
|
command -v gh >/dev/null && gh auth status >/dev/null 2>&1 || { echo "!! 'gh' ausente o sin auth"; exit 1; }
|
|
TMP=$(mktemp -d); trap 'rm -rf "$TMP"' EXIT
|
|
|
|
./scripts/licencias.sh --faltan 2>/dev/null | while IFS= read -r n; do
|
|
f=$(ls "recipes/$n.toml" 2>/dev/null | head -1)
|
|
[ -z "$f" ] && f=$(ls recipes/incoming-*/"$n.toml" 2>/dev/null | head -1)
|
|
[ -z "$f" ] && continue
|
|
u=$(grep -m1 -E '^[[:space:]]*(tarball|repo)[[:space:]]*=' "$f" 2>/dev/null)
|
|
case "$u" in *github.com*) ;; *) continue ;; esac
|
|
slug=$(printf '%s\n' "$u" | sed -E 's#.*github\.com[:/]+([^/"]+)/([^/"]+).*#\1/\2#; s/\.git$//')
|
|
case "$slug" in */*) printf '%s\t%s\n' "$n" "$slug" ;; esac
|
|
done | sort -u > "$TMP/obj.tsv"
|
|
echo "==> a inspeccionar: $(wc -l < "$TMP/obj.tsv")"
|
|
|
|
export TMP
|
|
xargs -P "$JOBS" -I{} sh -c '
|
|
n=$(printf "%s" "{}" | cut -f1); slug=$(printf "%s" "{}" | cut -f2)
|
|
for fich in LICENSE LICENSE.md LICENSE.txt COPYING LICENCE license; do
|
|
c=$(gh api "repos/$slug/contents/$fich" --jq ".content" 2>/dev/null) || continue
|
|
[ -z "$c" ] && continue
|
|
t=$(printf "%s" "$c" | base64 -d 2>/dev/null | head -60 | tr "[:upper:]" "[:lower:]" | tr -s " \n" " ")
|
|
[ -z "$t" ] && continue
|
|
lic=""
|
|
case "$t" in
|
|
*"apache license"*"version 2.0"*) lic="Apache-2.0" ;;
|
|
*"mozilla public license version 2.0"*) lic="MPL-2.0" ;;
|
|
*"permission is hereby granted, free of charge"*) lic="MIT" ;;
|
|
*"permission to use, copy, modify, and/or distribute this software for any purpose"*) lic="ISC" ;;
|
|
*"neither the name of"*"may be used to endorse or promote"*) lic="BSD-3-Clause" ;;
|
|
*"redistributions in binary form must reproduce"*) lic="BSD-2-Clause" ;;
|
|
*"this is free and unencumbered software released into the public domain"*) lic="Unlicense" ;;
|
|
esac
|
|
[ -n "$lic" ] && printf "%s\t%s\t%s:%s\n" "$n" "$lic" "$slug" "$fich" >> "$TMP/ok.tsv"
|
|
break
|
|
done
|
|
' < "$TMP/obj.tsv"
|
|
|
|
N=$(wc -l < "$TMP/ok.tsv" 2>/dev/null || echo 0)
|
|
{
|
|
echo "# licencias-texto.tsv — GENERADO por scripts/licencias-texto.sh. No editar a mano."
|
|
echo "# Clasificación por el TEXTO del fichero LICENSE del repo, para los casos en que la API de"
|
|
echo "# GitHub dice NOASSERTION. SÓLO permisivas (MIT/Apache/BSD/ISC/MPL/Unlicense): no tienen"
|
|
echo "# variantes -only/-or-later, así que reconocer el texto da el SPDX completo. La familia GPL"
|
|
echo "# se deja al humano A PROPÓSITO: su COPYING es idéntico en «sólo v3» y «v3 o posterior», y"
|
|
echo "# encima incluye la frase «or (at your option) any later version» en su apéndice de plantilla"
|
|
echo "# ⇒ buscarla da siempre positivo y parece evidencia sin serlo."
|
|
echo "# Tercera columna: owner/repo:fichero del que se leyó. Total $N"
|
|
sort "$TMP/ok.tsv" 2>/dev/null
|
|
} > "$SALIDA"
|
|
echo "==> $N clasificadas por texto → $SALIDA"
|