Open
Description
As stated below, I don’t think this can be solved in a reasonable way. I’m just logging it here for reference
Describe the bug
If foo
is a content-addressed derivation (or depends on one), with /nix/store/abc-foo
as output path, then builtins.replaceStrings ["-"] ["+"] foo.outPath
will be /nix/store/abc-foo
rather than /nix/store/abc+foo
.
This is because as far as the Nix evaluator is concerned, foo.outPath
is a placeholder of the form /123
rather than the actual /nix/store/abc-foo
. So the Nix evaluator actually runs builtins.replaceStrings ["-"] ["+"] /123
(which is equal to /123
).
Steps To Reproduce
With a default.nix
like:
{ ca ? false }:
with import <nixpkgs> {};
let
foo = runCommand "foo" { __contentAddressed = ca; } "echo foo > $out";
in
runCommand "bar" {} ''
set -x
[[ "${builtins.replaceStrings ["-"] ["+"] foo.outPath}" != ${foo.outPath} ]] || exit 1
touch $out
''
$ nix-build default.nix
# Succeeds
$ nix-build default.nix --arg ca true
# Fails
The same derivation
Expected behavior
Both derivations should build successfully
Additional context
- I encountered this in “real-life”:
openjfx15
has a snippet of the formThis doesn’t do what it’s supposed to do whenblah | sed 's,${lib.escape ["+"] openjdk11_headless.outPath},,'
openjdk11_headless
is content-addressed (because its output path contains a+
, which isn’t properly escaped and thus is interpreted by sed as a regex meta-character rather than a litteral+
) - This can also break the dependency rewriting: Assuming a
baseName
Nix function,baseName foo.outPath
will return123
, which won’t be replaced by/nix/store/abc-foo
at build-time - All that being said, I don’t think there’s much that can be done about that (except rewriting half on Nix to make the evaluation way lazier than what it is now, but even regardless of the amount of work involved I doubt that’d be a good idea). But It’s worth keeping this issue around − even as a “wontfix”, at least for reference.
Activity