aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaximilian Bosch <maximilian@mbosch.me>2021-05-18 15:07:30 +0200
committerMaximilian Bosch <maximilian@mbosch.me>2021-06-22 19:15:57 +0200
commit3504c811a55ecd58e0712cf24829c67c192f5e80 (patch)
tree97d291caa783961a4c55e3d39c1fac0097de0f20
parentf1e281c4fe1263a0c848bc8aaf57a0e61a99fa93 (diff)
Add testcase for `nix develop` with `__structuredAttrs`
-rw-r--r--src/nix/develop.cc3
-rw-r--r--src/nix/get-env.sh9
-rw-r--r--tests/shell.nix8
-rw-r--r--tests/structured-attrs-shell.nix2
-rw-r--r--tests/structured-attrs.sh5
5 files changed, 24 insertions, 3 deletions
diff --git a/src/nix/develop.cc b/src/nix/develop.cc
index 3443fab73..ee782c4ec 100644
--- a/src/nix/develop.cc
+++ b/src/nix/develop.cc
@@ -256,6 +256,9 @@ struct Common : InstallableCommand, MixProfile
// FIXME: properly unquote 'outputs'.
StringMap rewrites;
for (auto & outputName : tokenizeString<std::vector<std::string>>(replaceStrings(outputs->second.quoted, "'", ""))) {
+ // Hacky way to obtain the key of an associate array. This is needed for strctured attrs where
+ // `outputs` is an associative array. If the regex isn't matched, the non-structured-attrs behavior will
+ // be used.
std::regex ptrn(R"re(\[([A-z0-9]+)\]=.*)re");
std::smatch match;
if (std::regex_match(outputName, match, ptrn)) {
diff --git a/src/nix/get-env.sh b/src/nix/get-env.sh
index b6b8310a9..431440516 100644
--- a/src/nix/get-env.sh
+++ b/src/nix/get-env.sh
@@ -8,6 +8,9 @@ if [[ -n $stdenv ]]; then
source $stdenv/setup
fi
+# In case of `__structuredAttrs = true;` the list of outputs is an associative
+# array with a format like `outname => /nix/store/hash-drvname-outname`, so `__olist`
+# must contain the array's keys (hence `${!...[@]}`) in this case.
if [ -e .attrs.sh ]; then
__olist="${!outputs[@]}"
else
@@ -16,10 +19,10 @@ fi
for __output in $__olist; do
if [[ -z $__done ]]; then
- export > ${!__output}
- set >> ${!__output}
+ export > "${!__output}"
+ set >> "${!__output}"
__done=1
else
- echo -n >> ${!__output}
+ echo -n >> "${!__output}"
fi
done
diff --git a/tests/shell.nix b/tests/shell.nix
index 24ebcc04c..53a32059b 100644
--- a/tests/shell.nix
+++ b/tests/shell.nix
@@ -8,6 +8,14 @@ let pkgs = rec {
for pkg in $buildInputs; do
export PATH=$PATH:$pkg/bin
done
+
+ # mimic behavior of stdenv for `$out` etc. for structured attrs.
+ if [ -n "''${ATTRS_SH_FILE}" ]; then
+ for o in "''${!outputs[@]}"; do
+ eval "''${o}=''${outputs[$o]}"
+ export "''${o}"
+ done
+ fi
'';
stdenv = mkDerivation {
diff --git a/tests/structured-attrs-shell.nix b/tests/structured-attrs-shell.nix
index 0c01c2568..57c1e6bd2 100644
--- a/tests/structured-attrs-shell.nix
+++ b/tests/structured-attrs-shell.nix
@@ -6,10 +6,12 @@ let
mkdir $out; echo bla > $out/bla
'';
};
+ inherit (import ./shell.nix { inNixShell = true; }) stdenv;
in
mkDerivation {
name = "structured2";
__structuredAttrs = true;
+ inherit stdenv;
outputs = [ "out" "dev" ];
my.list = [ "a" "b" "c" ];
exportReferencesGraph.refs = [ dep ];
diff --git a/tests/structured-attrs.sh b/tests/structured-attrs.sh
index 241835539..f851b3cbb 100644
--- a/tests/structured-attrs.sh
+++ b/tests/structured-attrs.sh
@@ -12,3 +12,8 @@ nix-build structured-attrs.nix -A all -o $TEST_ROOT/result
export NIX_BUILD_SHELL=$SHELL
env NIX_PATH=nixpkgs=shell.nix nix-shell structured-attrs-shell.nix \
--run 'test -e .attrs.json; test "3" = "$(jq ".my.list|length" < $ATTRS_JSON_FILE)"'
+
+# `nix develop` is a slightly special way of dealing with environment vars, it parses
+# these from a shell-file exported from a derivation. This is to test especially `outputs`
+# (which is an associative array in thsi case) being fine.
+nix develop -f structured-attrs-shell.nix -c bash -c 'test -n "$out"'