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

Nix 2.0: Print out path to stdout with nix build #1930

Closed
ElvishJerricco opened this issue Feb 28, 2018 · 23 comments · Fixed by #4182
Closed

Nix 2.0: Print out path to stdout with nix build #1930

ElvishJerricco opened this issue Feb 28, 2018 · 23 comments · Fixed by #4182
Assignees
Labels
new-cli Relating to the "nix" command

Comments

@ElvishJerricco
Copy link
Contributor

This served as an extremely useful tool with nix-build in conjunction with --no-out-link. Two extremely common use cases:

  • $(nix-build ...)/bin/foo
  • nix-store -qR $(nix-build ...)

It's just nice to interpolate the path without having to copy paste it, and to make sure that the command you're running definitely has the latest version of the nix build output. It would be nice to have this back with nix build.

@ElvishJerricco
Copy link
Contributor Author

Trying to script around this doesn't seem viable because of GC roots. You can't isolate what the outputs of nix build were without putting them in an isolated temp dir, or else you can't know if result-100 was from this build or a previous one. And if you put them there, then moving them where the user wanted will leave dangling symlinks in the GC roots. This is technically fine, but writing a script that inherently leaves behind unwanted dangling symlinks sounds bad.

@dtzWill
Copy link
Member

dtzWill commented Mar 1, 2018

Technically speaking I think the pattern nix-store -qR $(nix-build ...) was always slightly broken in that once the nix-build command prints out the path and exits the path could be GC'd before nix-store parses its arguments and locks the path or whatever it does.

It's not a problem if you can be sure a GC isn't running concurrently or something, but just a thought.

Couldn't the "moving them where the user wanted" be done with nix-store --add-root $newlocation --indirect /nix/store/path? Not sure I understand what you're doing re:users though :).

@ElvishJerricco
Copy link
Contributor Author

ElvishJerricco commented Mar 1, 2018

Couldn't the "moving them where the user wanted" be done with nix-store --add-root $newlocation --indirect /nix/store/path?

@dtzWill This would still leave dangling symlinks in your gc roots (EDIT: from the symlinks in the isolated temp directory). Again, not technically a problem, but definitely undesirable to have a command be guaranteed to leave behind unwanted symlinks.

@viric
Copy link
Member

viric commented Mar 2, 2018

I'm with @ElvishJerricco; I used the stdout a lot. Even "nix build --no-link" does not output anything, so no reference at all to the outcome.

If someone wants to make the $(nix-build ) thing GC-safe, that can use a mktemp as symlink and then delete it. Annoying to impose this, though.

@ElvishJerricco
Copy link
Contributor Author

@viric I did figure out how to make such a thing, but it uses nix-store --delete (no argument) to wipe all hanging symlinks. I'd prefer to only wipe the ones created by the command, but this is somewhat reasonable.

https://gist.github.com/ElvishJerricco/e8193a5b4734877bc492e870625bc92f

@shlevy
Copy link
Member

shlevy commented Mar 2, 2018

Re GC-safety: #1938

@ElvishJerricco
Copy link
Contributor Author

ElvishJerricco commented Mar 2, 2018

@shlevy Thanks for that. To be clear though, I don't think a wrapper script is a good solution to this issue. It'd be far easier if nix build just output the paths. It seems really odd to me that nix build --no-link would just produce no usable output.

Maybe paths should only be output if --no-link is specified?

@shlevy
Copy link
Member

shlevy commented Mar 2, 2018

@ElvishJerricco This doesn't address the output path issue, just the GC safety issue that you have even with nix-build --no-out-link

@teto
Copy link
Member

teto commented Mar 6, 2018

sry if that's a bit but offtrack but what to do with multiple outputs ? I wished for nix-build to display all the built output paths but it only displays the first outputs = [ "dev" "out" "lib" ]; will display "$dev". It seems a bit brittle. Also nix-build will only create ./result-dev, I would expect ./result-lib to be created too.

@dtzWill
Copy link
Member

dtzWill commented Mar 6, 2018

@ElvishJerricco try building "foo.all" instead of "foo"! I use this often :).

@ElvishJerricco
Copy link
Contributor Author

@dtzWill Did you mean to mention @teto?

@dtzWill
Copy link
Member

dtzWill commented Mar 6, 2018

@dtzWill Did you mean to mention @teto?

Yes! Haha sorry about that.

@vcunat vcunat added the new-cli Relating to the "nix" command label Mar 8, 2018
@7c6f434c
Copy link
Member

7c6f434c commented Mar 9, 2018

Printing a link to stdout is very useful for simple (and maybe even single-use) interactive scripts where it is assumed that the user knows there is no GC running…

By the way, nix build applied to a .drv doesn't seem to create the result link by default, either (which is natural as it inherits behaviour from nix-store), so even with no extra flags there are cases where nix build doesn't produce anything pointing to the output.

@shlevy shlevy added the backlog label Apr 1, 2018
@shlevy shlevy self-assigned this Apr 1, 2018
@ghost
Copy link

ghost commented Apr 1, 2018

Related: #1647

@ElvishJerricco
Copy link
Contributor Author

What about -o -? Other command line tools often use - to represent stdin and stdout. Seems fitting in this case to use -o - to mean "Don't make symlinks; just print on stdout."

@ElvishJerricco
Copy link
Contributor Author

Of course, it'd be good to be able to do both...

@michaelpj
Copy link

This also prevents nixos-rebuild using nix 2.0 commands, since it relies quite a bit on getting the result path on stdout.

@ElvishJerricco
Copy link
Contributor Author

@michaelpj you could place out links in a tmp directory and readlink them.

@ElvishJerricco
Copy link
Contributor Author

If you only care about getting stuff on stdout, and not the out links, path-info enables a pretty simple wrapper:

nbuild() {
  nix build --no-link "$@"
  nix path-info "$@"
}

Of course this evaluates expressions twice as many times....

@ElvishJerricco
Copy link
Contributor Author

Is #2423 all we need, or do we want to change the default? Personally, I'm only ever using the symlink or the stdout, not both, so #2423 is enough for me.

@michaelpj
Copy link

It seems a bit weird to link it to the out-link flag - they seem orthogonal to me.

@7c6f434c
Copy link
Member

Theoretically orthogonal, but they are two possible answers to «how do you want to get the result», so wanting a single one (either of the two) is way more typical than both or neither

@domenkozar
Copy link
Member

See #2622

mkenigs added a commit to mkenigs/nix that referenced this issue Oct 23, 2020
Add --json option to nix build to allow machine readable output on
stdout with all built derivations

Fixes NixOS#1930
mkenigs added a commit to mkenigs/nix that referenced this issue Nov 10, 2020
Add --json option to nix build to allow machine readable output on
stdout with all built derivations

Fixes NixOS#1930
mkenigs added a commit to mkenigs/nix that referenced this issue Nov 11, 2020
Add --json option to nix build to allow machine readable output on
stdout with all built derivations

Fixes NixOS#1930
mkenigs added a commit to mkenigs/nix that referenced this issue Nov 11, 2020
Add --json option to nix build to allow machine readable output on
stdout with all built derivations

Fixes NixOS#1930
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new-cli Relating to the "nix" command
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants