NixOS/nix

Improve flakes installables ergonomics, avoid nixpkgs# part?

dramforever opened this issue ยท 23 comments

Is your feature request related to a problem? Please describe.

It's kind of annoying to keep typing nixpkgs# over and over in situations like:

$ nix shell nixpkgs#wireshark
$ nix run nixpkgs#peek

Especially considering that # is kinda hard to type.

Describe the solution you'd like

I feel like this should just work:

$ nix shell wireshark
$ nix run peek

To achieve this, I'm thinking about this scheme:

  • If an INSTALLABLE does not contain either : or # looks like an attribute name like foo.bar.baz, resolve it to some default flake, like either flake:default#foo.bar.baz or flake:nixpkgs#foo.bar.baz
  • Otherwise treat it as we do now

I'm not sure if this is the intention, but I think I am going to use stuff under nixpkgs# far more than the various other flakes. When we do need other flakes, just put a # after the flake name, i.e. foo# still means flake:foo, and things like github:owner/repo still means that flake.

Describe alternatives you've considered

  • Give nixpkgs# a shorter name: Still a bit hard to type, even if it's just n#

Additional context

This would be a breaking change, but I do believe that the impact will be minimal. Ideally this should just affect the use of the registry (i.e. flake:foo stuff), and only when accessing the default output, which I believe is a minority of the cases one would specify an INSTALLABLE. I could be very wrong about how flakes are actually/intended to be used though.

The reasons why we didn't do this:

  • It privileges nixpkgs over other flakes, while other flakes should be as easy to use as nixpkgs.
  • It's ambiguous: it's not clear whether nix run wireshark means nixpkgs#wireshark or wireshark#defaultPackage.

I'm not sure if this is the intention, but I think I am going to use stuff under nixpkgs# far more than the various other flakes.

That's true today but might not be the case in a decentralized world where a lot of stuff isn't in nixpkgs.

Okay, thanks for the clarification

Allow omitting the flake ref part for nixpkgs as is may privileges nixpkgs. but instead, we can grant the choice back to the users, allow setting a default flake that would be used to resolve names in case of no other matches, or even better a search list (just like how podman handles multiple registries). For the ambiguity part, we may introduce special symbols into the definition of INSTALLABLES, @wireshark for example.

I would really love to see how the community ends up using flakes. So I'm hoping that this UI is more open to discussion.

For my own use case, I have a package set which is nixpkgs with a overlay on top of it, with my packages and some tweaks and patches. The same flake also contains my NixOS configuration. So it would be wonderful personally if a default flake can be set.

That's true today but might not be the case in a decentralized world where a lot of stuff isn't in nixpkgs.

In a decentralized world, would it probably be expected that each user has a 'personal flake' that is used most often? I'm thinking about a flake with inputs referring to many other flakes as dependencies, and containing a package set and/or a nixosConfiguration for the machines a user has. It certainly seems like this is how many are making their flakes now.

As for the ambiguity problem, from a UI point of view, I'd prefer if there's no special character, but I think we can also reuse # such that #wireshark with an empty flake name would mean flake:default#wireshark.

As for the ambiguity problem, from a UI point of view, I'd prefer if there's no special character, but I think we can also reuse # such that #wireshark with an empty flake name would mean flake:default#wireshark.

That could be an option, but # at the start of a token needs to be quoted, otherwise it's a comment in bash. So that makes it a bit less ergonomic.

How about this, fairly self-explanatory and would be nice and convenient:

nix run \#wireshark
... error of some sort

export DEFAULT_FLAKE_NAME_OR_SOMETHING=nixpkgs 
nix run \#wireshark
.... wireshark goes https://www.youtube.com/watch?v=XqZsoesa55w


export OR_MAYBE_DEFAULT_PREFIX_OR_SOMETHING=nixpkgs\#
nix run wireshark
....and wireshark goes https://www.youtube.com/watch?v=XqZsoesa55w

This thread is very interesting, I had a recent problem of setting a shell for testing where I had to write this:

nix shell nixpkgs#gcc nixpkgs#gnumake nixpkgs#openssh nixpkgs#p7zip

or

nix shell nixpkgs#cargo nixpkgs#rustc

for example.
writing the nixpkgs# once would be really nice:

nix shell nixpkgs#[gcc gnumake openssh p7zip]

I thought at some point that the --inputs-from option would solve my problem but this doesn't work for example:

nix run --inputs-from nixpkgs hello
error: cannot find flake 'flake:hello' in the flake registries

So my question is, is there a way to make it shorter?
Also, should I open another issue or is it fine to discuss this here @edolstra?

btw, you can shorten the name of nixpkgs with this command:

nix registry add n nixpkgs
fogti commented

@Narice bash afaik should also support

nix shell nixpkgs#{gcc,gnumake,openssh,p7zip}

๐Ÿค”
I'd be down for nix shell --flake nixpkgs gcc gnumake openssh p7zip and similar for other commands. This way one could easily create an alias like this alias super-shell='nix shell --flake nixpkgs' to make life more convenient.

These days im like:

$ nix sh<C-f> # Ctrl+f - Autocompletes to something like '$ nix shell nixpkgs#gcc'
$ nix shell nixpkgs#gcc<C-BS> # Ctrl + backspace - deletes `gcc`
$ nix shell nixpkgs#<TypeWhateverINeed>

