What would you like to see improved in Nix cli experience?

well, if you think that’s strange ,look at trying to pick a name for nix shell. naming stuff is very very difficult.

https://github.com/NixOS/nix/issues/4715

;-).

4 Likes

Incidentally, I just opened up this issue today:
https://github.com/NixOS/nix/issues/7468

I realized that nix develop creates a derivation which there is no way to reproduce in Nix code, and thus there is no way to have other derivations depend on a dev env, even though I feel this is a valid usecase (scripts that first enter a devshell, etc).

Another consequence is that there is no way to build the actual devshell derivation without also running it, which is bad for things like CI and caching, unless we have some kind of special handling for devshells.

I think a simple primop like builtins.devEnv drv would solve this, but in general I don’t think the CLI should be doing any special “magic” like this that cannot be reproduced easily in Nix code.

Another similar situation would be the eval-cache, which is heavily tied to nix build and flakes and doesn’t even work with things like nix eval which is completely unintuitive. I think the solution there may end up being similar to my suggestion for the above issue (a primop):
https://github.com/NixOS/nix/issues/6228

2 Likes

i never use these shells in CI. It’s always nix builds or the nothing…

Shells != Builds , I have the luxury/privilege of not supporting legacy garbage.

But anything that could improve the situation …would be super dooper!

in terms of the underlying abstraction shells == builds in that they are both derivations. The only differnce is that one can be referenced and one cannot (which I think is a mistake).

For example, at work we have a very sensitive tool (SBT) that is very finicky about its environment, and even a slight deviation can cause some unexpected behavior, what I do in CI to prevent this is to enter the devshell produced on the build of the project package we are going to work on so that the environment SBT is operating in is identical to the build env, which is already known to work reliably.

I updated my issue with a concrete example to properly illustrate what I mean, but, yeah, the general comment is that the CLI should not do things that cannot be done manually in Nix code. It should be a convenience, not a crutch.

1 Like

if you talking about Scala build tool, ouch… that things is about a reproducible as a making a sculpture out of water.

Java, and things associated with it seem to be the most unreproduable things i’ve encounted… … if SBT is something else…then I’ve fallen into the too many acronyms doom trap.

Sure, I can see what you mean… i loose track, but i think nix now has 600 shells now… :wink:

Interesting stuff, thanks for the education.

And exactly here the misconception starts. It does not create a “derivation”. It just mimics an environment that can be used to build a given derivation.

And as pointed out in How to use `nix develop` within a GitLab CI pipeline? - #2 by NobbZ, it is possible to use nix develop in CI.

CI Services that allow you to change your shell for a job/step with a custom command, can use nix develop even as a “shell”.

Though you will never actually able to “build” and “install” something that is like what you enter with nix develop, as it simply isn’t able to set env vats some how.

Anyway. Most if not all of the posts since What would you like to see improved in Nix cli experience? - #10 by nixinator are probably off topic in this thread, and I’d ask @moderators to split them out.

2 Likes

I’m gonna have to beg to differ. Simply do a nix develop --profile foo and inspect foo, you’ll see that is a unique derivation. In any case I think thufschmitt has the right idea as to how to address it.

I actually have an ad hoc 2nix style solution that generates a lock file which is then used to build a local maven repo that SBT exclusively reads from, so its a little better than what’s out in the wild as it has no IFD and no massive FOD. I wanted to do a proper 2nix or a dream2nix integration for it, but haven’t had time yet.

Agreed, I was just trying to use a few examples to illustrate the general idea that the CLI should keep magic like this to a minimum, sorry for derailing :sweat_smile:

2 Likes

This isn’t precisely a CLI thing, but I’d like the ability for nix to keep track of how long it’s been since a store object was tied to a gcroot, and allow gc to be configured to use that information to decide whether to delete it. It would help a lot with the issues people have with, e.g. nix shells being garbage collected when they don’t want them to.

4 Likes

It would indeed by nice if the garbage collector could delete the least/oldest used derivations first

5 Likes

Very annoying and easily fixable:
nix eval nixpkgs#hello fails with a long, cryptic error.

https://github.com/NixOS/nix/issues/5731

1 Like

Fits the title, but not really the context of the initial post. Here’s it anyway:

  • A reduced set of pocelain nix
  • A consistently behaving set of plumbing nix
2 Likes

