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

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>!

I know about that, but It’s much longer to type and it doesn’t work with nix search. Since nix-env -q is just terrible and nix search is broken nowadays I resort to search for packages on nixos.org.

2 Likes

The problem with nixpkgs.hello is, how do you distinguish between nixpkgs.hello as an attribute path and the current interpretation of $(pwd)/nixpkgs.hello#default?

And -f seems to work with nix search

$ nix search -f '<nixpkgs>' hello
*  (2.12.1)
  A program that produces a familiar, friendly greeting
$ nix search -f '<nixpkgs>' firefox
*  (108.0.1)
  A web browser built from Firefox source tree

Alternatively you can still use nix-env -qaP if you don’t want to use nix search nor the browser.

The problem with nixpkgs.hello is, how do you distinguish between nixpkgs.hello as an attribute path and the current interpretation of $(pwd)/nixpkgs.hello#default ?

I would just not allow the second possibility: add ./ to force the path interpretation, as is already mandated in the Nix language.

And -f seems to work with nix search

Try searching for something that’s not exact match and you’ll get a puzzling error.

I see. So lets fix -f there.

Not really a friend of it, and might already break, as we already had some random breakages because of “relative paths are not allowed as a flakeref” which happened where they didn’t make sense.

I have to be honest with all of you… I think we could actually make your way kind of default (*) and require --flake or -F for flakes. Everything in the new CLI just assumes they are the default and ignores non-flake use cases, I consider this indeed a pity.

(*): I am not a friend of the exact syntax, because it was never clear to me when I can use it optionally or when I actually had to provide the channel name, and if I omit it which rules are used to select it heuristically. That either had to be documented clearly, or the channel (or better nix path name) has to be mandatory, as a flakeref is for dealing with flakes…

1 Like

Yeah, the current behavior doesn’t really make sense to me:
If I enable the nix-command experimental feature but not flakes, by default nix it tries to do everything with flakes and it fails.
It would certainly make sense to keep all flake stuff off, unless flakes are also enabled.

3 Likes

There is an issue opened somewhere about this, that it’s puzzling to have nix complaining about nix-command, and then you add it to experimental-features and run again, it will complain about flakes being missing

1 Like

The nix flake check seems to be inconsistent with the rest of the commands. I recently ran into some annoyances.

It uses nix flake subcommand, whereas building using flakes is merely nix build. With the history of flakes in mind it kindof makes sense as other commands can also be used for nonflakes. When you have gone all in on flakes it doesn’t make sense anymore.

It only allows check builds of all checks. Unlike nix build .#packageName, it isn’t possible to do nix flake check .#checkName, so people need to fallback to using nix build .#checks.x86_64-linux.checkName. It is confusing.
With the build checks it seems it can be used for tests when using builds, but there is no standardized test functionality. mkTest from nixpkgs is not available and nontrivial to use these in other projects.
The output of nix flake check is kind of minimal. Might be alright, but it could do with some output like other test frameworks do. List of checkmarks and crosses of which checks have succeeded and failed.
Like most test frameworks it should use --keep-going, so that it is clear all failed checks instead of the first one that it encountered. Though it should also be able to --no-keep-going or --fail-fast.

Maybe nix flake check should be a separate command from nix flake test, so you don’t have the strange distinction of using --build.

5 Likes

A cheat sheet table to help people migrate from nix2 to nix3 would help lots of new adopters. E.g.,

nix-shell → nix develop.

I know this is not the right place. Just a wishful thinking lol

3 Likes
  1. --update-input should be removed as a common flake-related option, and just be available under nix flake update (as --input)
    a. Related: if --update-input is a “common flake-related option”, why is it not available under nix flake update?
    b. Related: it is very confusing I can’t update an input with nix flake update, but have to use nix flake lock instead
    c. nix flake lock could then be removed, as it’s equivalent to nix flake update AFAIU

  2. when no sub-command is specified, print the available ones, instead of:

    ❯ nix flake
    error: 'nix flake' requires a sub-command.
    Try 'nix --help' for more information.
    
  3. there’s man nix, but no man nix-flake. Do it like git does, e.g. man git-log.

  4. -h should be equivalent to --help

  5. remove nix help flake syntax, since it doesn’t work with sub-sub-commands (nix flake help show fails) which makes it confusing

  6. --help should print an inline list of the most useful options, not the whole manual

  7. re-introduce -K as a short version of --keep-failed, like nix 2

  8. after a failed build, nix log should print the log of the failed derivation, without having to specify a store path

  9. remove verbs from sub-commands, or add them as sub-sub-commands:

    • nix show-derivationnix derivation/nix drv, or nix derivation show (like nix realisation info)
    • nix print-dev-envnix dev-env
    • in general though, we might want to imply show
  10. remove nix develop, it could just be nix shell --dev

  11. nix store sign --recursive should work out of the box, and not require this

  12. query interface is still not in nix 3, meaning i have to jump between nix 3 and 2 for nix-store -q

5 Likes

man nix3-flake will help you here.

No! They are clearly different! nix-shell -p caused a lot of confusion and leaked. nix shell --dev will be just the opposite.

Perhaps nix develop --print?

3 Likes
nix show develop
nix show derivation
nix show realisation
...
2 Likes

nix develop --pure as a simple, predictable equivalent of nix-shell --pure (see Why doesn't develop or shell have a pure mode?).

Potentially even make it default.

1 Like

There is -i/-ignore-environment for that. Combined with -k/--keep it is more powerful than the old --pure.

Also the old --impure does something completely different then the new --pure, that would be confusing to have them both.

I think it is fine as it is now.

PS: I rarely needed -i so far, and if, then only to debug builds. The regular behavior of letting the old environment leak in is much more useful for the much more often needed “convinience” dev shells.