summary refs log tree commit diff
path: root/pkgs/stdenv
diff options
context:
space:
mode:
authorGraham Christensen <graham@grahamc.com>2018-09-18 09:30:59 -0400
committerGraham Christensen <graham@grahamc.com>2018-09-18 10:38:44 -0400
commitb80c9ce4a962661f5589092f618ca8ae70f56a1e (patch)
treeeb61d0c73fc46d2340dc2ed55366d92613956d51 /pkgs/stdenv
parent0a308534615dc3cbb37f3c9400323a9089083343 (diff)
downloadnixlib-b80c9ce4a962661f5589092f618ca8ae70f56a1e.tar
nixlib-b80c9ce4a962661f5589092f618ca8ae70f56a1e.tar.gz
nixlib-b80c9ce4a962661f5589092f618ca8ae70f56a1e.tar.bz2
nixlib-b80c9ce4a962661f5589092f618ca8ae70f56a1e.tar.lz
nixlib-b80c9ce4a962661f5589092f618ca8ae70f56a1e.tar.xz
nixlib-b80c9ce4a962661f5589092f618ca8ae70f56a1e.tar.zst
nixlib-b80c9ce4a962661f5589092f618ca8ae70f56a1e.zip
stdenv: Validate meta.outputsToInstall
If meta.outputsToInstall is set to include absent outputs, various
tools break including channel updates and nix-env.

    grahamc@Morbo> nix-env -i -f . -A elf-header-real
    installing 'elf-header'
    error: this derivation has bad 'meta.outputsToInstall'

This patch verifies each value in meta.outputsToInstall is a valid
output. It validates this condition only if checkMeta is true.

    grahamc@Morbo> nix-build . -A elf-header-real
    error: Package ‘elf-header’ in /home/grahamc/projects/nixpkgs/pkgs/development/libraries/elf-header/default.nix:36 has invalid meta.outputsToInstall, refusing to evaluate.

    The package elf-header has set meta.outputsToInstall to: bin

    however elf-header only has the outputs: out

    and is missing the following ouputs:

      - bin

    (use '--show-trace' to show detailed location information)

Note, now the nix-env experience is decidedly worse for users who have
checkMeta set to true:

    grahamc@Morbo> nix-env -i -f . -A elf-header-real; echo $?
    0

though since this is already an issue for unfree, broken, unsupported,
and insecure validity problems I'm not sure we should do something
different here.
Diffstat (limited to 'pkgs/stdenv')
-rw-r--r--pkgs/stdenv/generic/check-meta.nix25
1 files changed, 25 insertions, 0 deletions
diff --git a/pkgs/stdenv/generic/check-meta.nix b/pkgs/stdenv/generic/check-meta.nix
index a5c8ca705231..28b69f5c2dc9 100644
--- a/pkgs/stdenv/generic/check-meta.nix
+++ b/pkgs/stdenv/generic/check-meta.nix
@@ -81,6 +81,7 @@ let
     unsupported = remediate_whitelist "UnsupportedSystem";
     blacklisted = x: "";
     insecure = remediate_insecure;
+    broken-outputs = remediateOutputsToInstall;
     unknown-meta = x: "";
   };
   remediate_whitelist = allow_attr: attrs:
@@ -125,6 +126,20 @@ let
 
       '';
 
+  remediateOutputsToInstall = attrs: let
+      expectedOutputs = attrs.meta.outputsToInstall or [];
+      actualOutputs = attrs.outputs or [ "out" ];
+      missingOutputs = builtins.filter (output: ! builtins.elem output actualOutputs) expectedOutputs;
+    in ''
+      The package ${attrs.name} has set meta.outputsToInstall to: ${builtins.concatStringsSep ", " expectedOutputs}
+
+      however ${attrs.name} only has the outputs: ${builtins.concatStringsSep ", " actualOutputs}
+
+      and is missing the following ouputs:
+
+      ${lib.concatStrings (builtins.map (output: "  - ${output}\n") missingOutputs)}
+    '';
+
   handleEvalIssue = attrs: { reason , errormsg ? "" }:
     let
       msg = ''
@@ -185,6 +200,14 @@ let
     in  anyMatch (attrs.meta.platforms or lib.platforms.all) &&
       ! anyMatch (attrs.meta.badPlatforms or []);
 
+  checkOutputsToInstall = attrs: let
+      expectedOutputs = attrs.meta.outputsToInstall or [];
+      actualOutputs = attrs.outputs or [ "out" ];
+      missingOutputs = builtins.filter (output: ! builtins.elem output actualOutputs) expectedOutputs;
+    in if shouldCheckMeta
+       then builtins.length missingOutputs > 0
+       else false;
+
   # Check if a derivation is valid, that is whether it passes checks for
   # e.g brokenness or license.
   #
@@ -202,6 +225,8 @@ let
       { valid = false; reason = "unsupported"; errormsg = "is not supported on ‘${hostPlatform.config}’"; }
     else if !(hasAllowedInsecure attrs) then
       { valid = false; reason = "insecure"; errormsg = "is marked as insecure"; }
+    else if checkOutputsToInstall attrs then
+      { 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; };