diff --git a/pkgs/build-support/replace-vars/default.nix b/pkgs/build-support/replace-vars/default.nix index a6fc94f4f376d..0053b5e7c6162 100644 --- a/pkgs/build-support/replace-vars/default.nix +++ b/pkgs/build-support/replace-vars/default.nix @@ -1,18 +1,24 @@ -{ lib, stdenvNoCC }: +{ + lib, + stdenvNoCC, + doCheck ? true, +}: /** - `replaceVars` is a wrapper around the [bash function `substitute`](https://nixos.org/manual/nixpkgs/stable/#fun-substitute) + `replaceVars` is a wrapper around the [bash function `substitute`](https://nixos.org/manual/nixpkgs/unstable/#fun-substitute) in the stdenv. It allows for terse replacement of names in the specified path, while checking for common mistakes such as naming a replacement that does nothing or forgetting a variable which needs to be replaced. - As with the [`--subst-var-by`](https://nixos.org/manual/nixpkgs/stable/#fun-substitute-subst-var-by) + As with the [`--subst-var-by`](https://nixos.org/manual/nixpkgs/unstable/#fun-substitute-subst-var-by) flag, names are encoded as `@name@` in the provided file at the provided path. 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. + has occurred will cause a build failure. In the case this step is not desired, use + `replaceVars.withoutCheck`, which has the same semantics but doesn't have a check phase making + the assertion about remaining unreplaced variables. # Inputs @@ -20,15 +26,65 @@ : 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/unstable/#fun-substitute). - # Example + # Examples + + ## `replaceVars` + + Given a file `greeting.txt` that contains the following contents: + + ``` + @greeting@! Have you heard about the way of the Jedi? + ``` + + And a derivation that looks like this: ```nix { replaceVars }: - replaceVars ./greeting.txt { world = "hello"; } + replaceVars ./greeting.txt { greeting = "Hello there"; } + ``` + + The resulting file in `$out` contains this text: + + ``` + Hello there! Have you heard about the way of the Jedi? + ``` + + ## `replaceVars.withoutCheck` + + Given a file named `template.json` that contains the following contents: + ``` + { + "key": "@key@", + "value": @value@ + } + ``` + + And a derivation that looks like this: + + ```nix + { replaceVars }: + + replaceVars.withoutCheck ./template.json { key = "master"; } + ``` + + The resulting file in `$out` contains this text: + + ``` + { + "key": "master", + "value": @value@ + } + ``` + + This allows chaining together `replaceVars` calls in subsequent derivations or the use of the + `substituteInPlace` stdenv function to complete the replacements, at the cost of potentially + leaving unreplaced material in the output. + + # Tests See `../../test/replace-vars/default.nix` for tests of this function. */ @@ -48,7 +104,7 @@ in stdenvNoCC.mkDerivation { name = baseNameOf (toString path); src = path; - doCheck = true; + inherit doCheck; dontUnpack = true; preferLocalBuild = true; allowSubstitutes = false; diff --git a/pkgs/test/replace-vars/default.nix b/pkgs/test/replace-vars/default.nix index 76dc81de49c81..b049eefb61730 100644 --- a/pkgs/test/replace-vars/default.nix +++ b/pkgs/test/replace-vars/default.nix @@ -27,6 +27,23 @@ in ''; }; + # Success case for `replaceVars.withoutCheck`. + replaceVars-without-check = testEqualContents { + assertion = "replaceVars-without-check"; + actual = replaceVars.withoutCheck ./source.txt { + "equal in" = "are the same in"; + brotherhood = "shared humanity"; + }; + + 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 shared humanity. + + -- eroosevelt@humanrights.un.org + ''; + }; + # There might eventually be a usecase for this, but it's not supported at the moment. replaceVars-fails-on-directory = runCommand "replaceVars-fails" { failed = testBuildFailure (replaceVars emptyDirectory { }); } @@ -43,6 +60,14 @@ in touch $out ''; + replaceVars-without-check-fails-in-build-phase = + runCommand "replaceVars-fails" + { failed = testBuildFailure (replaceVars.withoutCheck emptyFile { not-found = "boo~"; }); } + '' + grep -e "ERROR: pattern @not-found@ doesn't match anything in file.*empty-file" $failed/testBuildFailure.log + touch $out + ''; + replaceVars-fails-in-check-phase = runCommand "replaceVars-fails" { diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 69e98c04372a4..ea1c1b05c619e 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -1329,7 +1329,9 @@ with pkgs; replaceDependency = callPackage ../build-support/replace-dependency.nix { }; - replaceVars = callPackage ../build-support/replace-vars { }; + replaceVars = callPackage ../build-support/replace-vars { } // { + withoutCheck = callPackage ../build-support/replace-vars { doCheck = false; }; + }; nukeReferences = callPackage ../build-support/nuke-references { inherit (darwin) signingUtils;