licencias: la declaración del autor manda — y arreglo 5 recetas que ROMPÍ y commiteé

Dos cosas: una mejora de calidad y un fallo mío que hay que contar entero.

═══ EL FALLO: escribí un error JSON dentro de 5 recetas y las commiteé rotas ═══
En `a6a9d59`, cinco recetas quedaron con
    license = "{"message":"Not Found","documentation_url":"...","status":"404"}"
Causa: cuando el repo da 404 (renombrado, borrado, privado), `gh api` escribe el CUERPO DEL
ERROR en stdout y el filtro `--jq` falla, así que la variable queda valiendo el JSON. Mi
`case` sólo descartaba ""/null/NOASSERTION/other ⇒ el JSON pasó como si fuera una licencia.
Las comillas ROMPEN el TOML, y esas 5 recetas dejaron de parsear y de tener ArtifactHash.

No lo vio nadie leyendo: lo cazó la comparación de hashes, al detectar que `cargo-sort`
había cambiado. Afectadas: cargo-sort, cargo-audit, cargo-binstall, waybackurls, usbutils.

La lección no es «se me pasó un caso», es que **validé los «no sé» conocidos en vez de la
FORMA del dato**. Ahora se acepta sólo lo que tiene forma de expresión SPDX, y la barrera
está en los DOS sitios que escriben (detectar y sembrar), más un GUARDIÁN en el informe que
sale ≠0 si alguna licencia tiene forma imposible. Un fallo aguas arriba disfrazado de dato
hay que verlo sin buscarlo.

Y de paso normalizadas 11 licencias con la barra antigua de Cargo (`MIT/Apache-2.0`), que
no es SPDX válido. Traducir la barra a OR no es inferir: Cargo documentó esa equivalencia.

═══ LA MEJORA: `scripts/licencias-cargo.sh` ═══
Lee la licencia que el AUTOR declara en su Cargo.toml, pidiéndola AL TAG QUE LA RECETA
PINEA (`?ref=v<version>`, con HEAD como último recurso y anotando cuál se usó). 176
obtenidas, 167 al tag exacto. Es la fuente más autoritativa de las que usamos y corrige los
dos defectos de la detección por API de una vez:
 · las licencias DOBLES dejan de colapsar: `fd` pasa de `Apache-2.0` a `MIT OR Apache-2.0`,
   `ripgrep` a `Unlicense OR MIT`, `bat` a `MIT OR Apache-2.0`;
 · los SPDX AMBIGUOS caen de 71 a 55, porque el autor sí escribe -only/-or-later.
66 corregidas, 7 nuevas. Y aparecieron cosas que la detección había perdido: `eza` es
EUPL-1.2, una copyleft europea que se habría empaquetado creyendo otra cosa.

Jerarquía de evidencia, escrita en la cabecera del script: nombre (prohibido) < familia/URL
de fuente < API de licencias de GitHub < Cargo.toml del autor.

