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

Get rid of .drv special-casing for store path installable #7600

Merged
merged 1 commit into from
Feb 28, 2023

Conversation

Ericson2314
Copy link
Member

@Ericson2314 Ericson2314 commented Jan 14, 2023

We no longer treat a store path different based on whether it ends in .drv.

To quote the release notes:

In light of the new ^ syntax for store paths allowing one to be fully explicit, stop special-casing whether a store path in an installable ends in .drv.

For example,

$ nix path-info /nix/store/gzaflydcr6sb3567hap9q6srzx8ggdgg-glibc-2.33-78.drv

gives info about the derivation itself, while

$ nix path-info /nix/store/gzaflydcr6sb3567hap9q6srzx8ggdgg-glibc-2.33-78.drv^*

gives info about each of its outputs.

Motivation

Plumbing CLI should be simple

Store derivation installations are intended as "plumbing": very simple utilities for advanced users and scripts, and not what regular users interact with. (Similarly, regular Git users will use branch and tag names not explicit hashes for most things.)

The plumbing CLI should prize simplicity over convenience; that is its raison d'etre. If the user provides a path, we should treat it the same way not caring what sort of path it is.

Scripting

This is especially important for the scripting use-case. when arbitrary paths are sent to e.g. nix copy and the script author wants consistent behavior regardless of what those store paths are. Otherwise the script author needs to be careful to filter out .drv ones, and then run nix copy again with those paths and --derivation. That is not good!

Surprisingly low impact

Only two lines in the tests need changing, showing that the impact of this is pretty light.

Many command, like nix log will continue to work with just the derivation passed as before. This because we used to:

  • Special case the drv path and replace it with it's outputs (what this gets rid of).
  • Turn those output path back into the original drv path.

Now we just skip that entire round trip!

Context

Issue #7261 lays out a broader vision for getting rid of --derivation, and has this as one of its dependencies. But we can do this with or without that.

Installable::toDerivations is changed to handle the case of a DerivedPath::Opaque ending in .drv, which is new: it simply doesn't need to do any extra work in that case. On this basis, commands like nix {show-derivation,log} /nix/store/...-foo.drv still work as before, as described above.

When testing older daemons, the post-build-hook will be run against the old CLI, so we need the old version of the post-build-hook to support that use-case.

Checklist for maintainers

Maintainers: tick if completed or explain if not relevant

  • agreed on idea
  • agreed on implementation strategy
  • tests, as appropriate
    • functional tests - tests/**.sh
    • unit tests - src/*/tests
    • integration tests
  • documentation in the manual
  • code and comments are self-explanatory
  • commit message explains why the change was made
  • new feature or bug fix: updated release notes

See the change log for user-facing details.

Only two lines in the tests need changing, showing that the impact of this is pretty light.

Progress towards #7261

doc/manual/src/release-notes/rl-next.md Outdated Show resolved Hide resolved
doc/manual/src/release-notes/rl-next.md Outdated Show resolved Hide resolved
Comment on lines +1044 to +682
bo.path.isDerivation()
? bo.path
Copy link
Member Author

Choose a reason for hiding this comment

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

This allows nix show-derivation /nix/store/asdfasdfasdf-foo.drv to work. It would be silly to require ^* for that!

If we do end up doing all of #7261, I am pretty sure the useDriver flag, and possibly this entire function, will disappear altogether.

@edolstra
Copy link
Member

Arguably this creates an inconsistency between store derivations and expressions that evaluate to a derivation. E.g.

nix path-info nixpkgs#hello

operates on the default outputs of nixpkgs#hello, not the .drv file. For the latter you have to specify --derivation.

@Ericson2314
Copy link
Member Author

Ericson2314 commented Jan 16, 2023

@edolstra I get at some of those ideas in #7261, and @roberth also does in #6507. There are some philosophical things to unpack. #7417 also relates in that nixpkgs#hello.drvPath could now work.

@roberth
Copy link
Member

roberth commented Jan 16, 2023

