diff --git a/lib/default.nix b/lib/default.nix index ecf4fbb75339..d637ca203f0e 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -123,7 +123,7 @@ let inherit (self.derivations) lazyDerivation optionalDrvAttr; inherit (self.meta) addMetaAttrs dontDistribute setName updateName appendToName mapDerivationAttrset setPrio lowPrio lowPrioSet hiPrio - hiPrioSet getLicenseFromSpdxId getExe getExe'; + hiPrioSet getLicenseFromSpdxId getLicenseFromSpdxIdOr getExe getExe'; inherit (self.filesystem) pathType pathIsDirectory pathIsRegularFile packagesFromDirectoryRecursive; inherit (self.sources) cleanSourceFilter diff --git a/lib/meta.nix b/lib/meta.nix index 8fa93d40d595..65d7bf99191a 100644 --- a/lib/meta.nix +++ b/lib/meta.nix @@ -287,10 +287,10 @@ rec { all (elem: !platformMatch platform elem) (pkg.meta.badPlatforms or []); /** - Get the corresponding attribute in lib.licenses - from the SPDX ID. - For SPDX IDs, see - https://spdx.org/licenses + Get the corresponding attribute in lib.licenses from the SPDX ID + or warn and fallback to `{ shortName = ; }`. + + For SPDX IDs, see https://spdx.org/licenses # Type @@ -315,15 +315,57 @@ rec { ::: */ getLicenseFromSpdxId = - let - spdxLicenses = lib.mapAttrs (id: ls: assert lib.length ls == 1; builtins.head ls) - (lib.groupBy (l: lib.toLower l.spdxId) (lib.filter (l: l ? spdxId) (lib.attrValues lib.licenses))); - in licstr: - spdxLicenses.${ lib.toLower licstr } or ( + licstr: + getLicenseFromSpdxIdOr licstr ( lib.warn "getLicenseFromSpdxId: No license matches the given SPDX ID: ${licstr}" { shortName = licstr; } ); + /** + Get the corresponding attribute in lib.licenses from the SPDX ID + or fallback to the given default value. + + For SPDX IDs, see https://spdx.org/licenses + + # Inputs + + `licstr` + : 1\. SPDX ID string to find a matching license + + `default` + : 2\. Fallback value when a match is not found + + # Type + + ``` + getLicenseFromSpdxIdOr :: str -> Any -> Any + ``` + + # Examples + :::{.example} + ## `lib.meta.getLicenseFromSpdxIdOr` usage example + + ```nix + lib.getLicenseFromSpdxIdOr "MIT" null == lib.licenses.mit + => true + lib.getLicenseFromSpdxId "mIt" null == lib.licenses.mit + => true + lib.getLicenseFromSpdxIdOr "MY LICENSE" lib.licenses.free == lib.licenses.free + => true + lib.getLicenseFromSpdxIdOr "MY LICENSE" null + => null + lib.getLicenseFromSpdxIdOr "MY LICENSE" (builtins.throw "No SPDX ID matches MY LICENSE") + => error: No SPDX ID matches MY LICENSE + ``` + ::: + */ + getLicenseFromSpdxIdOr = + let + spdxLicenses = lib.mapAttrs (id: ls: assert lib.length ls == 1; builtins.head ls) + (lib.groupBy (l: lib.toLower l.spdxId) (lib.filter (l: l ? spdxId) (lib.attrValues lib.licenses))); + in licstr: default: + spdxLicenses.${ lib.toLower licstr } or default; + /** Get the path to the main program of a package based on meta.mainProgram diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index dd12923e636e..4294d29b47ef 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -58,6 +58,7 @@ let genList getExe getExe' + getLicenseFromSpdxIdOr groupBy groupBy' hasAttrByPath @@ -2323,6 +2324,25 @@ runTests { getExe' { type = "derivation"; } "dir/executable" ); + testGetLicenseFromSpdxIdOrExamples = { + expr = [ + (getLicenseFromSpdxIdOr "MIT" null) + (getLicenseFromSpdxIdOr "mIt" null) + (getLicenseFromSpdxIdOr "MY LICENSE" lib.licenses.free) + (getLicenseFromSpdxIdOr "MY LICENSE" null) + ]; + expected = [ + lib.licenses.mit + lib.licenses.mit + lib.licenses.free + null + ]; + }; + + testGetLicenseFromSpdxIdOrThrow = testingThrow ( + getLicenseFromSpdxIdOr "MY LICENSE" (throw "No SPDX ID matches MY LICENSE") + ); + testPlatformMatch = { expr = meta.platformMatch { system = "x86_64-linux"; } "x86_64-linux"; expected = true;