mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-06-05 21:03:40 +00:00
lib.licenses: add compound licenses
This commit is contained in:
@@ -268,7 +268,7 @@ pkgs/development/python-modules/buildcatrust/ @ajs124 @lukegb @mweinelt
|
||||
/pkgs/applications/editors/jetbrains @leona-ya @theCapypara
|
||||
|
||||
# Licenses
|
||||
/lib/licenses.nix @alyssais @emilazy @jopejoe1
|
||||
/lib/licenses @alyssais @emilazy @jopejoe1
|
||||
|
||||
# Qt
|
||||
/pkgs/development/libraries/qt-5 @K900 @NickCao @SuperSandro2000 @ttuegel
|
||||
|
||||
@@ -73,7 +73,7 @@ let
|
||||
types = callLibs ./types.nix;
|
||||
|
||||
# constants
|
||||
licenses = callLibs ./licenses.nix;
|
||||
licenses = callLibs ./licenses;
|
||||
sourceTypes = callLibs ./source-types.nix;
|
||||
systems = callLibs ./systems;
|
||||
|
||||
|
||||
7
lib/licenses/default.nix
Normal file
7
lib/licenses/default.nix
Normal file
@@ -0,0 +1,7 @@
|
||||
{ lib }:
|
||||
let
|
||||
licenses = import ./licenses.nix { inherit lib; };
|
||||
operators = import ./operators.nix;
|
||||
helpers = import ./helpers.nix { inherit lib; };
|
||||
in
|
||||
licenses // operators // helpers
|
||||
152
lib/licenses/helpers.nix
Normal file
152
lib/licenses/helpers.nix
Normal file
@@ -0,0 +1,152 @@
|
||||
{ lib }:
|
||||
rec {
|
||||
/**
|
||||
Evaluate a license expression for a given predicate.
|
||||
|
||||
# Example
|
||||
|
||||
```nix
|
||||
evaluateProperty (x: x.free) true (with lib.licenses; AND [ ncsa (WITH asl20 llvm-exception) ])
|
||||
```
|
||||
# Type
|
||||
|
||||
```
|
||||
evaluateProperty :: Function -> Bool -> AttrSet -> Bool
|
||||
```
|
||||
|
||||
# Arguments
|
||||
|
||||
- [predicate] checks for each license included in the license expression
|
||||
- [permissive] whether to apply checks permissive or reciprocal
|
||||
- [license] license expression to check
|
||||
*/
|
||||
evaluateProperty =
|
||||
predicate: permissive: license:
|
||||
let
|
||||
OR = if permissive then lib.any else lib.all;
|
||||
AND = if permissive then lib.all else lib.any;
|
||||
in
|
||||
if license.licenseType == "simple" then
|
||||
predicate license
|
||||
else if license.licenseType == "compound" then
|
||||
if license.operator == "OR" then
|
||||
OR (x: evaluateProperty predicate permissive x) license.licenses
|
||||
else if license.operator == "AND" then
|
||||
AND (x: evaluateProperty predicate permissive x) license.licenses
|
||||
else
|
||||
throw "Unknown license operator"
|
||||
else if license.licenseType == "exception" then
|
||||
AND (x: evaluateProperty predicate permissive x) [
|
||||
license.license
|
||||
license.exception
|
||||
]
|
||||
else if license.licenseType == "plus" then
|
||||
evaluateProperty predicate permissive license.license
|
||||
else
|
||||
throw "Unknown license type or legacy license";
|
||||
|
||||
/**
|
||||
Check whether a license expression is free.
|
||||
|
||||
# Example
|
||||
|
||||
```nix
|
||||
isFree (with lib.licenses; (AND [ ncsa (WITH asl20 llvm-exception) ]))
|
||||
=> true
|
||||
```
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
isFree :: AttrSet -> Bool
|
||||
```
|
||||
|
||||
# Arguments
|
||||
|
||||
- [license] License expression to check if free
|
||||
*/
|
||||
isFree = evaluateProperty (x: x.free) true;
|
||||
|
||||
/**
|
||||
Check whether a license expression is redistributable.
|
||||
|
||||
# Example
|
||||
|
||||
```nix
|
||||
isRedistributable (with lib.licenses; (AND [ ncsa (WITH asl20 llvm-exception) ]))
|
||||
=> true
|
||||
```
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
isRedistributable :: AttrSet -> Bool
|
||||
```
|
||||
|
||||
# Arguments
|
||||
|
||||
- [license] License expression to check if redistributable
|
||||
*/
|
||||
isRedistributable = evaluateProperty (x: x.redistributable) true;
|
||||
|
||||
/**
|
||||
Check whether any of the given licenses is required in the license expression.
|
||||
|
||||
# Example
|
||||
|
||||
```nix
|
||||
containsLicenses [ lib.licenses.asl20 ] (with lib.licenses; (AND [ ncsa (WITH asl20 llvm-exception) ]))
|
||||
=> true
|
||||
```
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
containsLicenses :: List -> AttrSet -> Bool
|
||||
```
|
||||
|
||||
# Arguments
|
||||
|
||||
- [licenses] List of licenses to look
|
||||
- [license] License expression to check
|
||||
*/
|
||||
containsLicenses = licenses: evaluateProperty (x: lib.lists.elem x licenses) false;
|
||||
|
||||
/**
|
||||
Convert a license expression to an SPDX license expression string.
|
||||
|
||||
# Example
|
||||
|
||||
```nix
|
||||
toSPDX (with lib.licenses; AND [ ncsa (WITH asl20 llvm-exception) ])
|
||||
=> "NCSA AND (Apache-2.0 WITH LLVM-exception)"
|
||||
```
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
toSPDX :: AttrSet -> String
|
||||
```
|
||||
|
||||
# Arguments
|
||||
|
||||
- [license] License expression which to convert to spdx expression
|
||||
*/
|
||||
toSPDX =
|
||||
license:
|
||||
let
|
||||
mkBracket =
|
||||
x:
|
||||
if x.licenseType == "compound" || x.licenseType == "exception" then "(${toSPDX x})" else toSPDX x;
|
||||
in
|
||||
if license.licenseType == "simple" then
|
||||
license.spdxId or "LicenseRef-nixos-${license.shortName}"
|
||||
else if license.licenseType == "compound" then
|
||||
lib.concatMapStringsSep " ${license.operator} " (x: mkBracket x) license.licenses
|
||||
else if license.licenseType == "exception" then
|
||||
"${mkBracket license.license} ${license.operator} ${mkBracket license.exception}"
|
||||
else if license.licenseType == "plus" then
|
||||
"${mkBracket license.license}${license.operator}"
|
||||
else
|
||||
throw "Unknown license type";
|
||||
}
|
||||
@@ -21,6 +21,7 @@ let
|
||||
deprecated
|
||||
redistributable
|
||||
;
|
||||
licenseType = "simple";
|
||||
}
|
||||
// optionalAttrs (attrs ? spdxId) {
|
||||
inherit spdxId;
|
||||
110
lib/licenses/operators.nix
Normal file
110
lib/licenses/operators.nix
Normal file
@@ -0,0 +1,110 @@
|
||||
{
|
||||
/**
|
||||
This should be used when there is a choice of which license expression to use.
|
||||
This is a disjunctive binary "OR" operator.
|
||||
|
||||
# Example
|
||||
|
||||
```nix
|
||||
OR [ lib.licenses.mit lib.licenses.asl20 ]
|
||||
=> { licenseType = "compound"; operator = "OR"; licenses = [ lib.licenses.mit lib.licenses.asl20 ] };
|
||||
```
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
OR :: List -> AttrSet
|
||||
```
|
||||
|
||||
# Arguments
|
||||
|
||||
- [licenses] Possible licenses to choose from
|
||||
*/
|
||||
OR = licenses: {
|
||||
licenseType = "compound";
|
||||
operator = "OR";
|
||||
inherit licenses;
|
||||
};
|
||||
|
||||
/**
|
||||
Create a compound licenses where the user needs to follow both licenses,
|
||||
eqivialent of spdx `and` modifier.
|
||||
|
||||
# Example
|
||||
|
||||
```nix
|
||||
AND [ lib.licenses.mit lib.licenses.asl20 ]
|
||||
=> { licenseType = "compound"; operator = "AND"; licenses = [ lib.licenses.mit lib.licenses.asl20 ] };
|
||||
```
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
AND :: List -> AttrSet
|
||||
```
|
||||
|
||||
# Arguments
|
||||
|
||||
- [licenses] Licenses required to use
|
||||
*/
|
||||
AND = licenses: {
|
||||
licenseType = "compound";
|
||||
operator = "AND";
|
||||
inherit licenses;
|
||||
};
|
||||
|
||||
/**
|
||||
Create a licenses exception where a license has a license exception,
|
||||
eqivialent of spdx `with` modifier.
|
||||
|
||||
# Example
|
||||
|
||||
```nix
|
||||
WITH lib.licenses.lgpl21Only lib.licenses.ocamlLgplLinkingException
|
||||
=> { licenseType = "exception"; operator = "WITH"; license = lib.licenses.lgpl21Only; exception = lib.licenses.ocamlLgplLinkingException; };
|
||||
```
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
WITH :: AttrSet -> AttrSet -> AttrSet
|
||||
```
|
||||
|
||||
# Arguments
|
||||
|
||||
- [license] License to which the exception applies
|
||||
- [exception] Exception to apply
|
||||
*/
|
||||
WITH = license: exception: {
|
||||
licenseType = "compound";
|
||||
operator = "WITH";
|
||||
inherit license exception;
|
||||
};
|
||||
|
||||
/**
|
||||
Create a licenses which can be upgraded to any later version of itself,
|
||||
eqivialent of spdx `+` modifier
|
||||
|
||||
# Example
|
||||
|
||||
```nix
|
||||
PLUS lib.licenses.lgpl21Only
|
||||
=> { licenseType = "plus"; operator = "+"; license = lib.licenses.lgpl21Only; };
|
||||
```
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
PLUS :: AttrSet -> AttrSet
|
||||
```
|
||||
|
||||
# Arguments
|
||||
|
||||
- [license] License to wich apply an exception
|
||||
*/
|
||||
PLUS = license: {
|
||||
licenseType = "plus";
|
||||
operator = "+";
|
||||
inherit license;
|
||||
};
|
||||
}
|
||||
@@ -90,6 +90,8 @@ let
|
||||
&& (
|
||||
if isList attrs.meta.license then
|
||||
any (l: elem l list) attrs.meta.license
|
||||
else if attrs.meta.license ? "type" then
|
||||
lib.licenses.containsLicenses list attrs.meta.license
|
||||
else
|
||||
elem attrs.meta.license list
|
||||
);
|
||||
@@ -103,7 +105,9 @@ let
|
||||
|
||||
isUnfree =
|
||||
licenses:
|
||||
if isAttrs licenses then
|
||||
if isAttrs licenses && licenses ? "type" then
|
||||
!(lib.licenses.isFree licenses)
|
||||
else if isAttrs licenses then
|
||||
!(licenses.free or true)
|
||||
# TODO: Returning false in the case of a string is a bug that should be fixed.
|
||||
# In a previous implementation of this function the function body
|
||||
|
||||
Reference in New Issue
Block a user