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 let
# We use `--replace-fail` instead of `--subst-var-by` so that if the thing isn't there, we fail. # We use `--replace-fail` instead of `--subst-var-by` so that if the thing isn't there, we fail.
subst-var-by = subst-var-by = name: value: [
name: value: "--replace-fail"
lib.optionals (value != null) [ (lib.escapeShellArg "@${name}@")
"--replace-fail" (lib.escapeShellArg (lib.defaultTo "@${name}@" value))
(lib.escapeShellArg "@${name}@") ];
(lib.escapeShellArg value)
];
substitutions = lib.concatLists (lib.mapAttrsToList subst-var-by replacements); substitutions = lib.concatLists (lib.mapAttrsToList subst-var-by replacements);

View file

@ -1042,19 +1042,15 @@ substituteStream() {
pattern="$2" pattern="$2"
replacement="$3" replacement="$3"
shift 3 shift 3
local savedvar if ! [[ "${!var}" == *"$pattern"* ]]; then
savedvar="${!var}" if [ "$replace_mode" == --replace-warn ]; then
eval "$var"'=${'"$var"'//"$pattern"/"$replacement"}' printf "substituteStream() in derivation $name: WARNING: pattern %q doesn't match anything in %s\n" "$pattern" "$description" >&2
if [ "$pattern" != "$replacement" ]; then elif [ "$replace_mode" == --replace-fail ]; then
if [ "${!var}" == "$savedvar" ]; then printf "substituteStream() in derivation $name: ERROR: pattern %q doesn't match anything in %s\n" "$pattern" "$description" >&2
if [ "$replace_mode" == --replace-warn ]; then return 1
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
fi fi
eval "$var"'=${'"$var"'//"$pattern"/"$replacement"}'
;; ;;
--subst-var) --subst-var)

View file

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