replaceVars: fail when exemption can't be found

This also changes stdenv's substitute --replace-fail to error out when
the replacement is the same as the search pattern, but can't be found.
This should not cause any problems in existing code, from what I can
tell from grepping nixpkgs.

The exception for pattern==replacement was previously introduced all the
way back in 5ff872aa24983cf3e1cf28bb990042846c1a97ee, but this was
apparently only used to make the check for the warning "simpler".

Changed files
+36 -18
pkgs
build-support
replace-vars
stdenv
generic
test
replace-vars
+5 -7
pkgs/build-support/replace-vars/replace-vars-with.nix
···
let
# We use `--replace-fail` instead of `--subst-var-by` so that if the thing isn't there, we fail.
-
subst-var-by =
-
name: value:
-
lib.optionals (value != null) [
-
"--replace-fail"
-
(lib.escapeShellArg "@${name}@")
-
(lib.escapeShellArg value)
-
];
substitutions = lib.concatLists (lib.mapAttrsToList subst-var-by replacements);
···
let
# We use `--replace-fail` instead of `--subst-var-by` so that if the thing isn't there, we fail.
+
subst-var-by = name: value: [
+
"--replace-fail"
+
(lib.escapeShellArg "@${name}@")
+
(lib.escapeShellArg (lib.defaultTo "@${name}@" value))
+
];
substitutions = lib.concatLists (lib.mapAttrsToList subst-var-by replacements);
+7 -11
pkgs/stdenv/generic/setup.sh
···
pattern="$2"
replacement="$3"
shift 3
-
local savedvar
-
savedvar="${!var}"
-
eval "$var"'=${'"$var"'//"$pattern"/"$replacement"}'
-
if [ "$pattern" != "$replacement" ]; then
-
if [ "${!var}" == "$savedvar" ]; then
-
if [ "$replace_mode" == --replace-warn ]; then
-
printf "substituteStream() in derivation $name: WARNING: pattern %q doesn't match anything in %s\n" "$pattern" "$description" >&2
-
elif [ "$replace_mode" == --replace-fail ]; then
-
printf "substituteStream() in derivation $name: ERROR: pattern %q doesn't match anything in %s\n" "$pattern" "$description" >&2
-
return 1
-
fi
fi
fi
;;
--subst-var)
···
pattern="$2"
replacement="$3"
shift 3
+
if ! [[ "${!var}" == *"$pattern"* ]]; then
+
if [ "$replace_mode" == --replace-warn ]; then
+
printf "substituteStream() in derivation $name: WARNING: pattern %q doesn't match anything in %s\n" "$pattern" "$description" >&2
+
elif [ "$replace_mode" == --replace-fail ]; then
+
printf "substituteStream() in derivation $name: ERROR: pattern %q doesn't match anything in %s\n" "$pattern" "$description" >&2
+
return 1
fi
fi
+
eval "$var"'=${'"$var"'//"$pattern"/"$replacement"}'
;;
--subst-var)
+24
pkgs/test/replace-vars/default.nix
···
touch $out
'';
};
in
{
···
touch $out
'';
+
+
fails-in-check-phase-with-bad-exemption =
+
runCommand "replaceVars-fails"
+
{
+
failed =
+
let
+
src = builtins.toFile "source.txt" ''
+
@a@
+
@b@
+
'';
+
in
+
testBuildFailure (
+
callReplaceVars src {
+
a = "a";
+
b = null;
+
c = null;
+
}
+
);
+
}
+
''
+
grep -e "ERROR: pattern @c@ doesn't match anything in file.*source.txt" $failed/testBuildFailure.log
+
+
touch $out
+
'';
};
in
{