summary refs log tree commit diff
path: root/pkgs/stdenv/generic
diff options
context:
space:
mode:
authorMaximilian Bosch <maximilian@mbosch.me>2023-09-28 11:05:52 +0200
committerMaximilian Bosch <maximilian@mbosch.me>2023-10-04 18:35:30 +0200
commit53c5f084151264701e6332f1606bb892bf9c3574 (patch)
tree0ddce6af6b2909166fdc5d4db93522650f5b505b /pkgs/stdenv/generic
parent1e41c3352bb8de154f85b85c21bfc911f010b777 (diff)
downloadnixpkgs-53c5f084151264701e6332f1606bb892bf9c3574.tar
nixpkgs-53c5f084151264701e6332f1606bb892bf9c3574.tar.gz
nixpkgs-53c5f084151264701e6332f1606bb892bf9c3574.tar.bz2
nixpkgs-53c5f084151264701e6332f1606bb892bf9c3574.tar.lz
nixpkgs-53c5f084151264701e6332f1606bb892bf9c3574.tar.xz
nixpkgs-53c5f084151264701e6332f1606bb892bf9c3574.tar.zst
nixpkgs-53c5f084151264701e6332f1606bb892bf9c3574.zip
stdenv: refactor `.attrs.sh` detection
Relying on `.attrs.sh` to exist in `$NIX_BUILD_TOP` is problematic
because that's not compatible with how `nix-shell(1)` behaves. It places
`.attrs.{json,sh}` into a temporary directory and makes them accessible via
`$NIX_ATTRS_{SH,JSON}_FILE` in the environment[1]. The sole reason that
`nix-shell(1)` still works with structured-attrs enabled derivations
is that the contents of `.attrs.sh` are sourced into the
shell before sourcing `$stdenv/setup` (if `$stdenv` exists) by `nix-shell`.

However, the assumption that two files called `.attrs.sh` and
`.attrs.json` exist in `$NIX_BUILD_TOP` is wrong in an interactive shell
session and thus an inconsistency between shell debug session and actual
builds which can lead to unexpected problems.

To be precise, we currently have the following problem: an expression
like

  with import ./. {};
  runCommand "foo" { __structuredAttrs = true; foo.bar = [ 1 2 3 ]; }
    ''
      echo "''${__structuredAttrs@Q}"
      touch $out
    ''

prints `1` in its build-log. However when building interactively in a
`nix-shell`, it doesn't.

Because of that, I'm considering to propose a full deprecation of
`$NIX_BUILD_TOP/.attrs.{json,sh}`. A first step is to only mention the
environment variables, but not the actual paths anymore in Nix's
manual[2]. The second step - this patch - is to fix nixpkgs' stdenv
accordingly.

Please note that we cannot check for `-e "$NIX_ATTRS_JSON_FILE"` because
certain outdated Nix minors (that are still in the range of supported
Nix versions in `nixpkgs`) have a bug where `NIX_ATTRS_JSON_FILE` points
to the wrong file while building[3].

Also, for compatibility with Nix 2.3 which doesn't provide these
environment variables at all we still need to check for the existence of
.attrs.json/.attrs.sh here. As soon as we bump nixpkgs' minver to 2.4,
this can be dropped.

Finally, dropped the check for ATTRS_SH_FILE because that was never
relevant. In nix#4770 the ATTRS_SH_FILE variable was introduced[4] and
in a review iteration prefixed with NIX_[5]. In other words, these
variables were never part of a release and you'd only have this problem
if you'd use a Nix from a git revision of my branch from back then. In
other words, that's dead code.

[1] https://github.com/nixos/nix/pull/4770#issuecomment-834718851
[2] https://github.com/NixOS/nix/pull/9032
[3] https://github.com/NixOS/nix/issues/6736
[4] https://github.com/NixOS/nix/pull/4770/commits/3944a120ec6986c723bf36bfade9b331dd4af68a
[5] https://github.com/NixOS/nix/pull/4770/commits/27ce722638eeabb987bc9b4a1234c2818c5bf401
Diffstat (limited to 'pkgs/stdenv/generic')
-rw-r--r--pkgs/stdenv/generic/setup.sh17
1 files changed, 2 insertions, 15 deletions
diff --git a/pkgs/stdenv/generic/setup.sh b/pkgs/stdenv/generic/setup.sh
index ad9857fc9d6..419a66261e6 100644
--- a/pkgs/stdenv/generic/setup.sh
+++ b/pkgs/stdenv/generic/setup.sh
@@ -16,29 +16,15 @@ if (( "${NIX_DEBUG:-0}" >= 6 )); then
     set -x
 fi
 
-if [ -f .attrs.sh ]; then
+if [ -f .attrs.sh ] || [[ -n "${NIX_ATTRS_JSON_FILE:-}" ]]; then
     __structuredAttrs=1
     echo "structuredAttrs is enabled"
-else
-    __structuredAttrs=
-fi
 
-if [ -n "$__structuredAttrs" ]; then
     for outputName in "${!outputs[@]}"; do
         # ex: out=/nix/store/...
         export "$outputName=${outputs[$outputName]}"
     done
 
-    # Before Nix 2.4, $NIX_ATTRS_*_FILE was named differently:
-    # https://github.com/NixOS/nix/commit/27ce722
-    if [[ -n "${ATTRS_JSON_FILE:-}" ]]; then
-        export NIX_ATTRS_JSON_FILE="$ATTRS_JSON_FILE"
-    fi
-
-    if [[ -n "${ATTRS_SH_FILE:-}" ]]; then
-        export NIX_ATTRS_SH_FILE="$ATTRS_SH_FILE"
-    fi
-
     # $NIX_ATTRS_JSON_FILE pointed to the wrong location in sandbox
     # https://github.com/NixOS/nix/issues/6736; please keep around until the
     # fix reaches *every patch version* that's >= lib/minver.nix
@@ -49,6 +35,7 @@ if [ -n "$__structuredAttrs" ]; then
         export NIX_ATTRS_SH_FILE="$NIX_BUILD_TOP/.attrs.sh"
     fi
 else
+    __structuredAttrs=
     : "${outputs:=out}"
 fi