Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

substitute-all.nix: Define in terms of the substitute bash function #238636

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 47 additions & 7 deletions pkgs/build-support/substitute/substitute-all.nix
Original file line number Diff line number Diff line change
@@ -1,12 +1,52 @@
{ stdenvNoCC }:
{ lib
, stdenvNoCC
}:

args:
/*
Replaces all occurrences of `@varName@` in `src`, where `varName` is an
attribute passed to the `substituteAll` Nix function, writing the result to a
file in the Nix store.

# see the substituteAll in the nixpkgs documentation for usage and constaints
stdenvNoCC.mkDerivation ({
name = if args ? name then args.name else baseNameOf (toString args.src);
Example:

# Writes a text file to the Nix store with contents "Hello, World!"
substituteAll {
src = builtins.toFile "greeting.txt" "Hello, @subject@!";
subject = "World";
}
*/
{ src
, name ? baseNameOf (toString src)
, dir ? null
, isExecutable ? false
, preInstall ? null
, postInstall ? null
, passthru ? { }
, meta ? { }
# The remaining arguments are the variables to replace.
, ...
}@args:

let
variables = builtins.removeAttrs args [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removeAttrs is still kinda terrible.
It'd be nicer to first have a function that does the right thing for all possible key value combinations, and then define substituteAll in terms of that function for compatibility.

The interface could be something like this when called

substituteStrings {
  nativeBuildInputs = [ foolint ];
  checkPhase = ''
    runHook preCheck;
    barlint $out;
    runHook postCheck;
  '';
  replacements = {
    "@foo@" = lib.getExe foo;
  };
};

(note that I'm also making the @s explicit for better grepping)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The above could be done with --replace and escapeShellArg I think.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My 2c: I think we could have a new interface but at the same time having a better substituteAll that does what it is supposed to do would be much better.

"name" "src" "dir" "isExecutable" "preInstall" "postInstall"
"passthru" "meta"
];

# { cat = "meow"; dog = "woof"; } -> [ "--subst-var-by" "cat" "meow" "--subst-var-by" "dog" "woof" ]
substitutions = lib.foldlAttrs
(acc: variable: replacement: acc ++ [ "--subst-var-by" variable replacement ])
[]
variables;
in

stdenvNoCC.mkDerivation {
builder = ./substitute-all.sh;
inherit (args) src;
inherit name src dir isExecutable preInstall postInstall passthru meta;

substitutions = lib.toShellVar "substitutions" substitutions;
passAsFile = [ "substitutions" ];

preferLocalBuild = true;
allowSubstitutes = false;
} // args)
}
3 changes: 2 additions & 1 deletion pkgs/build-support/substitute/substitute-all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ if test -n "$dir"; then
mkdir -p $out/$dir
fi

substituteAll $src $target
source "$substitutionsPath"
substitute $src $target "${substitutions[@]}"

if test -n "$isExecutable"; then
chmod +x $target
Expand Down