From d2e4af7c7eaed58f62e61bc53818e47ba2555f24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20=C4=8Cun=C3=A1t?= Date: Sun, 29 Jan 2017 11:50:21 +0100 Subject: [PATCH] stdenv: allow querying meta on disallowed packages In the end I've chosen to do the check when evaluating the name. There were two tricky points to consider: - nix-env -qa (changes in there tend to be very slow to get released) - hydra.nixos.org https://github.com/NixOS/nixpkgs/pull/9305#issuecomment-132791730 --- lib/check-meta.nix | 21 ++++++++++++++++----- pkgs/stdenv/generic/default.nix | 2 +- pkgs/top-level/release-lib.nix | 3 +++ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/lib/check-meta.nix b/lib/check-meta.nix index b490d63922be65..5499177ff62b5b 100644 --- a/lib/check-meta.nix +++ b/lib/check-meta.nix @@ -2,17 +2,28 @@ let lib = import ./default.nix; in rec { - # Extend a derivation with a check for brokenness, license, etc. - # Throw a descriptive error when the check fails. - # Note: no dependencies are checked in this step. - addMetaCheck = config: meta: drv: + # Extend attributes to be passed to derivation (or similar) with a check + # for brokenness, license, etc. Throw a descriptive error if the check fails. + # Note: no dependencies are checked in this step, but this should be done before + # applying the `derivation` primitive in order to "propagate to dependants". + addMetaCheckInner = config: meta: drv: let name = drv.name or "«name-missing»"; position = meta.position or "«unknown-file»"; v = checkMetaValidity { inherit meta config; inherit (drv) system; }; in - if v.valid then drv + # As a compromise, do the check when evaluating the name attribute; + # the intention is to also catch any attempt to show in nix-env -qa, + # while allowing to query meta (surprisingly even --no-name doesn't break that). + drv // { + name = if v.valid then drv.name else throwEvalHelp (removeAttrs v ["valid"] // { inherit name position; }); + }; + + # Make sure the dependencies are evaluted when accessing the name. + # The input is a derivation, i.e. *after* applying the `derivation` primitive. + addMetaCheckOuter = drv: + drv // { name = assert drv.outPath != null; drv.name; }; # Throw a descriptive error message for a failed evaluation check. throwEvalHelp = { reason, errormsg, name, position }: diff --git a/pkgs/stdenv/generic/default.nix b/pkgs/stdenv/generic/default.nix index 39bfe4516a8a83..801f732919de73 100644 --- a/pkgs/stdenv/generic/default.nix +++ b/pkgs/stdenv/generic/default.nix @@ -169,7 +169,7 @@ let in lib.addPassthru - (derivation (lib.addMetaCheck config meta derivationArg)) + (lib.addMetaCheckOuter (derivation (lib.addMetaCheckInner config meta derivationArg))) ( { overrideAttrs = f: mkDerivation (attrs // (f attrs)); inherit meta passthru; diff --git a/pkgs/top-level/release-lib.nix b/pkgs/top-level/release-lib.nix index 5fe87711c01650..a8aa26e64339fe 100644 --- a/pkgs/top-level/release-lib.nix +++ b/pkgs/top-level/release-lib.nix @@ -85,6 +85,9 @@ rec { packagePlatforms = mapAttrs (name: value: let res = builtins.tryEval ( if isDerivation value then + # Hopefully a reliable way to test whether the derivation evaluates, + # including brokenness/license checks in any dependencies. + assert value.outPath != null; value.meta.hydraPlatforms or (value.meta.platforms or [ "x86_64-linux" ]) else if value.recurseForDerivations or false || value.recurseForRelease or false then packagePlatforms value