scripts/license_notices.py (1612B)
1 #!/usr/bin/env python3
2 """Collect the license files shipped with locked Cargo dependencies."""
3
4 import json
5 from pathlib import Path
6 import subprocess
7
8 ROOT = Path(__file__).resolve().parents[1]
9
10
11 def main():
12 metadata = json.loads(subprocess.check_output([
13 "cargo", "metadata", "--offline", "--locked", "--format-version", "1",
14 "--manifest-path", str(ROOT / "generator/Cargo.toml"),
15 ]))
16 notices = ["Third-party Cargo dependency notices\nGenerated from Cargo.lock and packaged license files.\n"]
17 for package in sorted(metadata["packages"], key=lambda item: (item["name"], item["version"])):
18 if not package.get("source"):
19 continue
20 root = Path(package["manifest_path"]).parent
21 files = {file for file in root.rglob("*") if file.is_file()
22 and file.name.upper().startswith(("LICENSE", "COPYING", "NOTICE"))}
23 if package.get("license_file"):
24 files.add(root / package["license_file"])
25 if not files:
26 raise RuntimeError(f"Missing packaged license for {package['name']}")
27 notices.append(f"\n{'=' * 72}\n{package['name']} {package['version']}\n"
28 f"Declared license: {package.get('license', '')}\nRepository: {package.get('repository', '')}\n")
29 for file in sorted(files):
30 notices.append(f"\n--- {file.relative_to(root)} ---\n{file.read_text()}\n")
31 output = ROOT / "third-party/cargo-LICENSES.txt"
32 output.write_text("".join(notices), encoding="utf-8")
33 print(f"Wrote dependency notices to {output}")
34
35
36 if __name__ == "__main__":
37 main()