From 2d64877f636944facc0b12e6bc07fabd860cf8aa Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Tue, 19 Nov 2024 22:16:10 +0100 Subject: [PATCH] replaceVars: allow exemptions replaceVars has a checkPhase to confirm that no left-over @...@ patterns remain. Since it's not possible to use "placeholder" with replaceVars, the substitution of some patterns must be delayed to a later step. By passing "null" for those keys explicitly, replaceVars can make an exemption *just for this case*, but keep checking all other references. --- pkgs/build-support/replace-vars/default.nix | 31 +++++++++------ pkgs/test/replace-vars/default.nix | 43 +++++++++++++++++++++ pkgs/tools/virtualization/mkosi/default.nix | 4 +- 3 files changed, 65 insertions(+), 13 deletions(-) diff --git a/pkgs/build-support/replace-vars/default.nix b/pkgs/build-support/replace-vars/default.nix index a6fc94f4f376..0088279ad939 100644 --- a/pkgs/build-support/replace-vars/default.nix +++ b/pkgs/build-support/replace-vars/default.nix @@ -11,8 +11,8 @@ Any unmatched variable names in the file at the provided path will cause a build failure. - Any remaining text that matches `@[A-Za-z_][0-9A-Za-z_'-]@` in the output after replacement - has occurred will cause a build failure. + By default, any remaining text that matches `@[A-Za-z_][0-9A-Za-z_'-]@` in the output after replacement + has occurred will cause a build failure. Variables can be excluded from this check by passing "null" for them. # Inputs @@ -20,7 +20,8 @@ : The file in which to replace variables. `attrs` (AttrsOf String) - : Each entry in this set corresponds to a `--subst-var-by` entry in [`substitute`](https://nixos.org/manual/nixpkgs/stable/#fun-substitute). + : Each entry in this set corresponds to a `--subst-var-by` entry in [`substitute`](https://nixos.org/manual/nixpkgs/stable/#fun-substitute) or + null to keep it unchanged. # Example @@ -36,13 +37,19 @@ path: attrs: 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 value) - ]; + subst-var-by = + name: value: + lib.optionals (value != null) [ + "--replace-fail" + (lib.escapeShellArg "@${name}@") + (lib.escapeShellArg value) + ]; replacements = lib.concatLists (lib.mapAttrsToList subst-var-by attrs); + + left-overs = map ({ name, ... }: name) ( + builtins.filter ({ value, ... }: value == null) (lib.attrsToList attrs) + ); in stdenvNoCC.mkDerivation { @@ -62,13 +69,15 @@ stdenvNoCC.mkDerivation { # Look for Nix identifiers surrounded by `@` that aren't substituted. checkPhase = let - regex = lib.escapeShellArg "@[a-zA-Z_][0-9A-Za-z_'-]*@"; + lookahead = + if builtins.length left-overs == 0 then "" else "(?!${builtins.concatStringsSep "|" left-overs}@)"; + regex = lib.escapeShellArg "@${lookahead}[a-zA-Z_][0-9A-Za-z_'-]*@"; in '' runHook preCheck - if grep -qe ${regex} "$out"; then + if grep -Pqe ${regex} "$out"; then echo The following look like unsubstituted Nix identifiers that remain in "$out": - grep -oe ${regex} "$out" + grep -Poe ${regex} "$out" echo Use the more precise '`substitute`' function if this check is in error. exit 1 fi diff --git a/pkgs/test/replace-vars/default.nix b/pkgs/test/replace-vars/default.nix index 76dc81de49c8..115836ba22ed 100644 --- a/pkgs/test/replace-vars/default.nix +++ b/pkgs/test/replace-vars/default.nix @@ -69,6 +69,49 @@ in # Shouldn't see the "cannot detect" version. ! grep -q -F "cannot detect due to space" $failed/testBuildFailure.log + touch $out + ''; + + replaceVars-succeeds-with-exemption = testEqualContents { + assertion = "replaceVars-succeeds-with-exemption"; + actual = replaceVars ./source.txt { + free = "free"; + "equal in" = "are the same in"; + brotherhood = null; + }; + + expected = builtins.toFile "expected" '' + All human beings are born free and are the same in dignity and rights. + They are endowed with reason and conscience and should act towards + one another in a spirit of @brotherhood@. + + -- eroosevelt@humanrights.un.org + ''; + }; + + replaceVars-fails-in-check-phase-with-exemption = + runCommand "replaceVars-fails-with-exemption" + { + failed = + let + src = builtins.toFile "source.txt" '' + @a@ + @b@ + @c@ + ''; + in + testBuildFailure ( + replaceVars src { + a = "a"; + b = null; + } + ); + } + '' + grep -e "unsubstituted Nix identifiers.*source.txt" $failed/testBuildFailure.log + grep -F "@c@" $failed/testBuildFailure.log + ! grep -F "@b@" $failed/testBuildFailure.log + touch $out ''; } diff --git a/pkgs/tools/virtualization/mkosi/default.nix b/pkgs/tools/virtualization/mkosi/default.nix index 2f5dea5481fb..a39bec7ae876 100644 --- a/pkgs/tools/virtualization/mkosi/default.nix +++ b/pkgs/tools/virtualization/mkosi/default.nix @@ -68,7 +68,7 @@ buildPythonApplication rec { (replaceVars ./0001-Use-wrapped-binaries-instead-of-Python-interpreter.patch { UKIFY = "${systemdForMkosi}/lib/systemd/ukify"; PYTHON_PEFILE = "${python3pefile}/bin/python3.12"; - MKOSI_SANDBOX = "~MKOSI_SANDBOX~"; # to satisfy replaceVars, will be replaced in postPatch + MKOSI_SANDBOX = null; # will be replaced in postPatch }) (replaceVars ./0002-Fix-library-resolving.patch { LIBC = "${stdenv.cc.libc}/lib/libc.so.6"; @@ -84,7 +84,7 @@ buildPythonApplication rec { postPatch = '' # As we need the $out reference, we can't use `replaceVars` here. substituteInPlace mkosi/run.py \ - --replace-fail '~MKOSI_SANDBOX~' "\"$out/bin/mkosi-sandbox\"" + --replace-fail '@MKOSI_SANDBOX@' "\"$out/bin/mkosi-sandbox\"" ''; nativeBuildInputs = [