997 de 1141 (87%). Verificación COMPLETA sobre las 77 recetas tocadas —no una muestra—:
0 hashes cambiados, y 5 que ahora parsean y en HEAD no.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-07 13:51:09 -04:00
co-authored by Claude Opus 5
parent 5e42d201b1
commit c8d1357f06
81 changed files with 389 additions and 73 deletions
+185
View File
@@ -0,0 +1,185 @@
# licencias-cargo.tsv — GENERADO por scripts/licencias-cargo.sh. No editar a mano.
#
# La licencia que el AUTOR declara en su Cargo.toml: expresión SPDX escrita por quien tiene
# la potestad de licenciar. Sin ambigüedad -only/-or-later y SIN colapsar las dobles ⇒ manda
# sobre la detección por API de GitHub, que pierde ambas cosas. Sembrar con FORZAR=1.
#
# Tercera columna = el ref con el que se resolvió. Un tag concreto significa que el dato es
# de la VERSIÓN QUE EMPAQUETAMOS; 'HEAD(aprox)' que no se halló el tag y puede diferir.
# Total 176 · al tag exacto 167 · aproximadas 9
aichat MIT OR Apache-2.0 v0.30.0
angle-grinder MIT v0.19.6
atac MIT v0.23.0
bacon AGPL-3.0 v3.23.0
bandwhich MIT v0.23.1
bat MIT OR Apache-2.0 v0.26.1
bingrep MIT v0.12.1
bob-nvim MIT v4.1.7
bottom MIT 0.12.3
broot MIT v1.57.0
caligula GPL-3.0 v0.5.0
cargo-bloat MIT v0.12.1
cargo-bundle-licenses MIT/Apache-2.0 v4.2.0
cargo-cache MIT/Apache-2.0 0.8.3
cargo-careful MIT OR Apache-2.0 v0.4.10
cargo-criterion Apache-2.0/MIT 1.1.0
cargo-deb MIT v3.7.0
cargo-deny MIT OR Apache-2.0 0.19.9
cargo-edit Apache-2.0 OR MIT v0.13.11
cargo-expand MIT OR Apache-2.0 1.0.122
cargo-feature MIT v0.7.0
cargo-features-manager MIT v0.11.0
cargo-flamegraph MIT OR Apache-2.0 v0.6.13
cargo-fuzz MIT OR Apache-2.0 0.13.2
cargo-generate MIT OR Apache-2.0 v0.23.9
cargo-hack Apache-2.0 OR MIT v0.6.45
cargo-llvm-cov Apache-2.0 OR MIT v0.8.5
cargo-llvm-lines MIT OR Apache-2.0 0.4.46
cargo-machete MIT v0.9.2
cargo-make Apache-2.0 0.37.24
cargo-modules MPL-2.0 v0.26.0
cargo-msrv Apache-2.0 OR MIT v0.19.3
cargo-mutants MIT v27.1.0
cargo-ndk Apache-2.0 OR MIT v4.1.2
cargo-outdated MIT v0.19.0
cargo-readme MIT OR Apache-2.0 v3.3.2
cargo-semver-checks Apache-2.0 OR MIT v0.48.0
cargo-sort MIT/Apache-2.0 v2.1.3
cargo-supply-chain Apache-2.0 OR MIT OR Zlib v0.3.4
cargo-sweep MIT v0.8.0
cargo-temp MIT OR Apache-2.0 v0.4.1
cargo-udeps MIT OR Apache-2.0 v0.1.61
cargo-watch CC0-1.0 v8.5.3
cargo-wipe MIT v0.4.0
cargo-wizard MIT v0.2.3
cargo-zigbuild MIT v0.22.3
cbindgen MPL-2.0 v0.27.0
choose GPL-3.0-or-later v1.3.7
cobalt MIT v0.20.4
comrak BSD-2-Clause v0.52.0
cosmic-comp GPL-3.0-only HEAD(aprox)
cosmic-edit GPL-3.0-only HEAD(aprox)
cosmic-files GPL-3.0-only HEAD(aprox)
cosmic-osd GPL-3.0-or-later HEAD(aprox)
cosmic-session GPL-3.0-only HEAD(aprox)
cosmic-settings-daemon GPL-3.0-or-later HEAD(aprox)
cosmic-term GPL-3.0-only HEAD(aprox)
cpc MIT v3.0.0
csview MIT OR Apache-2.0 v1.3.4
csvlens MIT v0.13.0
dalfox MIT v3.1.2
ddh LGPL-3.0 0.13.0
delta MIT 0.19.2
difftastic MIT 0.69.0
diffutils MIT OR Apache-2.0 v0.5.0
diskus MIT/Apache-2.0 v0.9.0
dotter Unlicense v0.13.4
dua MIT v2.34.0
dufs MIT OR Apache-2.0 v0.46.0
dust Apache-2.0 v1.2.4
erdtree MIT v3.1.2
eza EUPL-1.2 v0.23.4
fastmod Apache-2.0 v0.4.4
fblog WTFPL v4.17.0
fd MIT OR Apache-2.0 v10.4.2
feroxbuster MIT v2.13.1
findutils MIT 0.9.1
findutils-xargs MIT 0.9.1
fnm GPL-3.0 v1.39.0
fselect MIT OR Apache-2.0 0.10.1
genact MIT v1.5.1
git-absorb BSD-3-Clause 0.9.0
git-graph MIT v0.7.0
git-igitt MIT v0.1.21
gitoxide MIT OR Apache-2.0 v0.54.0
gitui MIT v0.28.1
gitu MIT v0.42.0
gptman MIT OR Apache-2.0 v1.1.0
grcov MPL-2.0 v0.9.1
grex Apache-2.0 v1.4.6
heh MIT v0.6.3
hexyl MIT/Apache-2.0 v0.17.0
hgrep MIT v0.3.9
htmlq MIT v0.4.0
hwatch MIT 0.4.2
hyperfine MIT OR Apache-2.0 v1.20.0
igrep MIT v1.3.0
jnv MIT v0.7.1
joshuto LGPL-3.0 v0.9.9
just CC0-1.0 1.51.0
kbs2 MIT v0.7.3
kmon GPL-3.0 v1.7.1
kubie Zlib v0.26.1
lsd Apache-2.0 v1.2.0
macchina MIT v6.4.0
maturin MIT OR Apache-2.0 v1.12.6
mcfly MIT v0.9.3
mdbook-mermaid MPL-2.0 v0.17.0
mdbook-toc MPL-2.0 0.15.4
miniserve MIT v0.35.0
mise MIT v2026.7.0
monolith CC0-1.0 v2.10.1
natls MIT v2.1.14
navi Apache-2.0 v2.24.0
netscanner MIT v0.6.41
nomino MIT OR Apache-2.0 v1.6.4
nu MIT 0.104.1
oha MIT v1.14.0
otree MIT v0.6.5
ouch MIT 0.8.0
ox GPL-2.0 0.7.7
parallel-disk-usage Apache-2.0 0.21.1
pastel MIT/Apache-2.0 v0.12.0
pls GPL-3.0-or-later v0.0.1-beta.10
pop-launcher MPL-2.0 1.2.7
presenterm BSD-2-Clause v0.16.1
procs MIT v0.14.11
rep-grep MIT 0.0.8
repgrep Unlicense OR MIT OR Apache-2.0 0.16.1
rip2 GPL-3.0+ v0.9.6
ripgrep-all AGPL-3.0-or-later v0.10.10
ripgrep Unlicense OR MIT 14.1.1
ripsecrets MIT v0.1.11
rnr MIT v0.5.1
ruplacer BSD-3-Clause v0.10.0
russ AGPL-3.0-or-later HEAD(aprox)
rustcat GPL-3.0 v3.0.0
rustic Apache-2.0 OR MIT v0.11.3
rustscan GPL-3.0-only 2.4.1
rust-script MIT/Apache-2.0 0.36.0
sccache Apache-2.0 v0.15.0
sendme Apache-2.0 OR MIT v0.33.0
serie MIT v0.8.0
shellharden MPL-2.0 v4.3.1
simple-http-server MIT v0.8.0
skim MIT v4.7.0
sshs MIT 4.7.2
ssh-vault BSD-3-Clause 1.2.10
starship ISC v1.25.1
stylua MPL-2.0 v2.5.2
systemctl-tui MIT v0.5.2
taskwarrior-tui MIT v0.27.0
tealdeer MIT OR Apache-2.0 v1.8.1
television MIT 0.15.9
tenere GPL-3.0-or-later v0.11.3
tere EUPL-1.2 v1.6.0
the-way MIT v0.20.3
tokei MIT OR Apache-2.0 v14.0.0
tomlq MIT 0.2.2
topgrade GPL-3.0-or-later v17.6.1
trunk MIT/Apache-2.0 v0.21.14
ttyper MIT v1.6.0
tuc GPL-3.0-or-later v1.3.0
tuckr GPL-3.0-or-later 0.13.1
viddy MIT v1.3.1
viu MIT v1.6.1
vivid MIT/Apache-2.0 v0.11.1
wasm-pack MIT OR Apache-2.0 v0.15.0
xan Unlicense OR MIT 0.59.0
xdg-desktop-portal-cosmic GPL-3.0-or-later HEAD(aprox)
xh MIT v0.25.3
xsv Unlicense/MIT 0.13.0
xwin Apache-2.0 OR MIT 0.7.0
zenith MIT 0.15.0
zola EUPL-1.2 v0.22.1
zoxide MIT v0.9.9
1 # licencias-cargo.tsv — GENERADO por scripts/licencias-cargo.sh. No editar a mano.
2 #
3 # La licencia que el AUTOR declara en su Cargo.toml: expresión SPDX escrita por quien tiene
4 # la potestad de licenciar. Sin ambigüedad -only/-or-later y SIN colapsar las dobles ⇒ manda
5 # sobre la detección por API de GitHub, que pierde ambas cosas. Sembrar con FORZAR=1.
6 #
7 # Tercera columna = el ref con el que se resolvió. Un tag concreto significa que el dato es
8 # de la VERSIÓN QUE EMPAQUETAMOS; 'HEAD(aprox)' que no se halló el tag y puede diferir.
9 # Total 176 · al tag exacto 167 · aproximadas 9
10 aichat MIT OR Apache-2.0 v0.30.0
11 angle-grinder MIT v0.19.6
12 atac MIT v0.23.0
13 bacon AGPL-3.0 v3.23.0
14 bandwhich MIT v0.23.1
15 bat MIT OR Apache-2.0 v0.26.1
16 bingrep MIT v0.12.1
17 bob-nvim MIT v4.1.7
18 bottom MIT 0.12.3
19 broot MIT v1.57.0
20 caligula GPL-3.0 v0.5.0
21 cargo-bloat MIT v0.12.1
22 cargo-bundle-licenses MIT/Apache-2.0 v4.2.0
23 cargo-cache MIT/Apache-2.0 0.8.3
24 cargo-careful MIT OR Apache-2.0 v0.4.10
25 cargo-criterion Apache-2.0/MIT 1.1.0
26 cargo-deb MIT v3.7.0
27 cargo-deny MIT OR Apache-2.0 0.19.9
28 cargo-edit Apache-2.0 OR MIT v0.13.11
29 cargo-expand MIT OR Apache-2.0 1.0.122
30 cargo-feature MIT v0.7.0
31 cargo-features-manager MIT v0.11.0
32 cargo-flamegraph MIT OR Apache-2.0 v0.6.13
33 cargo-fuzz MIT OR Apache-2.0 0.13.2
34 cargo-generate MIT OR Apache-2.0 v0.23.9
35 cargo-hack Apache-2.0 OR MIT v0.6.45
36 cargo-llvm-cov Apache-2.0 OR MIT v0.8.5
37 cargo-llvm-lines MIT OR Apache-2.0 0.4.46
38 cargo-machete MIT v0.9.2
39 cargo-make Apache-2.0 0.37.24
40 cargo-modules MPL-2.0 v0.26.0
41 cargo-msrv Apache-2.0 OR MIT v0.19.3
42 cargo-mutants MIT v27.1.0
43 cargo-ndk Apache-2.0 OR MIT v4.1.2
44 cargo-outdated MIT v0.19.0
45 cargo-readme MIT OR Apache-2.0 v3.3.2
46 cargo-semver-checks Apache-2.0 OR MIT v0.48.0
47 cargo-sort MIT/Apache-2.0 v2.1.3
48 cargo-supply-chain Apache-2.0 OR MIT OR Zlib v0.3.4
49 cargo-sweep MIT v0.8.0
50 cargo-temp MIT OR Apache-2.0 v0.4.1
51 cargo-udeps MIT OR Apache-2.0 v0.1.61
52 cargo-watch CC0-1.0 v8.5.3
53 cargo-wipe MIT v0.4.0
54 cargo-wizard MIT v0.2.3
55 cargo-zigbuild MIT v0.22.3
56 cbindgen MPL-2.0 v0.27.0
57 choose GPL-3.0-or-later v1.3.7
58 cobalt MIT v0.20.4
59 comrak BSD-2-Clause v0.52.0
60 cosmic-comp GPL-3.0-only HEAD(aprox)
61 cosmic-edit GPL-3.0-only HEAD(aprox)
62 cosmic-files GPL-3.0-only HEAD(aprox)
63 cosmic-osd GPL-3.0-or-later HEAD(aprox)
64 cosmic-session GPL-3.0-only HEAD(aprox)
65 cosmic-settings-daemon GPL-3.0-or-later HEAD(aprox)
66 cosmic-term GPL-3.0-only HEAD(aprox)
67 cpc MIT v3.0.0
68 csview MIT OR Apache-2.0 v1.3.4
69 csvlens MIT v0.13.0
70 dalfox MIT v3.1.2
71 ddh LGPL-3.0 0.13.0
72 delta MIT 0.19.2
73 difftastic MIT 0.69.0
74 diffutils MIT OR Apache-2.0 v0.5.0
75 diskus MIT/Apache-2.0 v0.9.0
76 dotter Unlicense v0.13.4
77 dua MIT v2.34.0
78 dufs MIT OR Apache-2.0 v0.46.0
79 dust Apache-2.0 v1.2.4
80 erdtree MIT v3.1.2
81 eza EUPL-1.2 v0.23.4
82 fastmod Apache-2.0 v0.4.4
83 fblog WTFPL v4.17.0
84 fd MIT OR Apache-2.0 v10.4.2
85 feroxbuster MIT v2.13.1
86 findutils MIT 0.9.1
87 findutils-xargs MIT 0.9.1
88 fnm GPL-3.0 v1.39.0
89 fselect MIT OR Apache-2.0 0.10.1
90 genact MIT v1.5.1
91 git-absorb BSD-3-Clause 0.9.0
92 git-graph MIT v0.7.0
93 git-igitt MIT v0.1.21
94 gitoxide MIT OR Apache-2.0 v0.54.0
95 gitui MIT v0.28.1
96 gitu MIT v0.42.0
97 gptman MIT OR Apache-2.0 v1.1.0
98 grcov MPL-2.0 v0.9.1
99 grex Apache-2.0 v1.4.6
100 heh MIT v0.6.3
101 hexyl MIT/Apache-2.0 v0.17.0
102 hgrep MIT v0.3.9
103 htmlq MIT v0.4.0
104 hwatch MIT 0.4.2
105 hyperfine MIT OR Apache-2.0 v1.20.0
106 igrep MIT v1.3.0
107 jnv MIT v0.7.1
108 joshuto LGPL-3.0 v0.9.9
109 just CC0-1.0 1.51.0
110 kbs2 MIT v0.7.3
111 kmon GPL-3.0 v1.7.1
112 kubie Zlib v0.26.1
113 lsd Apache-2.0 v1.2.0
114 macchina MIT v6.4.0
115 maturin MIT OR Apache-2.0 v1.12.6
116 mcfly MIT v0.9.3
117 mdbook-mermaid MPL-2.0 v0.17.0
118 mdbook-toc MPL-2.0 0.15.4
119 miniserve MIT v0.35.0
120 mise MIT v2026.7.0
121 monolith CC0-1.0 v2.10.1
122 natls MIT v2.1.14
123 navi Apache-2.0 v2.24.0
124 netscanner MIT v0.6.41
125 nomino MIT OR Apache-2.0 v1.6.4
126 nu MIT 0.104.1
127 oha MIT v1.14.0
128 otree MIT v0.6.5
129 ouch MIT 0.8.0
130 ox GPL-2.0 0.7.7
131 parallel-disk-usage Apache-2.0 0.21.1
132 pastel MIT/Apache-2.0 v0.12.0
133 pls GPL-3.0-or-later v0.0.1-beta.10
134 pop-launcher MPL-2.0 1.2.7
135 presenterm BSD-2-Clause v0.16.1
136 procs MIT v0.14.11
137 rep-grep MIT 0.0.8
138 repgrep Unlicense OR MIT OR Apache-2.0 0.16.1
139 rip2 GPL-3.0+ v0.9.6
140 ripgrep-all AGPL-3.0-or-later v0.10.10
141 ripgrep Unlicense OR MIT 14.1.1
142 ripsecrets MIT v0.1.11
143 rnr MIT v0.5.1
144 ruplacer BSD-3-Clause v0.10.0
145 russ AGPL-3.0-or-later HEAD(aprox)
146 rustcat GPL-3.0 v3.0.0
147 rustic Apache-2.0 OR MIT v0.11.3
148 rustscan GPL-3.0-only 2.4.1
149 rust-script MIT/Apache-2.0 0.36.0
150 sccache Apache-2.0 v0.15.0
151 sendme Apache-2.0 OR MIT v0.33.0
152 serie MIT v0.8.0
153 shellharden MPL-2.0 v4.3.1
154 simple-http-server MIT v0.8.0
155 skim MIT v4.7.0
156 sshs MIT 4.7.2
157 ssh-vault BSD-3-Clause 1.2.10
158 starship ISC v1.25.1
159 stylua MPL-2.0 v2.5.2
160 systemctl-tui MIT v0.5.2
161 taskwarrior-tui MIT v0.27.0
162 tealdeer MIT OR Apache-2.0 v1.8.1
163 television MIT 0.15.9
164 tenere GPL-3.0-or-later v0.11.3
165 tere EUPL-1.2 v1.6.0
166 the-way MIT v0.20.3
167 tokei MIT OR Apache-2.0 v14.0.0
168 tomlq MIT 0.2.2
169 topgrade GPL-3.0-or-later v17.6.1
170 trunk MIT/Apache-2.0 v0.21.14
171 ttyper MIT v1.6.0
172 tuc GPL-3.0-or-later v1.3.0
173 tuckr GPL-3.0-or-later 0.13.1
174 viddy MIT v1.3.1
175 viu MIT v1.6.1
176 vivid MIT/Apache-2.0 v0.11.1
177 wasm-pack MIT OR Apache-2.0 v0.15.0
178 xan Unlicense OR MIT 0.59.0
179 xdg-desktop-portal-cosmic GPL-3.0-or-later HEAD(aprox)
180 xh MIT v0.25.3
181 xsv Unlicense/MIT 0.13.0
182 xwin Apache-2.0 OR MIT 0.7.0
183 zenith MIT 0.15.0
184 zola EUPL-1.2 v0.22.1
185 zoxide MIT v0.9.9
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "aichat"
version = "0.30.0"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/sigoden/aichat"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "bat"
version = "0.26.1"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/sharkdp/bat"
-1
View File
@@ -6,7 +6,6 @@
# - deps.build=["zlib"]: git2/openssl-sys enlazan -lz.
name = "cargo-audit"
version = "0.22.1"
license = "{"message":"Not Found","documentation_url":"https://docs.github.com/rest/licenses/licenses#get-the-license-for-a-repository","status":"404"}"
[source]
tarball = "https://github.com/RustSec/cargo-audit/archive/cargo-audit/v0.22.1.tar.gz"
-1
View File
@@ -4,7 +4,6 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "cargo-binstall"
version = "1.20.0"
license = "{"message":"Not Found","documentation_url":"https://docs.github.com/rest/licenses/licenses#get-the-license-for-a-repository","status":"404"}"
[source]
repo = "https://github.com/cargo-bins/cargo-binstall"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "cargo-bundle-licenses"
version = "4.2.0"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/sstadick/cargo-bundle-licenses"
+1
View File
@@ -4,6 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "cargo-cache"
version = "0.8.3"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/matthiaskrgr/cargo-cache"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "cargo-careful"
version = "0.4.10"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/RalfJung/cargo-careful"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "cargo-criterion"
version = "1.1.0"
license = "Apache-2.0"
license = "Apache-2.0 OR MIT"
[source]
repo = "https://github.com/bheisler/cargo-criterion"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "cargo-deny"
version = "0.19.9"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/EmbarkStudios/cargo-deny"
+1 -1
View File
@@ -8,7 +8,7 @@
# `cargo rustc --` exige un único target, itero los 4 bins. El install lo auto-genera el lab.
name = "cargo-edit"
version = "0.13.11"
license = "MIT"
license = "Apache-2.0 OR MIT"
[source]
repo = "https://github.com/killercup/cargo-edit"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "cargo-expand"
version = "1.0.122"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/dtolnay/cargo-expand"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "cargo-flamegraph"
version = "0.6.13"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/flamegraph-rs/flamegraph"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "cargo-fuzz"
version = "0.13.2"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/rust-fuzz/cargo-fuzz"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "cargo-generate"
version = "0.23.9"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/cargo-generate/cargo-generate"
+1 -1
View File
@@ -4,7 +4,7 @@
# El `cargo auditable` del abuild de Alpine no existe en el lab ⇒ se elimina.
name = "cargo-hack"
version = "0.6.45"
license = "Apache-2.0"
license = "Apache-2.0 OR MIT"
[source]
tarball = "https://github.com/taiki-e/cargo-hack/archive/refs/tags/v0.6.45.tar.gz"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "cargo-llvm-cov"
version = "0.8.5"
license = "Apache-2.0"
license = "Apache-2.0 OR MIT"
[source]
repo = "https://github.com/taiki-e/cargo-llvm-cov"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "cargo-llvm-lines"
version = "0.4.46"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/dtolnay/cargo-llvm-lines"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "cargo-msrv"
version = "0.19.3"
license = "Apache-2.0"
license = "Apache-2.0 OR MIT"
[source]
repo = "https://github.com/foresterre/cargo-msrv"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "cargo-ndk"
version = "4.1.2"
license = "Apache-2.0"
license = "Apache-2.0 OR MIT"
[source]
repo = "https://github.com/bbqsrc/cargo-ndk"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "cargo-readme"
version = "3.3.2"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/webern/cargo-readme"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "cargo-semver-checks"
version = "0.48.0"
license = "Apache-2.0"
license = "Apache-2.0 OR MIT"
[source]
repo = "https://github.com/obi1kenobi/cargo-semver-checks"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "cargo-sort"
version = "2.1.3"
license = "{"message":"Not Found","documentation_url":"https://docs.github.com/rest/licenses/licenses#get-the-license-for-a-repository","status":"404"}"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/devinr528/cargo-sort"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "cargo-supply-chain"
version = "0.3.4"
license = "Apache-2.0"
license = "Apache-2.0 OR MIT OR Zlib"
[source]
repo = "https://github.com/rust-secure-code/cargo-supply-chain"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "cargo-temp"
version = "0.4.1"
license = "MIT"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/yozhgoor/cargo-temp"
+1
View File
@@ -4,6 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "cargo-udeps"
version = "0.1.61"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/est31/cargo-udeps"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "choose"
version = "1.3.7"
license = "GPL-3.0"
license = "GPL-3.0-or-later"
[source]
repo = "https://github.com/theryangeary/choose"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "cobalt"
version = "0.20.4"
license = "Apache-2.0"
license = "MIT"
[source]
repo = "https://github.com/cobalt-org/cobalt.rs"
+1
View File
@@ -4,6 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "comrak"
version = "0.52.0"
license = "BSD-2-Clause"
[source]
repo = "https://github.com/kivikakk/comrak"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "cpc"
version = "3.0.0"
license = "AGPL-3.0"
license = "MIT"
[source]
repo = "https://github.com/probablykasper/cpc"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "csview"
version = "1.3.4"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/wfxr/csview"
+1
View File
@@ -4,6 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "ddh"
version = "0.13.0"
license = "LGPL-3.0"
[source]
repo = "https://github.com/darakian/ddh"
+1 -1
View File
@@ -10,7 +10,7 @@
name = "diffutils"
version = "0.5.0"
license = "GPL-3.0-or-later"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/uutils/diffutils"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "diskus"
version = "0.9.0"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/sharkdp/diskus"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "dufs"
version = "0.46.0"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/sigoden/dufs"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "fd"
version = "10.4.2"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/sharkdp/fd"
+1 -1
View File
@@ -16,7 +16,7 @@
name = "findutils"
version = "0.9.1"
license = "GPL-3.0-or-later"
license = "MIT"
[source]
repo = "https://github.com/uutils/findutils"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "fselect"
version = "0.10.1"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/jhspetersson/fselect"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "gitoxide"
version = "0.54.0"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/GitoxideLabs/gitoxide"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "gptman"
version = "1.1.0"
license = "MIT"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/rust-disk-partition-management/gptman"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "hexyl"
version = "0.17.0"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/sharkdp/hexyl"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "hyperfine"
version = "1.20.0"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/sharkdp/hyperfine"
+1 -1
View File
@@ -29,7 +29,7 @@
# de EGL/wayland/xkbcommon; un estático acá no es una postura, es una mentira.
name = "cosmic-comp"
version = "1.5.0"
license = "GPL-3.0"
license = "GPL-3.0-only"
[source]
tarball = "https://github.com/pop-os/cosmic-comp/archive/epoch-1.5.0/cosmic-comp-epoch-1.5.0.tar.gz"
+1 -1
View File
@@ -29,7 +29,7 @@
# los cuarenta minutos.
name = "cosmic-edit"
version = "1.5.0"
license = "GPL-3.0"
license = "GPL-3.0-only"
[source]
tarball = "https://github.com/pop-os/cosmic-edit/archive/epoch-1.5.0/cosmic-edit-epoch-1.5.0.tar.gz"
+1 -1
View File
@@ -26,7 +26,7 @@
# (`bzip2-sys` no aparece) antes de agregar una dep que no hacía falta.
name = "cosmic-files"
version = "1.5.0"
license = "GPL-3.0"
license = "GPL-3.0-only"
[source]
tarball = "https://github.com/pop-os/cosmic-files/archive/epoch-1.5.0/cosmic-files-epoch-1.5.0.tar.gz"
+1 -1
View File
@@ -13,7 +13,7 @@
# `libxkbcommon` + `pkgconf` por el gotcha 7 del runbook: winit/sctk ENLAZAN xkbcommon.
name = "cosmic-osd"
version = "1.5.0"
license = "GPL-3.0"
license = "GPL-3.0-or-later"
[source]
tarball = "https://github.com/pop-os/cosmic-osd/archive/epoch-1.5.0/cosmic-osd-epoch-1.5.0.tar.gz"
+1 -1
View File
@@ -23,7 +23,7 @@
# arriba y no lo implica: es el nombre del protocolo, no del programa que lo contesta.
name = "cosmic-session"
version = "1.5.0"
license = "GPL-3.0"
license = "GPL-3.0-only"
[source]
tarball = "https://github.com/pop-os/cosmic-session/archive/epoch-1.5.0/cosmic-session-epoch-1.5.0.tar.gz"
@@ -21,7 +21,7 @@
# `ddc-hi` (brillo por DDC/CI sobre i2c) es Rust puro: habla el ioctl directo, no libddcutil.
name = "cosmic-settings-daemon"
version = "1.5.0"
license = "GPL-3.0"
license = "GPL-3.0-or-later"
[source]
tarball = "https://github.com/pop-os/cosmic-settings-daemon/archive/epoch-1.5.0/cosmic-settings-daemon-epoch-1.5.0.tar.gz"
+1 -1
View File
@@ -16,7 +16,7 @@
# tocar las features por defecto es apartarse de la única combinación que upstream prueba.
name = "cosmic-term"
version = "1.5.0"
license = "GPL-3.0"
license = "GPL-3.0-only"
[source]
tarball = "https://github.com/pop-os/cosmic-term/archive/epoch-1.5.0/cosmic-term-epoch-1.5.0.tar.gz"
@@ -31,7 +31,7 @@
# recorte.
name = "xdg-desktop-portal-cosmic"
version = "1.5.0"
license = "GPL-3.0"
license = "GPL-3.0-or-later"
[source]
tarball = "https://github.com/pop-os/xdg-desktop-portal-cosmic/archive/epoch-1.5.0/xdg-desktop-portal-cosmic-epoch-1.5.0.tar.gz"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "maturin"
version = "1.12.6"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/PyO3/maturin"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "nomino"
version = "1.6.4"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/yaa110/nomino"
+1
View File
@@ -4,6 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "ouch"
version = "0.8.0"
license = "MIT"
[source]
repo = "https://github.com/ouch-org/ouch"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "pastel"
version = "0.12.0"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/sharkdp/pastel"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "pls"
version = "0.0.1-beta.10"
license = "GPL-3.0"
license = "GPL-3.0-or-later"
[source]
repo = "https://github.com/pls-rs/pls"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "repgrep"
version = "0.16.1"
license = "Apache-2.0"
license = "Unlicense OR MIT OR Apache-2.0"
[source]
repo = "https://github.com/acheronfail/repgrep"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "rip2"
version = "0.9.6"
license = "GPL-3.0"
license = "GPL-3.0+"
[source]
repo = "https://github.com/MilesCranmer/rip2"
+1
View File
@@ -4,6 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "ripgrep-all"
version = "0.10.10"
license = "AGPL-3.0-or-later"
[source]
repo = "https://github.com/phiresky/ripgrep-all"
+1 -1
View File
@@ -15,7 +15,7 @@
name = "ripgrep"
version = "14.1.1"
license = "Unlicense"
license = "Unlicense OR MIT"
[source]
repo = "https://github.com/BurntSushi/ripgrep"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "russ"
version = "0.5.0"
license = "AGPL-3.0"
license = "AGPL-3.0-or-later"
[source]
repo = "https://github.com/ckampfe/russ"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "rust-script"
version = "0.36.0"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/fornwall/rust-script"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "rustic"
version = "0.11.3"
license = "Apache-2.0"
license = "Apache-2.0 OR MIT"
[source]
repo = "https://github.com/rustic-rs/rustic"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "rustscan"
version = "2.4.1"
license = "GPL-3.0"
license = "GPL-3.0-only"
[source]
repo = "https://github.com/RustScan/RustScan"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "sendme"
version = "0.33.0"
license = "Apache-2.0"
license = "Apache-2.0 OR MIT"
[source]
repo = "https://github.com/n0-computer/sendme"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "tealdeer"
version = "1.8.1"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/tealdeer-rs/tealdeer"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "tenere"
version = "0.11.3"
license = "GPL-3.0"
license = "GPL-3.0-or-later"
[source]
repo = "https://github.com/pythops/tenere"
+1
View File
@@ -4,6 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "tokei"
version = "14.0.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/XAMPPRocky/tokei"
+1 -1
View File
@@ -4,7 +4,7 @@
# crt-static + linker zig-cc ⇒ binario ESTÁTICO). Pure-Rust ⇒ zig-cc baseline.
name = "topgrade"
version = "17.6.1"
license = "GPL-3.0"
license = "GPL-3.0-or-later"
[source]
tarball = "https://github.com/topgrade-rs/topgrade/archive/refs/tags/v17.6.1.tar.gz"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "trunk"
version = "0.21.14"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/trunk-rs/trunk"
+1 -1
View File
@@ -3,7 +3,7 @@
# sha256 del tarball (el wrapper lo calcula), y adaptar build/install del shell de abuild.
name = "tuc"
version = "1.3.0"
license = "GPL-3.0"
license = "GPL-3.0-or-later"
[source]
tarball = "https://github.com/riquito/tuc/archive/v1.3.0/tuc-1.3.0.tar.gz"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "tuckr"
version = "0.13.1"
license = "GPL-3.0"
license = "GPL-3.0-or-later"
[source]
repo = "https://github.com/RaphGL/Tuckr"
-1
View File
@@ -3,7 +3,6 @@
# sha256 del tarball (el wrapper lo calcula), y adaptar build/install del shell de abuild.
name = "usbutils"
version = "019"
license = "{"message":"Not Found","documentation_url":"https://docs.github.com/rest/licenses/licenses#get-the-license-for-a-repository","status":"404"}"
[source]
tarball = "https://github.com/gregkh/usbutils/archive/refs/tags/v019.tar.gz"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "vivid"
version = "0.11.1"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/sharkdp/vivid"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "wasm-pack"
version = "0.15.0"
license = "Apache-2.0"
license = "MIT OR Apache-2.0"
[source]
repo = "https://github.com/wasm-bindgen/wasm-pack"
-1
View File
@@ -4,7 +4,6 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "waybackurls"
version = "0.1.0"
license = "{"message":"Not Found","documentation_url":"https://docs.github.com/rest/licenses/licenses#get-the-license-for-a-repository","status":"404"}"
[source]
repo = "https://github.com/tomnomnom/waybackurls"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "xan"
version = "0.59.0"
license = "Unlicense"
license = "Unlicense OR MIT"
[source]
repo = "https://github.com/medialab/xan"
+1 -1
View File
@@ -7,7 +7,7 @@
name = "xsv"
version = "0.13.0"
license = "Unlicense"
license = "Unlicense OR MIT"
[source]
tarball = "https://github.com/BurntSushi/xsv/archive/0.13.0/xsv-0.13.0.tar.gz"
+1 -1
View File
@@ -4,7 +4,7 @@
# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
name = "xwin"
version = "0.7.0"
license = "Apache-2.0"
license = "Apache-2.0 OR MIT"
[source]
repo = "https://github.com/Jake-Shadle/xwin"
+81
View File
@@ -0,0 +1,81 @@
#!/usr/bin/env bash
# licencias-cargo.sh — lee la licencia que el AUTOR declara en su `Cargo.toml`, al tag exacto que la
# receta pinea. Es la fuente más autoritativa de las tres que usamos, y corrige a las otras dos.
#
# ── LA JERARQUÍA DE EVIDENCIA, DE PEOR A MEJOR ──────────────────────────────────────────────────
# 1. El nombre de la receta ......... NO es evidencia. Prohibido (ver docs/licencias-conocidas.tsv).
# 2. La familia / URL de fuente ..... buena para agrupar (X.Org=MIT, KDE Frameworks=LGPL doble).
# 3. La API de licencias de GitHub .. detecta el fichero LICENSE real, pero con DOS pérdidas:
# devuelve identificadores obsoletos y ambiguos (`GPL-3.0` sin decir -only/-or-later) y
# **colapsa las licencias dobles a una sola**.
# 4. El `Cargo.toml` del autor ...... ← ESTO. Una expresión SPDX escrita por quien tiene la potestad
# de licenciar, sin ambigüedad y sin colapsar. Corrige los dos defectos de (3) de una vez.
#
# Ejemplo medido: la API dejó `fd` como `Apache-2.0`; su Cargo.toml dice `MIT OR Apache-2.0`. No era
# falso —cumplir Apache-2.0 basta— pero perdía una opción que el autor concedió. Con esto se recupera.
#
# ── SE PIDE AL TAG QUE LA RECETA PINEA, NO A HEAD ───────────────────────────────────────────────
# Ésa era la limitación registrada de la detección por API (mira la rama por defecto, no la versión
# que empaquetamos). Acá se prueba `?ref=v<version>` y `?ref=<version>` antes de caer a HEAD, y se
# ANOTA con qué ref se resolvió cada una, para que la tercera columna diga si el dato es exacto o
# aproximado. Un dato con su procedencia se puede auditar; uno sin ella hay que creerlo.
#
# ── LO QUE NO HACE ──────────────────────────────────────────────────────────────────────────────
# `license.workspace = true` (la licencia vive en el workspace padre) y `license-file` (licencia a
# medida, sin SPDX) se DESCARTAN en vez de adivinarse. Y no toca las recetas que no son Cargo: los
# módulos Go no tienen un campo equivalente en `go.mod`, así que ésos siguen dependiendo de (2) y (3).
#
# Uso: scripts/licencias-cargo.sh (escribe docs/licencias-cargo.tsv)
# FORZAR=1 TABLA=docs/licencias-cargo.tsv scripts/licencias.sh --sembrar
set -uo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT"
SALIDA="${SALIDA:-docs/licencias-cargo.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
# Todas las recetas con fuente en GitHub (tengan licencia o no: éste CORRIGE, no sólo rellena).
for f in recipes/*.toml recipes/incoming-*/*.toml; do
[ -f "$f" ] || continue
u=$(grep -m1 -E '^[[:space:]]*(tarball|repo)[[:space:]]*=' "$f" 2>/dev/null)
case "$u" in *github.com*) ;; *) continue ;; esac
n=$(basename "$f" .toml)
v=$(awk -F'"' '/^\[/{exit} /^[[:space:]]*version[[:space:]]*=/{print $2; exit}' "$f")
slug=$(printf '%s\n' "$u" | sed -E 's#.*github\.com[:/]+([^/"]+)/([^/"]+).*#\1/\2#; s/\.git$//')
case "$slug" in */*) printf '%s\t%s\t%s\n' "$n" "$slug" "${v:-}" ;; esac
done | sort -u > "$TMP/obj.tsv"
echo "==> recetas con fuente en GitHub: $(wc -l < "$TMP/obj.tsv")"
export TMP
xargs -P "$JOBS" -I{} sh -c '
n=$(printf "%s" "{}" | cut -f1); slug=$(printf "%s" "{}" | cut -f2); v=$(printf "%s" "{}" | cut -f3)
for ref in "v$v" "$v" ""; do
[ -z "$v" ] && [ -n "$ref" ] && continue
if [ -n "$ref" ]; then q="?ref=$ref"; etiq="$ref"; else q=""; etiq="HEAD(aprox)"; fi
c=$(gh api "repos/$slug/contents/Cargo.toml$q" --jq ".content" 2>/dev/null) || continue
[ -z "$c" ] && continue
lic=$(printf "%s" "$c" | base64 -d 2>/dev/null | awk -F\" "/^\[/{if(t)exit; if(\$0 ~ /^\[package\]/)t=1; next} t&&/^[[:space:]]*license[[:space:]]*=/{print \$2; exit}")
case "$lic" in
""|*workspace*|*true*) break ;;
*) printf "%s\t%s\t%s\n" "$n" "$lic" "$etiq" >> "$TMP/ok.tsv"; break ;;
esac
done
' < "$TMP/obj.tsv"
N=$(wc -l < "$TMP/ok.tsv" 2>/dev/null || echo 0)
EXACT=$(grep -vc 'HEAD(aprox)' "$TMP/ok.tsv" 2>/dev/null || echo 0)
{
echo "# licencias-cargo.tsv — GENERADO por scripts/licencias-cargo.sh. No editar a mano."
echo "#"
echo "# La licencia que el AUTOR declara en su Cargo.toml: expresión SPDX escrita por quien tiene"
echo "# la potestad de licenciar. Sin ambigüedad -only/-or-later y SIN colapsar las dobles ⇒ manda"
echo "# sobre la detección por API de GitHub, que pierde ambas cosas. Sembrar con FORZAR=1."
echo "#"
echo "# Tercera columna = el ref con el que se resolvió. Un tag concreto significa que el dato es"
echo "# de la VERSIÓN QUE EMPAQUETAMOS; 'HEAD(aprox)' que no se halló el tag y puede diferir."
echo "# Total $N · al tag exacto $EXACT · aproximadas $((N-EXACT))"
sort "$TMP/ok.tsv" 2>/dev/null
} > "$SALIDA"
echo "==> $N licencias de Cargo.toml ($EXACT al tag exacto) → $SALIDA"
+9
View File
@@ -53,8 +53,17 @@ export TMP
xargs -P "$JOBS" -I{} sh -c '
n=$(printf "%s" "{}" | cut -f1); slug=$(printf "%s" "{}" | cut -f2)
lic=$(gh api "repos/$slug/license" --jq ".license.spdx_id" 2>/dev/null)
# ⚠ VALIDAR LA FORMA, NO SÓLO LOS «NO SÉ» CONOCIDOS. Cuando el repo da 404 (renombrado, borrado,
# privado), `gh api` escribe el CUERPO DEL ERROR JSON en stdout y el filtro --jq falla ⇒ `lic`
# queda valiendo `{"message":"Not Found",...}`. Filtrando sólo ""/null/NOASSERTION/other, ese JSON
# pasaba como si fuera una licencia y se escribía en la receta: comillas incluidas, lo que además
# ROMPE el TOML y hace que el ArtifactHash deje de calcularse. Pasó de verdad en 5 recetas el
# 2026-08-07 y lo cazó la verificación de hashes, no la vista.
# ⇒ Regla: aceptar sólo lo que TIENE FORMA de expresión SPDX (letras, dígitos, . - + y los
# operadores OR/AND/WITH). Todo lo demás es un fallo disfrazado de dato.
case "$lic" in
""|null|NOASSERTION|other) printf "%s\t%s\n" "$n" "$slug" >> "$TMP/sin.tsv" ;;
*[!A-Za-z0-9.+\ -]*) printf "%s\t%s\n" "$n" "$slug" >> "$TMP/sin.tsv" ;;
*) printf "%s\t%s\t%s\n" "$n" "$lic" "$slug" >> "$TMP/con.tsv" ;;
esac
' < "$TMP/objetivos.tsv"
+41 -3
View File
@@ -63,7 +63,7 @@ case "$MODO" in
# ── sembrar: escribir las licencias de la tabla curada ──────────────────────────────────────────
--sembrar)
[ -s "$TABLA" ] || { echo "!! falta la tabla curada: $TABLA"; exit 1; }
puestas=0; ya=0; sin_receta=0
puestas=0; ya=0; sin_receta=0; corregidas=0
# TRES campos, no dos: `licencias-detectadas.tsv` añade una tercera columna con el `owner/repo`
# consultado (la procedencia, para poder auditar). Leyendo sólo dos variables, `lic` se tragaría
# también el slug y se escribiría `license = "MIT<TAB>owner/repo"` en la receta — basura silenciosa,
@@ -71,11 +71,32 @@ case "$MODO" in
while IFS=$'\t' read -r pkg lic _resto; do
case "$pkg" in ''|'#'*) continue ;; esac
[ -n "${lic:-}" ] || continue
# ÚLTIMA BARRERA antes de tocar una receta: la licencia tiene que TENER FORMA de expresión SPDX.
# Sin esto, cualquier fallo de una fuente aguas arriba se escribe como si fuera un dato — y el
# 2026-08-07 pasó: un cuerpo de error JSON de la API de GitHub acabó dentro de 5 recetas, con
# comillas, rompiendo el TOML y dejando de calcularse su ArtifactHash. Validar en el sitio que
# ESCRIBE es lo que corta la clase entera de fallo, no sólo el caso conocido.
case "$lic" in
*[!A-Za-z0-9.+\ -]*) echo " ?? $pkg: descarto licencia con forma inválida: $(printf '%.40s' "$lic")"; continue ;;
esac
hallada=0
for f in recipes/"$pkg".toml recipes/incoming-*/"$pkg".toml; do
[ -f "$f" ] || continue
hallada=1
if tiene_licencia "$f"; then ya=$((ya+1)); continue; fi
if tiene_licencia "$f"; then
# FORZAR=1: reemplazar lo ya declarado. Sólo tiene sentido con una fuente MÁS autoritativa
# que la que puso el valor actual — el caso real es `licencias-cargo.tsv`, la declaración
# del propio autor, que corrige los dos defectos de la detección por API (SPDX ambiguo y
# licencias dobles colapsadas). Con la tabla curada NO se usa: pisaría a mano lo verificado.
if [ "${FORZAR:-0}" = 1 ] && [ "$(licencia_de "$f")" != "$lic" ]; then
esc=$(printf '%s' "$lic" | sed 's/[&/\]/\\&/g')
sed -i "0,/^[[:space:]]*license[[:space:]]*=.*/s//license = \"$esc\"/" "$f"
corregidas=$((corregidas+1))
else
ya=$((ya+1))
fi
continue
fi
# Insertar DESPUÉS de la línea `version = ...`, que está en la raíz del TOML y antes de
# cualquier `[table]`. Es el único sitio seguro (ver la trampa de TOML en la cabecera).
if grep -qE '^version[[:space:]]*=' "$f"; then
@@ -90,7 +111,7 @@ case "$MODO" in
done
[ "$hallada" = 0 ] && sin_receta=$((sin_receta+1))
done < "$TABLA"
echo "==> sembradas $puestas · ya tenían $ya · en la tabla pero sin receta $sin_receta"
echo "==> sembradas $puestas · corregidas $corregidas · ya tenían $ya · sin receta $sin_receta"
echo "==> verificá que el hash NO se movió: ./scripts/store-gc.sh (debe dar los mismos vigentes)"
;;
@@ -139,6 +160,23 @@ case "$MODO" in
done
pct=0; [ "$tot" -gt 0 ] && pct=$((con*100/tot))
echo "==> licencias declaradas: $con de $tot recetas (${pct}%)"
# ── GUARDIÁN: licencias con FORMA INVÁLIDA ───────────────────────────────────────────────────
# El 2026-08-07 se escribió el cuerpo de un error JSON de la API de GitHub dentro de 5 recetas
# (`license = "{"message":"Not Found",...}"`). Las comillas rompen el TOML ⇒ esas recetas dejaron
# de parsear y de tener ArtifactHash, y así se COMMITEARON. No lo vio nadie leyendo: lo cazó la
# comparación de hashes. Por eso el informe lo comprueba SIEMPRE y sale distinto de cero: un dato
# con forma imposible es un fallo aguas arriba disfrazado de dato, y hay que verlo sin buscarlo.
malas=0
for f in $(recetas); do
l=$(licencia_de "$f")
[ -z "$l" ] && continue
case "$l" in *[!A-Za-z0-9.+\ -]*) echo "!! FORMA INVÁLIDA en $f: $(printf '%.50s' "$l")"; malas=$((malas+1));; esac
done
if [ "$malas" -gt 0 ]; then
echo "!! $malas recetas con licencia de forma imposible — probablemente TOML roto. Arreglar YA."
exit 1
fi
if [ "$con" -gt 0 ]; then
echo "==> reparto:"
sort /tmp/.lic-cuenta.$$ | uniq -c | sort -rn | head -25 | sed 's/^/ /'