#!/usr/bin/env python3 """Lista os crates Rust que entram no .wasm (dependencias normais, a partir do pacote raiz) e junta o texto das licencas de cada um. Uso: cargo metadata ... | rust-licenses.py [] Falha se algum crate nao tiver arquivo de licenca ou se a expressao de licenca nao permitir uso comercial livre.""" import json, os, sys, glob root_name, out = sys.argv[1], sys.argv[2] extra = sys.argv[3] if len(sys.argv) > 3 else None m = json.load(sys.stdin) pk = {p["id"]: p for p in m["packages"]} nodes = {n["id"]: n for n in m["resolve"]["nodes"]} root = next(i for i, p in pk.items() if p["name"] == root_name and p["source"] is None) seen, stack = set(), [root] while stack: i = stack.pop() if i in seen: continue seen.add(i) for d in nodes[i]["deps"]: if any(k["kind"] is None for k in d["dep_kinds"]): stack.append(d["pkg"]) lines = [] bad = [] for i in sorted(seen, key=lambda i: (pk[i]["name"], pk[i]["version"])): p = pk[i] if p["source"] is None: continue # crates do proprio repositorio do jogo (MIT, LICENSE.txt do jogo) lic = p["license"] or "" d = os.path.dirname(p["manifest_path"]) files = sorted(f for f in glob.glob(os.path.join(d, "*")) if os.path.basename(f).upper().startswith(("LICENSE", "LICENCE", "COPYING", "UNLICENSE", "NOTICE")) and os.path.isfile(f)) if any(t in lic for t in ("GPL", "AGPL", "LGPL", "MPL", "CC-BY-NC")): bad.append((p["name"], lic)) lines.append("=" * 78) lines.append("%s %s (%s)" % (p["name"], p["version"], lic or "see files")) lines.append("=" * 78) if not files: if not lic: bad.append((p["name"], "sem licenca")) lines.append("(no license file in the published crate; license expression above)") for f in files: lines.append("--- %s" % os.path.basename(f)) lines.append(open(f, encoding="utf-8", errors="replace").read().rstrip()) lines.append("") if bad: sys.exit("licencas a conferir: %r" % bad) with open(out, "w", encoding="utf-8") as o: o.write("Rust crates compiled into the WebAssembly module (normal dependencies only), with the license texts\n" "published in each crate. %d crates.\n\n" % sum(1 for l in lines if l.startswith("=" * 78)) if False else "Rust crates compiled into the WebAssembly module (normal dependencies only), with the license texts\npublished in each crate.\n\n") if extra: o.write(open(extra, encoding="utf-8").read().rstrip() + "\n\n") o.write("\n".join(lines) + "\n") print("crates:", sum(1 for l in lines if l.startswith("=" * 78)) // 2)