lib.licenses: add evaluateNamedProperty for quickly checking subattributes

This commit is contained in:
Eman Resu
2026-04-28 13:07:49 -04:00
parent 9e48db8d39
commit 64e42fb8b1

View File

@@ -1,4 +1,25 @@
{ lib }:
let
handleComplexProperty =
evaluateSubProperty: AND: OR: license:
if license.licenseType == "compound" then
if license.operator == "OR" then
OR evaluateSubProperty license.licenses
else if license.operator == "AND" then
AND evaluateSubProperty license.licenses
else
throw "Unknown license operator"
else if license.licenseType == "exception" then
AND evaluateSubProperty [
license.license
license.exception
]
else if license.licenseType == "plus" then
evaluateSubProperty license.license
else
throw "Unknown license type or legacy license";
in
rec {
/**
Evaluate a license expression for a given predicate.
@@ -25,27 +46,41 @@ rec {
let
OR = if permissive then lib.any else lib.all;
AND = if permissive then lib.all else lib.any;
evaluateSubProperty = evaluateProperty predicate permissive;
evaluateComplexProperty = handleComplexProperty (evaluateProperty predicate permissive) AND OR;
in
license:
if license.licenseType == "simple" then
predicate license
else if license.licenseType == "compound" then
if license.operator == "OR" then
OR evaluateSubProperty license.licenses
else if license.operator == "AND" then
AND evaluateSubProperty license.licenses
else
throw "Unknown license operator"
else if license.licenseType == "exception" then
AND evaluateSubProperty [
license.license
license.exception
]
else if license.licenseType == "plus" then
evaluateSubProperty license.license
else
throw "Unknown license type or legacy license";
if license.licenseType == "simple" then predicate license else evaluateComplexProperty license;
/**
Evaluate a license expression for a given property name. The property must
be defined as a boolean attribute of all licenses passed.
# Example
```nix
evaluateNamedProperty "deprecated" true (with lib.licenses; AND [ ncsa (WITH asl20 llvm-exception) ])
```
# Type
```
evaluateProperty :: String -> Bool -> AttrSet -> Bool
```
# Arguments
- [name] name of the attribute to check
- [permissive] whether to apply checks permissive or reciprocal
- [license] license expression to check
*/
evaluateNamedProperty =
name: permissive:
let
OR = if permissive then lib.any else lib.all;
AND = if permissive then lib.all else lib.any;
evaluateComplexProperty = handleComplexProperty (evaluateNamedProperty name permissive) AND OR;
in
license:
if license.licenseType == "simple" then license.${name} else evaluateComplexProperty license;
/**
Check whether a license expression is free.
@@ -67,7 +102,7 @@ rec {
- [license] License expression to check if free
*/
isFree = evaluateProperty (x: x.free) true;
isFree = evaluateNamedProperty "free" true;
/**
Check whether a license expression is redistributable.
@@ -89,7 +124,7 @@ rec {
- [license] License expression to check if redistributable
*/
isRedistributable = evaluateProperty (x: x.redistributable) true;
isRedistributable = evaluateNamedProperty "redistributable" true;
/**
Check whether any of the given licenses is required in the license expression.