diff --git a/pkgs/build-support/dotnet/make-nuget-source/default.nix b/pkgs/build-support/dotnet/make-nuget-source/default.nix index ea1c5328082..6bda65f18d5 100644 --- a/pkgs/build-support/dotnet/make-nuget-source/default.nix +++ b/pkgs/build-support/dotnet/make-nuget-source/default.nix @@ -1,4 +1,4 @@ -{ dotnetPackages, lib, xml2, stdenvNoCC }: +{ lib, python3, stdenvNoCC }: { name , description ? "" @@ -10,21 +10,21 @@ let inherit name; meta.description = description; - nativeBuildInputs = [ dotnetPackages.Nuget xml2 ]; + nativeBuildInputs = [ python3 ]; buildCommand = '' - export HOME=$(mktemp -d) mkdir -p $out/{lib,share} - ${lib.concatMapStringsSep "\n" (dep: '' - nuget init "${dep}" "$out/lib" - '') deps} + ( + shopt -s nullglob + for nupkg in ${lib.concatMapStringsSep " " (dep: "\"${dep}\"/*.nupkg") deps}; do + cp --no-clobber "$nupkg" $out/lib + done + ) # Generates a list of all licenses' spdx ids, if available. # Note that this currently ignores any license provided in plain text (e.g. "LICENSE.txt") - find "$out/lib" -name "*.nuspec" -exec sh -c \ - "NUSPEC=\$(xml2 < {}) && echo "\$NUSPEC" | grep license/@type=expression | tr -s \ '\n' | grep "license=" | cut -d'=' -f2" \ - \; | sort -u > $out/share/licenses + python ${./extract-licenses-from-nupkgs.py} $out/lib > $out/share/licenses ''; } // { # We need data from `$out` for `meta`, so we have to use overrides as to not hit infinite recursion. meta.licence = let diff --git a/pkgs/build-support/dotnet/make-nuget-source/extract-licenses-from-nupkgs.py b/pkgs/build-support/dotnet/make-nuget-source/extract-licenses-from-nupkgs.py new file mode 100644 index 00000000000..22564b0bb2b --- /dev/null +++ b/pkgs/build-support/dotnet/make-nuget-source/extract-licenses-from-nupkgs.py @@ -0,0 +1,30 @@ +#!/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 +'...' 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)))