nixpkgs/pkgs/build-support/dotnet/make-nuget-source/extract-licenses-from-nupkgs.py
Raphael Robatsch d347b0400c mkNugetSource: remove mono from build closure
A directory full of *.nupkg files is a valid nuget source. We do not need mono
and the Nuget command line tool to create this structure. This has two
advantages:

- Nuget is currently broken due to a kernel bug affecting mono (#229476).
  Replacing the mkNugetSource implementation allows affected users on 6.1+
  kernels compile .NET core packages again.
- It removes mono from the build closure of .NET core packages. .NET core
  builds should not depend on .NET framework tools like mono.

There is no equivalent of the `nuget init` command in .NET core. The closest
command is `dotnet nuget push`, which just copies the *.nupkg files around
anyway, just like this PR does with `cp`.

`nuget init` used to extract the *.nuspec files from the nupkgs, this new
implementation doesn't. .NET core doesn't care, but it makes the license
extraction more difficult. What was previously done with find/grep/xml2 is now
a python script (extract-licenses-from-nupkgs.py).
2023-05-05 18:38:06 +00:00

31 lines
1.0 KiB
Python

#!/usr/bin/env python3
"""
Opens each .nupkg file in a directory, and extracts the SPDX license identifiers
from them if they exist. The SPDX license identifier is stored in the
'<license type="expression">...</license>' tag in the .nuspec file.
All found license identifiers will be printed to stdout.
"""
from glob import glob
from pathlib import Path
import sys
import xml.etree.ElementTree as ET
import zipfile
all_licenses = set()
if len(sys.argv) < 2:
print(f"Usage: {sys.argv[0]} DIRECTORY")
sys.exit(1)
nupkg_dir = Path(sys.argv[1])
for nupkg_name in glob("*.nupkg", root_dir=nupkg_dir):
with zipfile.ZipFile(nupkg_dir / nupkg_name) as nupkg:
for nuspec_name in [name for name in nupkg.namelist() if name.endswith(".nuspec")]:
with nupkg.open(nuspec_name) as nuspec_stream:
nuspec = ET.parse(nuspec_stream)
licenses = nuspec.findall(".//{*}license[@type='expression']")
all_licenses.update([license.text for license in licenses])
print("\n".join(sorted(all_licenses)))