This highlights the importance of being explicit about store level derivations and the expression-level "derivations" (which I propose to call packages instead, #6507).

@Ericson2314 Ericson2314 changed the title Get rid of legacy hack for store path installables Get rid of .drv special-casing for store path installable Jan 20, 2023
@Ericson2314 Ericson2314 marked this pull request as draft January 20, 2023 15:09
Comment on lines 824 to 832
if (storePath.isDerivation()) {
auto oldDerivedPath = DerivedPath::Built {
.drvPath = storePath,
.outputs = OutputsSpec::All { },
};
warn(
"The interpretation of store paths arguments ending in `.drv` recently changed. If this command is now failing try again with '%s'",
oldDerivedPath.to_string(*store));
};
Copy link
Member Author

Choose a reason for hiding this comment

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

@thufschmitt says mention --derivation too

@roberth
Copy link
Member

roberth commented Jan 23, 2023

A possible resolution for the nix build verb expectation issue:

  • Add nix produce <installable> which does not necessarily build (the same way nix copy doesn't)
  • Change nix build to build the thing it gets from the installable. If the installable produces outputs, realise those; if it produces a drv, realise its outputs.

@fricklerhandwerk
Copy link
Contributor

Discussed in the Nix team meeting 2023-01-20:

  • @regnat: agree we should have it eventually, but this is too radical
    • should start with a warning
    • @Ericson2314: against of another cycle, would like to have this functionality before any of the related commands are stable
  • to be discussed further by the team

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/2023-01-20-nix-team-meeting-minutes-25/25432/1

@fricklerhandwerk
Copy link
Contributor

Discussed in the Nix team meeting 2023-01-23:

  • Change in behavior
    • Currently has a warning telling that the behavior changed
    • But doesn't give people a grace period to do the change more incrementally
      • Maybe we could advise for using --derivation for now or switch to the ^* syntax
    • @edolstra: Inconsistency between passing in the drv path and an higher-level installable (nix build nixpkgs#hello will behave differently than nix build /nix/store/...-hello.drv)
      • @Ericson2314: Not really inconsitent. It's fine to consider these as different things: the .drv is a file while the result of the evaluation is a derivation value
  • Digression: Should we rename nix build to make it more intuitive with the new behavior?
    • nix build ...-foo.drv doesn't build anything
    • Maybe should be called nix get instead
      • And also have a nix build command that forcibly builds stuff
    • Some commands want to act on the store path (nix copy), others directly on the output paths (nix build, nix profile install)
  • no decision

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/2023-01-23-nix-team-meeting-minutes-26/25433/1

@fricklerhandwerk fricklerhandwerk added the new-cli Relating to the "nix" command label Feb 27, 2023
@thufschmitt thufschmitt added the idea approved The given proposal has been discussed and approved by the Nix team. An implementation is welcome. label Feb 27, 2023
doc/manual/src/release-notes/rl-next.md Outdated Show resolved Hide resolved
doc/manual/src/release-notes/rl-next.md Outdated Show resolved Hide resolved
doc/manual/src/release-notes/rl-next.md Outdated Show resolved Hide resolved
@fricklerhandwerk
Copy link
Contributor

Discussed in the Nix team meeting 2022-02-27:

  • Didn't reach an agreement before
    • Broad agreement on that we want the new explicit syntax to take over eventually
    • Contention on how to pull off a smooth transition
  • alternatives:
    • don't change the behavior but issue a warning
    • change the behavior and add a warning that it changed
      • warning recommends to use --derivation although it will ultimately go away
      • eventually --derivation is a no-op
  • @thufschmitt: probably people use this in scripts calling path-info on many derivations, and in that case I wouldn't want to flood them with warnings
  • @fricklerhandwerk: it's experimental, we can just break the behavior
    • @tomberek: it gets us to the end state quicker
      • adding a warning is a concession to existing users of experimental features
      • @fricklerhandwerk: the after-the-fact-warning sounds like interactive release notes. why not put it in the release notes?
    • @Ericson2314: we have been encouraging people to use experimental features in the past, and that was probably a mistake. but those who followed the advice should not pay for our mistakes, so in this case it is sensible to make smaller steps
  • agreed on implementation
  • @fricklerhandwerk will fix up release notes and merge once tests pass

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/2023-02-27-nix-team-meeting-minutes-36/25890/1

@Ericson2314 Ericson2314 marked this pull request as ready for review February 28, 2023 18:32
@Ericson2314 Ericson2314 force-pushed the explicit-drv-ness branch 2 times, most recently from 6001b3d to b263aae Compare February 28, 2023 21:05
The release notes document the change in behavior, I don't include it
here so there is no risk to it getting out of sync.

> Motivation

>> Plumbing CLI should be simple

Store derivation installations are intended as "plumbing": very simple
utilities for advanced users and scripts, and not what regular users
interact with. (Similarly, regular Git users will use branch and tag
names not explicit hashes for most things.)

The plumbing CLI should prize simplicity over convenience; that is its
raison d'etre. If the user provides a path, we should treat it the same
way not caring what sort of path it is.

>> Scripting

This is especially important for the scripting use-case. when arbitrary
paths are sent to e.g. `nix copy` and the script author wants consistent
behavior regardless of what those store paths are. Otherwise the script
author needs to be careful to filter out `.drv` ones, and then run `nix
copy` again with those paths and `--derivation`. That is not good!

>> Surprisingly low impact

Only two lines in the tests need changing, showing that the impact of
this is pretty light.

Many command, like `nix log` will continue to work with just the
derivation passed as before. This because we used to:

- Special case the drv path and replace it with it's outputs (what this
  gets rid of).

- Turn those output path *back* into the original drv path.

Now we just skip that entire round trip!

> Context

Issue NixOS#7261 lays out a broader vision for getting rid of `--derivation`,
and has this as one of its dependencies. But we can do this with or
without that.

`Installable::toDerivations` is changed to handle the case of a
`DerivedPath::Opaque` ending in `.drv`, which is new: it simply doesn't
need to do any extra work in that case. On this basis, commands like
`nix {show-derivation,log} /nix/store/...-foo.drv` still work as before,
as described above.

When testing older daemons, the post-build-hook will be run against the
old CLI, so we need the old version of the post-build-hook to support
that use-case.

Co-authored-by: Travis A. Everett <travis.a.everett@gmail.com>
Co-authored-by: Valentin Gagarin <valentin.gagarin@tweag.io>
@cole-h
Copy link
Member

cole-h commented Mar 20, 2023

Hi, what is the right way to use e.g. nix path-info on a .drv file now? --derivation is apparently bad and will go away eventually, so I don't want to reach for that, but the !* suggestion from the daemon does not work for me (nor the ^* suggestion as documented in this PR).

$ nix-env --version
nix-env (Nix) 2.15.0pre20230320_1de5b0e

$ nix build nixpkgs#hello && realpath ./result
/nix/store/v02pl5dhayp8jnz8ahdvg5vi71s8xc6g-hello-2.12.1

$ nix path-info -r /nix/store/v02pl5dhayp8jnz8ahdvg5vi71s8xc6g-hello-2.12.1
/nix/store/qmnr18aqd08zdkhka695ici96k6nzirv-libunistring-1.0
/nix/store/vv6rlzln7vhxk519rdsrzmhhlpyb5q2m-libidn2-2.3.2
/nix/store/76l4v99sk83ylfwkz8wmwrm4s8h73rhd-glibc-2.35-224
/nix/store/v02pl5dhayp8jnz8ahdvg5vi71s8xc6g-hello-2.12.1

$ nix-store --query --deriver /nix/store/v02pl5dhayp8jnz8ahdvg5vi71s8xc6g-hello-2.12.1
/nix/store/25i5yk3xxr0g54rab62jfmi2hpmcapiw-hello-2.12.1.drv

$ nix path-info -r /nix/store/25i5yk3xxr0g54rab62jfmi2hpmcapiw-hello-2.12.1.drv
warning: The interpretation of store paths arguments ending in `.drv` recently changed. If this command is now failing try again with '/nix/store/25i5yk3xxr0g54rab62jfmi2hpmcapiw-hello-2.12.1.drv!*'
don't know how to build these paths:
  /nix/store/25i5yk3xxr0g54rab62jfmi2hpmcapiw-hello-2.12.1.drv
error: path '/nix/store/25i5yk3xxr0g54rab62jfmi2hpmcapiw-hello-2.12.1.drv' is not valid

$ nix path-info -r '/nix/store/25i5yk3xxr0g54rab62jfmi2hpmcapiw-hello-2.12.1.drv!*'
path '/nix/store/25i5yk3xxr0g54rab62jfmi2hpmcapiw-hello-2.12.1.drv!*' does not contain a 'flake.nix', searching up
error: getting status of '/nix/store/25i5yk3xxr0g54rab62jfmi2hpmcapiw-hello-2.12.1.drv!*': No such file or directory

$ nix path-info -r '/nix/store/25i5yk3xxr0g54rab62jfmi2hpmcapiw-hello-2.12.1.drv^*'
don't know how to build these paths:
  /nix/store/25i5yk3xxr0g54rab62jfmi2hpmcapiw-hello-2.12.1.drv
error: path '/nix/store/25i5yk3xxr0g54rab62jfmi2hpmcapiw-hello-2.12.1.drv' is not a valid store path

$ nix path-info --derivation -r /nix/store/v02pl5dhayp8jnz8ahdvg5vi71s8xc6g-hello-2.12.1 | head
/nix/store/001gp43bjqzx60cg345n2slzg7131za8-nix-nss-open-files.patch
/nix/store/01n3wxxw29wj2pkjqimmmjzv7pihzmd7-which-2.21.tar.gz.drv
/nix/store/1qrnbw8xsww3vydd71lwfp32ylgx9i8g-make-wrapper.sh
/nix/store/6xg259477c90a229xwmb53pdfkn6ig3g-default-builder.sh
/nix/store/819fzxfwzp7zhhi4wy5nkapimkb1bsx5-die.sh
/nix/store/5yzw0vhkyszf2d179m0qfkgxmp5wjjx4-move-docs.sh
/nix/store/cickvswrvann041nqxb0rxilc46svw1n-prune-libtool-files.sh
/nix/store/ckzrg0f0bdyx8rf703nc61r3hz5yys9q-builder.sh
/nix/store/d0vsy7cjz9d5vzrndl8962pqq0mv02s3-patch-shebangs.sh
/nix/store/d275wzmimzi3xp4j3vbkvxscmc79q088-strip.sh

That last command (with --derivation) has the information I was looking for, but I don't want to rely on it because it will eventually go away. Is this just pending work to bring parity between nix path-info -r --derivation /nix/store/aaaaa-hello and nix path-info -r /nix/store/ddd-hello.drv?

@Ericson2314
Copy link
Member Author

@cole-h you seem to be witnessing some sort of bug. Is the drv path actually invalid? Is there some sort of eval store or other such thing going on?

@cole-h
Copy link
Member

cole-h commented Mar 20, 2023

Well, the drv path doesn't exist on my machine, and I can't seem to fetch it with nix-store -r /nix/store/25i5yk3xxr0g54rab62jfmi2hpmcapiw-hello-2.12.1.drv, so I guess that might mean it's invalid? It's strange that nix path-info --derivation works just fine though.

No eval store or any other funk. The most "strange" my setup is, is that I enable the flakes and nix-command features.

I only posted here in case I was just holding it wrong, but it might be more valuable to move this to an issue if that is not the case.

@raphaelr
Copy link
Contributor

I think the !* syntax that's suggested by the new warning message should be a ^* instead, because nix build /nix/store/whatever.drv!* fails:

$ nix --version
nix (Nix) 2.16.0pre20230411_ef0b483
$ mkdir tmpstore

$ nix eval nixpkgs#hello.drvPath --store ./tmpstore/
"/nix/store/42ipbdz8z12ax0aqchv0rmsy2qb5wi1i-hello-2.12.1.drv"

$ nix build --print-out-paths '/nix/store/42ipbdz8z12ax0aqchv0rmsy2qb5wi1i-hello-2.12.1.drv' --store ./tmpstore/
warning: The interpretation of store paths arguments ending in `.drv` recently changed. If this command is now failing
try again with '/nix/store/42ipbdz8z12ax0aqchv0rmsy2qb5wi1i-hello-2.12.1.drv!*'
/nix/store/42ipbdz8z12ax0aqchv0rmsy2qb5wi1i-hello-2.12.1.drv

$ nix build --print-out-paths '/nix/store/42ipbdz8z12ax0aqchv0rmsy2qb5wi1i-hello-2.12.1.drv!*' --store ./tmpstore/
path '/nix/store/42ipbdz8z12ax0aqchv0rmsy2qb5wi1i-hello-2.12.1.drv!*' does not contain a 'flake.nix', searching up
error: getting status of '/nix/store/42ipbdz8z12ax0aqchv0rmsy2qb5wi1i-hello-2.12.1.drv!*': No such file or directory

$ nix build --print-out-paths '/nix/store/42ipbdz8z12ax0aqchv0rmsy2qb5wi1i-hello-2.12.1.drv^*' --store ./tmpstore/
/nix/store/cfbhfgvn525zg8var9fr67wvmg2z5szl-hello-2.12.1

nix is from github:nixos/nix/ef0b48377d0fc79d70455c402ed4df4b18cb93dd (but I also reproduced this on 2.15.0), and nixpkgs is github:nixos/nixpkgs/ea96b4af6148114421fda90df33cf236ff5ecf1d.

@fricklerhandwerk
Copy link
Contributor

@raphaelr fixing this would be a great first contribution. Feel free to ping me in a PR or on Matrix if you get stuck. We're trying to make onboarding easier, and both the fix and feedback on the process are highly appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
idea approved The given proposal has been discussed and approved by the Nix team. An implementation is welcome. new-cli Relating to the "nix" command
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

9 participants