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

Search improvements for --file and --expr #7668

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

dramforever
Copy link
Contributor

@dramforever dramforever commented Jan 23, 2023

Motivation

The new nix search no longer works without flakes without some hacks. This PR fixes this so that this would work:

$ nix search --file '<nixpkgs>' '' hello-unfree

Still a slight mouthful, but now it's at least working as much as --file could.

Context

Discussed in: https://discourse.nixos.org/t/nix-search-broken/24447

A workaround is possible, which uses the special handling of legacyPackages to ignore evaluation errors, but it's pretty ugly and relies on a weird internal behavior:

$ nix search --impure --expr '{ legacyPackages.${builtins.currentSystem} = import <nixpkgs> {};}' '' hello-unfree

There are two main changes:

  • CmdSearch now recurses into recurseForDerivations = true if file || expr. For better error messages, top-level eval errors are not ignored.
  • InstallableAttrPath::getCursors now has a custom implementation that auto-calls the value and provides the full attribute path in the cursor (root->findAlongAttrPath so that is has a correct parent).

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

@@ -181,15 +181,21 @@ struct CmdSearch : InstallableCommand, MixJSON
else if (initialRecurse)
recurse();

else if (attrPathS[0] == "legacyPackages" && attrPath.size() > 2) {
else if (file || expr || (attrPathS[0] == "legacyPackages" && attrPath.size() > 2))
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
else if (file || expr || (attrPathS[0] == "legacyPackages" && attrPath.size() > 2))
else if (file || expr || (attrPath.size() > 2))

The "legacyPackages" restriction prevents ability to leverage the RecurseForDerivations logic in any other attribute path. This also helps match the behavior a few lines below, also removing the restriction.

Copy link
Contributor Author

@dramforever dramforever Jan 23, 2023

Choose a reason for hiding this comment

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

I'm not sure about flake installables, so I left the behavior as before.

(I think this also matches the behavior of nix flake show?)

@nixos-discourse
Copy link

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

https://discourse.nixos.org/t/nix-search-broken/24447/12

This means in commands like "nix search -f '<nixpkgs>'" the input is
treated like a 'legacyPackages' package set.
The 'nix search' command uses this function. Without this auto-calling
it will fail to find any packages.
@fricklerhandwerk
Copy link
Contributor

Triaged in the Nix team meeting:

We want to support the use case, and it's relevant for stabilising the new CLI. But the proposed solution is suboptimal. @Ericson2314 and @tomberek will propose an alternative approach and report back. Postponed until then.

Complete discussion
  • @thufschmitt: we want the fix since it relates to stabilising the CLI
  • @edolstra: the problem with this is that the syntax is nix search <flakeref> <search term> and it's not clear how it would fit with non-flakes search
    • the proposal uses a dummy argument, and that's really ugly
    • if someone comes up with an elegant way for taking singleton installables, we can adapt it
  • @tomberek: the implementation may not be what we want, but we agree that we want to support the use case
  • @Ericson2314, @tomberek: would like to propose a design
  • idea approved, postponed; @Ericson2314 and @tomberek will report back with a proposal

@fricklerhandwerk fricklerhandwerk added the idea approved The given proposal has been discussed and approved by the Nix team. An implementation is welcome. label Mar 3, 2023
@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-03-03-nix-team-meeting-minutes-37/25998/1

@dramforever
Copy link
Contributor Author

I'd like to clarify that the '' isn't really dummy, it's just 'search from root'. You can search any other sub-package-set with e.g. nix search --file '<nixpkgs>' python3Packages

@thufschmitt
Copy link
Member

@dramforever would . instead of '' work? That would probably make more explicit the fact that it's the path from the expression root and so make the command a bit more intuitive

@dramforever
Copy link
Contributor Author

. already works. Though I want to say it's a bit of a hack, since InstallableCommands defaults to ., which means 'current directory' for flakes, and it just seems to be hacked around for the --file/--expr case to mean 'root'. I couldn't remember where in the code it's done though.

A redesign would probably still be nice. In my fork-ish nix-dram I've had it changed to:

nix search [-i INSTALLABLE] <terms ...>

Though that's because nix-dram is based on a 'default flake' (see discussion in e.g. #4438), which -i can, well, default to.

@flickerfly
Copy link

I'm coping with this by using the following alias. Hopefully, that'll help those who, like me, are looking forward to this bug being fixed.

alias nixpkgs-search="nix --extra-experimental-features nix-command --extra-experimental-features flakes search nixpkgs"

@tejing1
Copy link

tejing1 commented Oct 29, 2023

I created a wrapper to implement the legacyPackages workaround, and never thought to link it here... but here it is, in case it's useful: https://github.com/tejing1/nix-search

@dramforever dramforever closed this Nov 6, 2023
@dramforever
Copy link
Contributor Author

(misclicked, sorry)

@tomberek
Copy link
Contributor

This is a problem to fix to make nix search usable in the non-flake case.

@dramforever would . instead of '' work? That would probably make more explicit the fact that it's the path from the expression root and so make the command a bit more intuitive

"." is better than the empty string, it is still not particularly appealing for general usage.

we had said this above, but I'm not clear on a good design yet, see below

if someone comes up with an elegant way for taking singleton installables, we can adapt it

The contention is this part of the installables semantics:

Options that change the interpretation of installables:

      · --expr expr
        
        Interpret installables as attribute paths relative to the Nix expression expr.
    
      · --file / -f file
        
        Interpret installables as attribute paths relative to the Nix expression stored in file. If file is
        the character -, then a Nix expression will be read from standard input. Implies --impure.

brainstorming:

  • nix search -f '<nixpkgs>' something is the desired syntax?
  • but now it becomes harder to say nix search -f '<nixpkgs>' inside-this-attr something'

This would require logic for file&&expr to be detected earlier than when the search results are processed. @dramforever this would mean I'd expect conditionals in installable.cc for this case.

conclusion

this PR seems to be a step in the right direction, supporting both "" and "." to make the workaround better.

Copy link
Contributor

@tomberek tomberek left a comment

Choose a reason for hiding this comment

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

  • needs a rebase
  • confirmation about what behavior is affected
  • Tests look good (though may need more if other behavior is affected, or to detect it)
  • release notes
  • docs

@@ -505,6 +505,26 @@ struct InstallableAttrPath : InstallableValue

return res;
}

std::vector<ref<eval_cache::AttrCursor>> getCursors(EvalState &state) override
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't know if the getCursors change will impact other commands, i suspect it would now do an autoCall where before it didn't. It might be desirable to do so, but it is not clear how much behavior this is overriding.

@tomberek
Copy link
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 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.

8 participants