-
-
Notifications
You must be signed in to change notification settings - Fork 14.7k
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
buildEnv: ignore empty paths
derivations containing an empty file
#325140
Conversation
ad12585
to
c5bcaea
Compare
Add the 'checkWithoutStandalone' packge, which is a lightweight 'nix flake check' alternative without 'inputs.self.checks.<SYSTEM>.standalone-<OPTION>-<VALUE>' checks. Due to 'pkgs.buildEnv' limitations, the 'checkWithoutStandalone' package excludes the 'preCommitHooks' derivation. Once [1] is merged, it should be possible to include the 'preCommitHooks' derivation. [1]: NixOS/nixpkgs#325140
'pkgs.buildEnv' fails with 'paths' derivations containing an empty file: pkgs.buildEnv { name = "touch"; paths = [ (pkgs.stdenvNoCC.mkDerivation { installPhase = ''touch "$out"''; name = "touch"; src = ./.; }) ]; } For convenience, 'paths' derivations containing an empty file should be ignored, avoiding workarounds like replacing 'touch $out' with 'mkdir $out'. This change makes the following command work: nix \ build \ --expr " let pkgs = import <nixpkgs> {}; in pkgs.buildEnv { name = ''touch''; paths = [ (pkgs.stdenvNoCC.mkDerivation { installPhase = ''touch \$out''; name = ''touch''; src = ./.; }) ]; } " \ --impure
c5bcaea
to
9f3e288
Compare
I'm not sure I like this: Ignoring certain files (i.e. empty ones) for convenience seems like too much magic to me. Is it really that painful to replace |
Currently, This is a design inconsistency. Either all empty derivations should be rejected with an error or consistently treated as identity elements. Intuitively, all empty derivations should be treated as identity elements. For reference, both
Considering that For reference, Nixpkgs extensively uses $ git checkout --quiet ed0fe13cc637546cad8c3ee903a23459b59f5080 &&
rg 'touch (\$out|"\$out")($|[^/])' | wc --lines
301 |
I think this is where we disagree: I think it's unintuitive to put a file into a builder that's supposed to operate on directories. And making a distinction between whether a file is empty (you can put it in there) and non-empty (you can't) really seems like a good candidate for another Nix quirk. I mean, the difference to directories is: you can put non-empty directories in there, but you can't do the same with files.
Yes. |
Yes.
Indeed. Maybe Nix should promote shifting the best practice from
This PR aims to "simplify" potential Either way, you are understandably skeptical of this proposal. Unless you expect your stance to change, feel free to close this PR. Or should we Thanks for all the insightful feedback. |
I don't have such a strong opinion about that since those are mostly testing derivations, i.e. these run a bunch of tests and the OTOH I've heard the opinion that the store should allow directories only in the first place. Anyways, if we go down that route this should be a conscious decision, so nothing that should contributors should be asked to do in random PR reviews.
I'm afraid I don't.
The thing is,
Sure, you're welcome :) |
Passing a git-hooks.lib.<SYSTEM>.run derivation as a path to pkgs.buildEnv results in the following error due to derivations with an empty file being treated differently from derivations with an empty directory: The store path <TARGET> is a file and can't be merged into an environment using pkgs.buildEnv! Since Nixpkgs rejected explicitly handling derivations with an empty file in pkgs.buildEnv [1], affected derivations should transition from 'touch $out' to 'mkdir $out' to be pkgs.buildEnv composable. This change replaces 'touch $out' with 'mkdir $out' and makes the following command work: nix \ build \ --expr ' let flake = builtins.getFlake (toString ./.); system = builtins.currentSystem; in flake.inputs.nixpkgs.legacyPackages.${system}.buildEnv { name = ""; paths = [(flake.outputs.lib.${system}.run {src = ./.;})]; } ' \ --impure [1]: NixOS/nixpkgs#325140
Passing a git-hooks.lib.<SYSTEM>.run derivation as a path to pkgs.buildEnv results in the following error due to derivations with an empty file being treated differently from derivations with an empty directory: The store path <TARGET> is a file and can't be merged into an environment using pkgs.buildEnv! Since Nixpkgs rejected explicitly handling derivations with an empty file in pkgs.buildEnv [1], affected derivations should transition from 'touch $out' to 'mkdir $out' to be pkgs.buildEnv composable. This change replaces 'touch $out' with 'mkdir $out' and makes the following command work: nix \ build \ --expr ' let flake = builtins.getFlake (toString ./.); system = builtins.currentSystem; in flake.inputs.nixpkgs.legacyPackages.${system}.buildEnv { name = ""; paths = [(flake.outputs.lib.${system}.run {src = ./.;})]; } ' \ --impure [1]: NixOS/nixpkgs#325140 Link: cachix#498
Description of changes
pkgs.buildEnv
fails withpaths
derivations containing an empty file:The lacking
$out
directory causespkgs.buildEnv
to fail due to:nixpkgs/pkgs/build-support/buildenv/builder.pl
Lines 120 to 123 in b6bcda5
For convenience,
paths
derivations containing an empty file should be ignored, avoiding workarounds like replacingtouch $out
withmkdir $out
.For example, git-hooks.nix'
run
derivation runs pre-commit hooks and fails accordingly, while includingtouch $out
merely to satisfy Nix derivation requirements:https://github.com/cachix/git-hooks.nix/blob/0ff4381bbb8f7a52ca4a851660fc7a437a4c6e07/modules/pre-commit.nix#L55-L82
Essentially, the following happens:
The following minimal working example demonstrates the issue before and after this PR:
The following output should be produced:
For reference, this PR follows up on #56085 and #134215.
Things done
nix.conf
? (See Nix manual)sandbox = relaxed
sandbox = true
nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"
. Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/
)Add a 👍 reaction to pull requests you find important.