diff options
author | Robert Scott <code@humanleg.org.uk> | 2022-02-20 19:23:12 +0000 |
---|---|---|
committer | Alexander Foremny <aforemny@posteo.de> | 2022-05-30 16:27:34 +0800 |
commit | da9162f667e5833b885edae3631299c0e7005d2b (patch) | |
tree | 6a435bfbd822ad8c133a5b797da1d05fe1d58a15 | |
parent | 93e6a4b6070a305c7608de120004b3a25f76f796 (diff) |
add mechanism for handling meta.sourceProvenance attributes
heavily based on patterns used by licenses infrastructure, so may appear overengineered for its initial level of use
-rw-r--r-- | lib/default.nix | 1 | ||||
-rw-r--r-- | lib/source-types.nix | 25 | ||||
-rw-r--r-- | pkgs/stdenv/generic/check-meta.nix | 46 |
3 files changed, 68 insertions, 4 deletions
diff --git a/lib/default.nix b/lib/default.nix index e919509e724a5..791eba8a9301f 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -36,6 +36,7 @@ let # constants licenses = callLibs ./licenses.nix; + sourceTypes = callLibs ./source-types.nix; systems = callLibs ./systems; # serialization diff --git a/lib/source-types.nix b/lib/source-types.nix new file mode 100644 index 0000000000000..8a4ab540b9da1 --- /dev/null +++ b/lib/source-types.nix @@ -0,0 +1,25 @@ +{ lib }: + +lib.mapAttrs (tname: tset: let + defaultSourceType = { + shortName = tname; + isSource = false; + }; + + mkSourceType = sourceTypeDeclaration: let + applyDefaults = sourceType: defaultSourceType // sourceType; + in lib.pipe sourceTypeDeclaration [ + applyDefaults + ]; +in mkSourceType tset) { + + fromSource = { + isSource = true; + }; + + binaryNativeCode = {}; + + binaryBytecode = {}; + + binaryFirmware = {}; +} diff --git a/pkgs/stdenv/generic/check-meta.nix b/pkgs/stdenv/generic/check-meta.nix index 1da098dabbee1..1be306fd39699 100644 --- a/pkgs/stdenv/generic/check-meta.nix +++ b/pkgs/stdenv/generic/check-meta.nix @@ -20,6 +20,9 @@ let allowUnfree = config.allowUnfree || builtins.getEnv "NIXPKGS_ALLOW_UNFREE" == "1"; + allowNonSource = config.allowNonSource or true + || builtins.getEnv "NIXPKGS_ALLOW_NONSOURCE" == "1"; + allowlist = config.allowlistedLicenses or config.whitelistedLicenses or []; blocklist = config.blocklistedLicenses or config.blacklistedLicenses or []; @@ -86,12 +89,41 @@ let allowInsecurePredicate attrs || builtins.getEnv "NIXPKGS_ALLOW_INSECURE" == "1"; - showLicense = license: toString (map (l: l.shortName or "unknown") (lib.lists.toList license)); + hasSourceProvenance = attrs: + attrs ? meta.sourceProvenance; + + isNonSource = sourceTypes: lib.lists.any (t: !t.isSource or true) sourceTypes; + + hasNonSourceProvenance = attrs: + hasSourceProvenance attrs && + isNonSource (lib.lists.toList attrs.meta.sourceProvenance); + + # Allow granular checks to allow only some non-source-built packages + # Example: + # {pkgs, ...}: + # { + # allowNonSource = false; + # allowNonSourcePredicate = (x: pkgs.lib.hasPrefix "pulumi" x.name); + # } + allowNonSourcePredicate = config.allowNonSourcePredicate or (x: false); + + # Check whether non-source packages are allowed and if not, whether the + # package has non-source provenance and is not explicitly allowed by the + # `allowNonSourcePredicate` function. + hasDeniedNonSourceProvenance = attrs: + hasNonSourceProvenance attrs && + !allowNonSource && + !allowNonSourcePredicate attrs; + + showLicenseOrSourceType = value: toString (map (v: v.shortName or "unknown") (lib.lists.toList value)); + showLicense = showLicenseOrSourceType; + showSourceType = showLicenseOrSourceType; pos_str = meta: meta.position or "«unknown-file»"; remediation = { - unfree = remediate_allowlist "Unfree" remediate_unfree_predicate; + unfree = remediate_allowlist "Unfree" (remediate_predicate "allowUnfreePredicate"); + non-source = remediate_allowlist "NonSource" (remediate_predicate "allowNonSourcePredicate"); broken = remediate_allowlist "Broken" (x: ""); unsupported = remediate_allowlist "UnsupportedSystem" (x: ""); blocklisted = x: ""; @@ -104,17 +136,19 @@ let Unfree = "NIXPKGS_ALLOW_UNFREE"; Broken = "NIXPKGS_ALLOW_BROKEN"; UnsupportedSystem = "NIXPKGS_ALLOW_UNSUPPORTED_SYSTEM"; + NonSource = "NIXPKGS_ALLOW_NONSOURCE"; }.${allow_attr}; remediation_phrase = allow_attr: { Unfree = "unfree packages"; Broken = "broken packages"; UnsupportedSystem = "packages that are unsupported for this system"; + NonSource = "packages not built from source"; }.${allow_attr}; - remediate_unfree_predicate = attrs: + remediate_predicate = predicateConfigAttr: attrs: '' Alternatively you can configure a predicate to allow specific packages: - { nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [ + { nixpkgs.config.${predicateConfigAttr} = pkg: builtins.elem (lib.getName pkg) [ "${lib.getName attrs}" ]; } @@ -226,6 +260,7 @@ let downloadPage = str; changelog = either (listOf str) str; license = either (listOf lib.types.attrs) (either lib.types.attrs str); + sourceProvenance = either (listOf lib.types.attrs) (either lib.types.attrs str); maintainers = listOf (attrsOf str); priority = int; platforms = listOf str; @@ -288,6 +323,7 @@ let checkValidity = attrs: { unfree = hasUnfreeLicense attrs; + nonSource = hasNonSourceProvenance attrs; broken = isMarkedBroken attrs; unsupported = hasUnsupportedPlatform attrs; insecure = isMarkedInsecure attrs; @@ -296,6 +332,8 @@ let { valid = "no"; reason = "unfree"; errormsg = "has an unfree license (‘${showLicense attrs.meta.license}’)"; } else if hasBlocklistedLicense attrs then { valid = "no"; reason = "blocklisted"; errormsg = "has a blocklisted license (‘${showLicense attrs.meta.license}’)"; } + else if hasDeniedNonSourceProvenance attrs then + { valid = "no"; reason = "non-source"; errormsg = "contains elements not built from source (‘${showSourceType attrs.meta.sourceProvenance}’)"; } else if !allowBroken && attrs.meta.broken or false then { valid = "no"; reason = "broken"; errormsg = "is marked as broken"; } else if !allowUnsupportedSystem && hasUnsupportedPlatform attrs then |