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 5ff872aa24, but this was
apparently only used to make the check for the warning "simpler".
This commit is contained in:
Wolfgang Walther 2025-02-08 11:11:42 +01:00
parent dfd366680e
commit 2e43b87c62
No known key found for this signature in database
GPG Key ID: B39893FA5F65CAE1
3 changed files with 36 additions and 18 deletions

View File

@ -58,13 +58,11 @@
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)
];
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);

View File

@ -1042,19 +1042,15 @@ substituteStream() {
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
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)

View File

@ -119,6 +119,30 @@ let
grep -F "@c@" $failed/testBuildFailure.log
! grep -F "@b@" $failed/testBuildFailure.log
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
'';
};