Merge pull request #301350 from philiptaron/substituteAttrs
This commit is contained in:
commit
086a5ea5b3
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@ -43,9 +43,11 @@
|
||||
/pkgs/top-level/stage.nix @Ericson2314
|
||||
/pkgs/top-level/splice.nix @Ericson2314
|
||||
/pkgs/top-level/release-cross.nix @Ericson2314
|
||||
/pkgs/stdenv @philiptaron
|
||||
/pkgs/stdenv/generic @Ericson2314
|
||||
/pkgs/stdenv/generic/check-meta.nix @Ericson2314
|
||||
/pkgs/stdenv/cross @Ericson2314
|
||||
/pkgs/build-support @philiptaron
|
||||
/pkgs/build-support/cc-wrapper @Ericson2314
|
||||
/pkgs/build-support/bintools-wrapper @Ericson2314
|
||||
/pkgs/build-support/setup-hooks @Ericson2314
|
||||
|
77
pkgs/build-support/replace-vars/default.nix
Normal file
77
pkgs/build-support/replace-vars/default.nix
Normal file
@ -0,0 +1,77 @@
|
||||
{ lib, stdenvNoCC }:
|
||||
|
||||
/**
|
||||
`replaceVars` is a wrapper around the [bash function `substitute`](https://nixos.org/manual/nixpkgs/stable/#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)
|
||||
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.
|
||||
|
||||
# Inputs
|
||||
|
||||
`path` ([Store Path](https://nixos.org/manual/nix/latest/store/store-path.html#store-path) String)
|
||||
: 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).
|
||||
|
||||
# Example
|
||||
|
||||
```nix
|
||||
{ replaceVars }:
|
||||
|
||||
replaceVars ./greeting.txt { world = "hello"; }
|
||||
```
|
||||
|
||||
See `../../test/replace-vars/default.nix` for tests of this function.
|
||||
*/
|
||||
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)
|
||||
];
|
||||
|
||||
replacements = lib.concatLists (lib.mapAttrsToList subst-var-by attrs);
|
||||
in
|
||||
|
||||
stdenvNoCC.mkDerivation {
|
||||
name = baseNameOf (toString path);
|
||||
src = path;
|
||||
doCheck = true;
|
||||
dontUnpack = true;
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
substitute "$src" "$out" ${lib.concatStringsSep " " replacements}
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
# Look for Nix identifiers surrounded by `@` that aren't substituted.
|
||||
checkPhase =
|
||||
let
|
||||
regex = lib.escapeShellArg "@[a-zA-Z_][0-9A-Za-z_'-]*@";
|
||||
in
|
||||
''
|
||||
runHook preCheck
|
||||
if grep -qe ${regex} "$out"; then
|
||||
echo The following look like unsubstituted Nix identifiers that remain in "$out":
|
||||
grep -oe ${regex} "$out"
|
||||
echo Use the more precise '`substitute`' function if this check is in error.
|
||||
exit 1
|
||||
fi
|
||||
runHook postCheck
|
||||
'';
|
||||
}
|
@ -183,5 +183,7 @@ with pkgs;
|
||||
|
||||
systemd = callPackage ./systemd { };
|
||||
|
||||
replaceVars = recurseIntoAttrs (callPackage ./replace-vars { });
|
||||
|
||||
substitute = recurseIntoAttrs (callPackage ./substitute { });
|
||||
}
|
||||
|
74
pkgs/test/replace-vars/default.nix
Normal file
74
pkgs/test/replace-vars/default.nix
Normal file
@ -0,0 +1,74 @@
|
||||
{
|
||||
replaceVars,
|
||||
emptyDirectory,
|
||||
emptyFile,
|
||||
runCommand,
|
||||
testers,
|
||||
}:
|
||||
let
|
||||
inherit (testers) testEqualContents testBuildFailure;
|
||||
in
|
||||
{
|
||||
# Success case for `replaceVars`.
|
||||
replaceVars = testEqualContents {
|
||||
assertion = "replaceVars";
|
||||
actual = replaceVars ./source.txt {
|
||||
free = "free";
|
||||
"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 { }); }
|
||||
''
|
||||
grep -e "ERROR: file.*empty-directory.*does not exist" $failed/testBuildFailure.log
|
||||
touch $out
|
||||
'';
|
||||
|
||||
replaceVars-fails-in-build-phase =
|
||||
runCommand "replaceVars-fails"
|
||||
{ failed = testBuildFailure (replaceVars 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"
|
||||
{
|
||||
failed =
|
||||
let
|
||||
src = builtins.toFile "source.txt" ''
|
||||
Header.
|
||||
before @whatIsThis@ middle @It'sOdd2Me@ after.
|
||||
@cannot detect due to space@
|
||||
Trailer.
|
||||
'';
|
||||
in
|
||||
testBuildFailure (replaceVars src { });
|
||||
}
|
||||
''
|
||||
grep -e "unsubstituted Nix identifiers.*source.txt" $failed/testBuildFailure.log
|
||||
grep -F "@whatIsThis@" $failed/testBuildFailure.log
|
||||
grep -F "@It'sOdd2Me@" $failed/testBuildFailure.log
|
||||
grep -F 'more precise `substitute` function' $failed/testBuildFailure.log
|
||||
|
||||
# Shouldn't see irrelevant details.
|
||||
! grep -q -E -e "Header|before|middle|after|Trailer" $failed/testBuildFailure.log
|
||||
|
||||
# Shouldn't see the "cannot detect" version.
|
||||
! grep -q -F "cannot detect due to space" $failed/testBuildFailure.log
|
||||
|
||||
touch $out
|
||||
'';
|
||||
}
|
5
pkgs/test/replace-vars/source.txt
Normal file
5
pkgs/test/replace-vars/source.txt
Normal file
@ -0,0 +1,5 @@
|
||||
All human beings are born @free@ and @equal 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
|
@ -1335,6 +1335,8 @@ with pkgs;
|
||||
|
||||
replaceDependency = callPackage ../build-support/replace-dependency.nix { };
|
||||
|
||||
replaceVars = callPackage ../build-support/replace-vars { };
|
||||
|
||||
nukeReferences = callPackage ../build-support/nuke-references {
|
||||
inherit (darwin) signingUtils;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user