:D

Thanks @zseri!
That seems to work perfectly, awesome!

nrdxp commented

@edolstra would you consider reopening this issue if instead of using a single priviledged flake, we allow for an arbitrary list of flakes to create a flat package space as I mused here? I ask this because I have been personally using nix-dram for over a month now, and the interface is just a lot nicer to work with, especially when pulling in multiple packages to a shell.

If we don't do this, we'll end up having to work around this with some magic derivation as already attempted in a nixpkgs pull. The advantage of doing this here instead of in a derivation is that completions work wonderfully, and it's just shorter and more intuitive.

I mean I guess zseri's answer above isn't horrible, but nix-dram has the advantage of working with completion

Maybe an alias completer is not the worst solution?

For example, I found this, here: https://github.com/cykerway/complete-alias

Maybe some tweaks are necesary, but @gytis-ivaskevicius 's suggestions might somehow work.

This neither prefers one flake over others, nor does it incur in never-to-be clean conflict resolution on merging namespaces.

The latter, specifically, might result in unexpected user behaviour and cannot be resolved.

Yes, I agree, the UX of nix-dram is better.
nix-search-pretty is also insanely cool, I would love to have this as the default.
The way nix-dram does it is not biased towards nixpkgs in any way.
Having some flake(s) available as default(s) would indeed be a good idea.
As the users are tending towards the nix-dram approach it would be wise to reopen the issue.
What is your thought process on this @edolstra? What are the tradeoffs you are making worth risking a fork and thus split in the community?

The problem with merging flakes into a flat namespace is that 1) it's ambiguous since multiple flakes can provide packages with the same name; and 2) it's inefficient since you have to evaluate all the flakes in the flat namespace.

nrdxp commented

so what's the problem with nix-dram implementation as is? Looks like the original objection was that we didn't want to make nixpkgs special, but as it stands this is already solved since it allows you to set whichever flake you want as the default, either via the default flake, or via a config option.

I dunno, at least for me, I don't see myself going back to the old UI any time soon, and I may not be the only one...

The remaining problem (with a single default) I see is not a technical one, but one of strategy & direction: if we allow people to set their preferred flake officially within the nix binary config, then it is a non-negligeable signal that de-facto acknowledges (and freezes) the centralized nature of nixpkgs. That, in essence, is treason to the issues [a multitude of decentralized] (snow-)flakes where intended to solve.

In other words: people who have a default flake set, will eventually fight decentralization [in addition to all the existing headwind] because it goes against their (officially sanctioned) habits.

As the author of nix-dram, and the original author of this feature request, I think the question I raised previously in this comment is more important than I thought: #4438 (comment)

In a decentralized world, would it probably be expected that each user has a 'personal flake' that is used most often?

nix-dram was developed under the assumption that the answer is 'yes' and works greatly with 'one personal everything flake'. This flake contains not only the package I knew I will be using, but also packages I might use but isn't already part of any config. These 'might use' packages are one nix run foo away without needing to type n# or p# or default# or nixpkgs#. It's not nixpkgs; it just happens to contain it.

It is also demonstrably not the case that everyone will have this workflow. For example, see this reddit comment: https://www.reddit.com/r/NixOS/comments/lbqsfg/comment/glvzhpe/

I'd love to hear about anyone's thoughts on this question, both answers and comments on the question itself.

nrdxp commented

This is a very good point. Since reexporting nixpkgs from your NixOS system's flake with your custome overlays applied seems like a clean way to combine whichever packages you'd like into a default package space to search. I would consider it good practice for flake authors to provide both a package and a overlay for their flake packages, although this isn't always the case unfortunately.

I understand the comment about needing to search multiple different nixpkgs, but I still think having one eval cached and quickly accessible nixpkgs is a great idea. This is a package manager after all, what should be the initial concern for a new user just trying to pull a package into a shell? Should it be the given package itself (like every other package manager in the world), or some abstract concept called "flakes" which they may not even fully grasp just yet?

In terms of breaking decentralization, I think combining flake overlays as mentioned above largely addresses this, but I'm not so sure the original intention of flakes was to break up nixpkgs anyway. Even if it was, I doubt that would ever come to pass since there are quite a number of Nixers who are hugely in favour of the current monorepo workflow, and it does seem to fit rather nicely with the goal of providing a global package repository.

For the sake of argument though, let's say nixpkgs is broken up. Individual flakes would still likely be accessible from a single global space somehow or another whether officially, or by some community effort, similar to how packages in Arch Linux are individual git repos, but they are still searchable and installable from a single package space. Anything else would just require too much overhead.

I think the relevant generalizations (over nixpkgs) that flakes is dealing with are:

  • overlays -> input.follows
  • default package space -> registry

So the point of contention seems to be that the registry namespace cannot easily be flattened.

This very fundamentally circles back to having a global namespace (as in nixpkgs) vs having flakes.

I'd say, aliasing certain registry items to short commands would do the trick without letting the dragon in?

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

https://discourse.nixos.org/t/too-many-open-files-nix-error-cant-search-packages/16299/2

nrdxp commented

Could we consider reopening this if we reduced the scope a bit, and only allow nix to search the flake in the current directory for outputs if a flakeref is not matched? That would be more convenient for working on flake based projects, while avoiding the main concerns that got this closed in the first place.