aboutsummaryrefslogtreecommitdiff
path: root/pkgs/stdenv
diff options
context:
space:
mode:
authorDaiderd Jordan <daiderd@gmail.com>2020-04-19 12:04:58 +0200
committerDaiderd Jordan <daiderd@gmail.com>2020-04-19 12:53:04 +0200
commit950ac2bc8fa13a7557d931123c24c93418662a2d (patch)
tree3bb7b3e76fdcf326e5a9e6b796802c7737bcdf76 /pkgs/stdenv
parent257aff801079890e2c5ed3fa5b8e5f818f611fad (diff)
meta: expose availability flags in derivation metadata
Currently it's not possible to determine the reason why a package is unavailable without evaluating nixpkgs multiple times with different settings. eg. nix-repl> :p android-studio.meta { available = false; broken = false; unfree = true; unsupported = true; ... } The following snippet is an example that uses this information to query the availability information of all packages in nixpkgs, giving an overview of all the packages currently marked as broken, etc. { pkgs }: with import <nixpkgs/lib>; let mapPkgs = let mapPkgs' = path: f: mapAttrs (n: v: let result = builtins.tryEval (v ? meta); in if !result.success then {} else if isDerivation v then f (path ++ [n]) v else if isAttrs v && v.recurseForDerivations or false then mapPkgs' (path ++ [n]) f v else {} ); in mapPkgs' []; getMeta = path: drv: if drv.meta ? available then let meta = { pkg = concatStringsSep "." path; inherit (drv.meta) broken unfree unsupported insecure; }; in builtins.trace meta.pkg meta else {}; metaToList = attrs: flatten (map (v: if v ? pkg then v else metaToList v) (attrValues attrs)); in metaToList (mapPkgs getMeta pkgs)
Diffstat (limited to 'pkgs/stdenv')
-rw-r--r--pkgs/stdenv/generic/check-meta.nix39
-rw-r--r--pkgs/stdenv/generic/make-derivation.nix3
2 files changed, 31 insertions, 11 deletions
diff --git a/pkgs/stdenv/generic/check-meta.nix b/pkgs/stdenv/generic/check-meta.nix
index 21ae809a2225..e6e90a6df1e1 100644
--- a/pkgs/stdenv/generic/check-meta.nix
+++ b/pkgs/stdenv/generic/check-meta.nix
@@ -49,6 +49,18 @@ let
isUnfree = licenses: lib.lists.any (l: !l.free or true) licenses;
+ hasUnfreeLicense = attrs:
+ hasLicense attrs &&
+ isUnfree (lib.lists.toList attrs.meta.license);
+
+ isMarkedBroken = attrs: attrs.meta.broken or false;
+
+ hasUnsupportedPlatform = attrs:
+ (!lib.lists.elem hostPlatform.system (attrs.meta.platforms or lib.platforms.all) ||
+ lib.lists.elem hostPlatform.system (attrs.meta.badPlatforms or []));
+
+ isMarkedInsecure = attrs: (attrs.meta.knownVulnerabilities or []) != [];
+
# Alow granular checks to allow only some unfree packages
# Example:
# {pkgs, ...}:
@@ -62,16 +74,15 @@ let
# package has an unfree license and is not explicitely allowed by the
# `allowUnfreePredicate` function.
hasDeniedUnfreeLicense = attrs:
+ hasUnfreeLicense attrs &&
!allowUnfree &&
- hasLicense attrs &&
- isUnfree (lib.lists.toList attrs.meta.license) &&
!allowUnfreePredicate attrs;
allowInsecureDefaultPredicate = x: builtins.elem (getName x) (config.permittedInsecurePackages or []);
allowInsecurePredicate = x: (config.allowInsecurePredicate or allowInsecureDefaultPredicate) x;
hasAllowedInsecure = attrs:
- (attrs.meta.knownVulnerabilities or []) == [] ||
+ !(isMarkedInsecure attrs) ||
allowInsecurePredicate attrs ||
builtins.getEnv "NIXPKGS_ALLOW_INSECURE" == "1";
@@ -173,6 +184,9 @@ let
platforms = listOf str;
hydraPlatforms = listOf str;
broken = bool;
+ unfree = bool;
+ unsupported = bool;
+ insecure = bool;
# TODO: refactor once something like Profpatsch's types-simple will land
# This is currently dead code due to https://github.com/NixOS/nix/issues/2532
tests = attrsOf (mkOptionType {
@@ -224,17 +238,22 @@ let
#
# Return { valid: Bool } and additionally
# { reason: String; errormsg: String } if it is not valid, where
- # reason is one of "unfree", "blacklisted" or "broken".
+ # reason is one of "unfree", "blacklisted", "broken", "insecure", ...
+ # Along with a boolean flag for each reason
checkValidity = attrs:
- if hasDeniedUnfreeLicense attrs && !(hasWhitelistedLicense attrs) then
+ {
+ unfree = hasUnfreeLicense attrs;
+ broken = isMarkedBroken attrs;
+ unsupported = hasUnsupportedPlatform attrs;
+ insecure = isMarkedInsecure attrs;
+ }
+ // (if hasDeniedUnfreeLicense attrs && !(hasWhitelistedLicense attrs) then
{ valid = false; reason = "unfree"; errormsg = "has an unfree license (‘${showLicense attrs.meta.license}’)"; }
else if hasBlacklistedLicense attrs then
{ valid = false; reason = "blacklisted"; errormsg = "has a blacklisted license (‘${showLicense attrs.meta.license}’)"; }
else if !allowBroken && attrs.meta.broken or false then
{ valid = false; reason = "broken"; errormsg = "is marked as broken"; }
- else if !allowUnsupportedSystem &&
- (!lib.lists.elem hostPlatform.system (attrs.meta.platforms or lib.platforms.all) ||
- lib.lists.elem hostPlatform.system (attrs.meta.badPlatforms or [])) then
+ else if !allowUnsupportedSystem && hasUnsupportedPlatform attrs then
{ valid = false; reason = "unsupported"; errormsg = "is not supported on ‘${hostPlatform.system}’"; }
else if !(hasAllowedInsecure attrs) then
{ valid = false; reason = "insecure"; errormsg = "is marked as insecure"; }
@@ -242,14 +261,14 @@ let
{ valid = false; reason = "broken-outputs"; errormsg = "has invalid meta.outputsToInstall"; }
else let res = checkMeta (attrs.meta or {}); in if res != [] then
{ valid = false; reason = "unknown-meta"; errormsg = "has an invalid meta attrset:${lib.concatMapStrings (x: "\n\t - " + x) res}"; }
- else { valid = true; };
+ else { valid = true; });
assertValidity = { meta, attrs }: let
validity = checkValidity attrs;
in validity // {
# Throw an error if trying to evaluate an non-valid derivation
handled = if !validity.valid
- then handleEvalIssue { inherit meta attrs; } (removeAttrs validity ["valid"])
+ then handleEvalIssue { inherit meta attrs; } { inherit (validity) reason errormsg; }
else true;
};
diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix
index a11b280b047e..7eb41b314dbb 100644
--- a/pkgs/stdenv/generic/make-derivation.nix
+++ b/pkgs/stdenv/generic/make-derivation.nix
@@ -302,8 +302,9 @@ in rec {
# Fill `meta.position` to identify the source location of the package.
// lib.optionalAttrs (pos != null) {
position = pos.file + ":" + toString pos.line;
- # Expose the result of the checks for everyone to see.
} // {
+ # Expose the result of the checks for everyone to see.
+ inherit (validity) unfree broken unsupported insecure;
available = validity.valid
&& (if config.checkMetaRecursively or false
then lib.all (d: d.meta.available or true) references