Here are some basic things Nix needs to get right imo, many of which are nicely implemented in Guix (anyone thinking about the Nix CLI’s UX should spend some time messing with Guix)

  1. We need a unified subcommand interface, and subcommands must have individual manpages, like with git.
  2. nix install <package name> and nix remove <package name> should both just work and do what people expect.
  • no subcommands required (this can be an alias for nix profile install and so on, whatever)
  • if a flake is unspecified, assume Nixpkgs or allow users to set a search path
  • only direct users to specify a flake or individual installed item if the name given is actually ambiguous
  1. Incorporate something like nvd to show the changes between generations. The ability to (p)review changes in that way will be taken for granted, if not seen as table stakes, for users coming from anywhere else.
  2. Repurpose nixos-rebuild as plumbing (or replace it, whatever) with a new nix os subcommand or similar. (see: guix system)

I can think of other things, but I think just those would go a long way, especially with new users

14 Likes

These are deep changes in Nix, I suppose this would require a RFC or something

nix flake add-input foo github:foo/bar should automatically handle flake = field.

nix build don’t shouldn’t automatically update dependencies.

nix flake check should implicitly use --system <current-system> when --no-build was not indicated. A --build flag may also work here if there were a desire to avoid legacy breakage.

nix flake lock -v should indicate when registries are referenced in favor of declarations.

While this is more of a registry change : registries should not assume entries are flakes, and should support arbitrary inputs.

nix build should support --apply.

nix eval should support --arg even if returned value is not an attrset. This one makes no sense honestly. I have to use --apply 'f: f { x = 1; }' to work around this which isn’t the worst; but it makes shell escapes more painful than they need to be.

Base Env vars for inPureMode, inCheckMode, inReplMode, and ifdAllowed.

2 Likes

This is one of my big annoyances as well.

You can easily do something like nix repl ./default.nix to load a project into the repl (which is helpful with a project like Nixpkgs), but there is no similar way (that I know of) to load a whole flake from the CLI.

Using builtins.getFlake inside the repl is also annoying, because it requires a full absolute path as a string.


Not having some system for passing arbitrary arguments to flakes is also annoying in practice:

https://github.com/NixOS/nix/issues/2861

2 Likes

nix --extra-experimental-features repl-flakes repl

@cdepillabout

Or nix-repl> :a builtins.getFlake ( toString ./. )

For args/overrides in the repl I wrote a lib. But I agree that passing arguments with the builtin should be possible.

$ nix repl;
nix-repl> :lf github:aakropotkin/ak-nix
nix-repl> :a lib.callFlakeWith {
  # "auto" args similar to a registry
  nixpkgs = builtins.getFlake ( toString ./my-nixpkgs );
} ./my-project /* target flake */ {
  # explicit args
  foo = "boom we're just out here passing arbitrary values as arguments y'all";
  bar = ( builtins.getFlake "baz" ).inputs.bar;  # "follows"
} 
nix-repl> :b packages.foo

More fun callFlake and registry utils: https://github.com/aakropotkin/ak-nix/blob/39f3e324c68110266a92ace46de51e62c6f85c34/lib/flake-utils.nix

Ah, the toString ./. is a nice trick! I’ll definitely have to remember that.

1 Like

Ok, I have a few:

  1. Inability to rollback to the last good generation.
    Say that you run sudo nixos-rebuild test and realise that the configuration is broken. Ok, no problem, that’s what test is for, right?
    No, you can’t rollback: nixos-rebuild switch --rollback bring you two generations back.

  2. Inability to switch to a specific generation.
    Say, I rolled back to generation 3 because I quickly needed something that generation 4 broke. Now I’m done, how do I go back to generation 4? Spend some 15 minutes looking at the nix-env(1) man page, then give up and do nixos-rebuild switch.

  3. the channel syntax removed in Nix 2.4 (I think) for apparently no good reason:
    nix run nixpkgs.hello should use the <nixpkgs> channel, while nix run nixpkgs#hello should use the flake.

5 Likes

I agree with the first 2, but just wanted to tell you that 3 is fixed already:

$ nix run -f '<nixpkgs>' hello
Hello, world!`

The explicit -f makes the intend much more clear.

3 Likes

And it’s working with nix shell too :star_struck: I pinned my nixpkgs registry and channel to the nixpkgs used to build NixOS, but it’s far easier to use -f <nixpkgs>!