nix icon indicating copy to clipboard operation
nix copied to clipboard

`nix flake update --single <name>` is more intuitive than `nix flake lock --update

Open colemickens opened this issue 4 years ago • 26 comments

Why is nix flake update a think instead of just nix flake lock --update-all?

Or why is nix flake lock --update-input not nix flake update --single <name>.

Or is there some other reasoning for the current grouping? I don't get it, I have to look it up every time. It just feels inconistent

colemickens avatar Aug 09 '21 05:08 colemickens

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

https://discourse.nixos.org/t/how-to-update-a-single-flake-input/13584/6

nixos-discourse avatar Aug 09 '21 18:08 nixos-discourse

I strongly agree with OP, if Flakes are supposed to make Nix more approachable we should aim to minimize confusion and optimize the UX for discoverability.

kubukoz avatar Nov 18 '21 17:11 kubukoz

Or even

nix flake update [option...] flake-url [input1 [input2 ...]]

Kha avatar Nov 18 '21 17:11 Kha

might also be nice to have a nix flake update --exclude [input1] for excluding specific inputs that might not be working at that moment.

zyansheep avatar Dec 11 '21 02:12 zyansheep

As a Nix beginner who was just wondering why nix flake update didn't let me upgrade specific inputs individually, and had to find out about nix flake lock from the forums, I can confirm this was a frustrating papercut!

brendanzab avatar Jan 02 '22 20:01 brendanzab

I have to google this command every time I want to update a single input.

shinzui avatar Jan 30 '22 23:01 shinzui

This really needs an UX improvment. I consider myself a fairly seasoned nix user and I recently wanted to update a single input. This is my story.

  • I tried nix flake update --update-input <input>. Didn't work.
  • I then read through nix help flake and the flake-related section of nix help build.
  • Finally, I settled for nix eval .#randomOutput --raw --apply '_: ""' --update-input nixpkgs-unstable. I'd never have associated the lock verb with updating a flake.

I'd recommend the following:

  • Support the common flake arg --update-input in nix flake update.
  • Remove nix flake lock --recreate-lock-file. What's the difference between this and nix flake update? If there's a difference, support --recreate-lock-file in nix flake update.
  • Delete subcommand lock, replace it with nix update --add-missing.

erikarvstedt avatar May 02 '22 23:05 erikarvstedt

I think there's plenty of agreement here, it'll take a PR to get things moving :)

TLATER avatar May 03 '22 10:05 TLATER

It just feels inconistent

It isn't.

  • nix flake update: Recreates the entire lock file, thus updating everything.
  • nix flake lock: Add missing locks, optionally updating some locks if --update-input is given. This is same behaviour as commands like nix build.

See also the discussion in #3781.

edolstra avatar May 03 '22 13:05 edolstra

At the very least it's difficult to find 😅

kubukoz avatar May 04 '22 09:05 kubukoz

I just ran into this myself. I saw that nix flake update updated my inputs, and it felt very natural to assume I'd be able to restrict that invocation to a single input. In fact, my working solution for the past week was

nix flake update; git add -p; git commit -m "partial flake update"; git reset --hard

until going off on another lengthy search today and ending up at this issue.

I'd suggest it might useful to override any technical consistency of the current approach in favour of a more intuitive UX?

robx avatar May 09 '22 12:05 robx

I think the following would be more intuitive:

  • nix flake update - the main way of updating anything in the lock file. Optional argument (named or positional, up to bikeshedding) for updating a specific input
  • nix flake lock - locks the current inputs (all of them) or one of them if --update-input is given. Most likely you'd only ever use this once or never (relying on nix build and others to perform the locking)

The main rationale for keeping single- and multi-input updates under the same command: it's just confusing to everyone that you currently need two.

kubukoz avatar May 09 '22 12:05 kubukoz

I understand both sides but think the status quo is bad.

I think there are two solutions:

  1. Either, we remove nix flake update completely, and use something like nix flake lock --update-all. (The only inconsistency would be the first invocation, because it is not an update).
  2. Or we allow nix flake update to act on one input, for example, like so: nix flake update --only bla (or --single).

dschrempf avatar May 18 '22 08:05 dschrempf

We discussed that a bit during the last UX meeting.

The broad outcome was that:

  • Both commands make sense individually
    • lock as a low-level “just do stuff on the lockfile”
    • update as the very handy “update everything”
  • update is morally an alias for lock --recreate-lockfile

One suggestion to reduce the confusion was to simply make the fact that update is merely a shorthand alias explicit in the documentation (and maybe give --recreate-lockfile a better name as it's not entirely obvious what it does)

thufschmitt avatar Jul 01 '22 07:07 thufschmitt

This doesn't seem inconsistent with making update arg1 arg2 an alias for lock --update-input arg1 --update-input arg2.

ncfavier avatar Jul 01 '22 10:07 ncfavier

This doesn't seem inconsistent with making update arg1 arg2 an alias for lock --update-input arg1 --update-input arg2.

It's not indeed. However doing so would be inconsistent with the fact that update arg1 means "update the inputs of the flake arg1" (and update alone is just a shorthand for update .)

thufschmitt avatar Jul 04 '22 15:07 thufschmitt

Honestly, I doubt beginner users will ever want to update any other flake than ..

What's the usecase for nix flake update github:nixos/nixpkgs?

Beginners want the ability to easily update these on their own flake (.):

  • all the dependencies
  • one particular dependency

I don't think they're gonna want to dig into lockfile-related lock commands to find out how to do that. Just nix update / nix update arg1 should be enough, really.

One suggestion to reduce the confusion was to simply make the fact that update is merely a shorthand alias explicit in the documentation (and maybe give --recreate-lockfile a better name as it's not entirely obvious what it does)

Documentation is good, but if the UX of the tool is confusing, it should be improved at the source, and not just documented. Especially now, while flakes are experimental.

kubukoz avatar Jul 04 '22 15:07 kubukoz

Backwards consistency isn't really the matter here (as you say, it's experimental, we could break things).

I agree that taken individually, this command could make more sense in the form nix flake update input1 input2 .... But that would play at the detriment of global coherence: All the commands that can operate on a flake (so nearly all the commands) follow the same convention nix <command> [flake-uri] [args]. Breaking this convention would be annoying.

If anything I'd rather remove update altogether and recommend something like lock --update-inputs as a replacement (and keep lock --update-input foo --update-input bar). Or maybe have lock --update-inputs foo bar which although a bit longer would have the advantage of preserving consistency and allow a direct list of inputs to update at the same time.

thufschmitt avatar Jul 04 '22 18:07 thufschmitt

What's the usecase for nix flake update github:nixos/nixpkgs?

That one obviously doesn't make any sense, but nix flake update /some/directory does

thufschmitt avatar Jul 04 '22 18:07 thufschmitt

I don't think lock --update-input helps simplify the UX. How about

  • nix flake update-all - does what the current update does
  • nix flake update - does what lock --update-input does

kubukoz avatar Jul 05 '22 01:07 kubukoz

nix flake update - does what lock --update-input does

Do you mean that you'd call it as nix flake update input1?

thufschmitt avatar Jul 05 '22 06:07 thufschmitt

nix flake update - does what lock --update-input does

Do you mean that you'd call it as nix flake update input1?

@thufschmitt that's right. I see how It's not going to be consistent with the way of passing the flake reference as a positional argument, but sticking to that for the sake of consistency would make for a less intuitive UX for users.

In my view nix flake update input1 makes sense because positional arguments feel more "important" than named parameters, and the main parameter of "I want to update a single input" is the input you want to update.

Another idea - provide syntax to refer to a flake input. Then it'd be like nix flake update .#inputs.nixpkgs (updating the nixpkgs input of the cwd's flake) and nix flake update . under the same command.

kubukoz avatar Jul 05 '22 17:07 kubukoz

nix flake currently supports 3 operations for operating on lockfiles, spread over 2 commands. To improve UX, these should be bundled into one command.

Lockfile operations

  1. Update all inputs / recreate the whole lock file nix flake update nix flake lock --recreate-lock-file

  2. Update missing inputs nix flake lock

  3. Update a specific input nix flake lock --update-input <input>

Why the current UX is bad

The split into two commands is confusing. Bundling all lockfile operations into one command would lead to a more intuitive and discoverable interface.

Example user story: A user wants to update a specific input of a flake.

  • The user runs nix flake --help and is currently shown the following subcommand listing, at the top of the help output:
    nix flake lock - create missing lock file entries
    ...
    nix flake update - update flake lock file
    
  • The user recognizes nix flake update as the relevant command and runs nix flake update --help.
  • The help shows no info relevant to the task (because only nix flake lock supports updating single inputs), the user is stuck.

Solution: Single command

update is the relevant verb for most lockfile operations, so nix flake update is the overall best fit for the command name.

Suggested output of nix flake --help:

nix flake update - update or create flake lock file

Suggested design of nix flake update:

nix flake update
nix flake update --update-input <input>
nix flake update --add-missing # replaces `nix flake lock`, which is seldomly called on its own

erikarvstedt avatar Aug 04 '22 09:08 erikarvstedt

nix flake update --add-missing # replaces nix flake lock, which is seldomly called on its own

I don't think this is true. It's pretty common to add a new input, where you want to update the lockfile to reflect the new input without upgrading every other input. In the new UI we try to avoid flags that negate what a command does, e.g. a --add-missing flag that negates the "update" part of nix flake update.

I do think nix flake update should be renamed to nix flake upgrade to better reflect what it does (namely upgrade all inputs to the latest version). That avoids the ambiguity of the word "update".

edolstra avatar Aug 04 '22 09:08 edolstra

Nix really should fix the update single input user story which is catastrophically bad right now. I'm convinced that a single command that makes the default case simple is by far the most user-friendly design. Maybe we should hold a vote or do user testing on this issue.

--add-missing is no direct negation, it just modifies which inputs are updated.

erikarvstedt avatar Aug 04 '22 10:08 erikarvstedt

I don't think this is true. It's pretty common to add a new input, where you want to update the lockfile to reflect the new input without upgrading every other input

A nix flake lock is indeed rarely necessary, as one usually adds some output using that input and one does nix build .#thatOutput, in which case nix already implicitely does whatever nix flake lock does.

If I do not want this behaviour I have to explicitely opt out using --no-write-lockfile, and I have to use that flag in many other cases when nix considers a lock file "stale".

NobbZ avatar Aug 05 '22 15:08 NobbZ

@edolstra:

I do think nix flake update should be renamed to nix flake upgrade to better reflect what it does (namely upgrade all inputs to the latest version). That avoids the ambiguity of the word "update".

Why have two separate commands for lockfile manipulation? Given that nix flake lock has quite a number of features, I suggest that nix flake update should be replaced by something like nix flake lock --update-all.


Edit: I read through the UX meeting minutes, which suggests noting that nix flake update is an alias for nix flake lock --recreate-lockfile.

I think this will help the user solve their problem without a search engine.

I still expect many users to reach for nix flake update, realise it won't help, then try nix flake lock (as per the user story above). In my opinion that indirection makes for a poorer experience.

LightAndLight avatar Aug 12 '22 01:08 LightAndLight

I think everyone has been very clear that the current experience is bad, and @edolstra has been clear that he doesn't see a problem or care. Not really sure where to go from this, especially considering how detailed the user stories and feedback written in this issue are. For me personally it was really demoralizing to have the issue described in this thread, Google to find out why it's broken, and see project leadership rejecting the sort of fixes that would have saved me time and frustration.

9999years avatar Oct 31 '22 21:10 9999years

@9999years I don't think anyone denies that there's an issue here. But I don't think we have a clear-cut solution either. Everyone (including myself) seems to have their own idea of how this should behave. I, for one, think they are mostly all better than the current status quo, but none seems to stand-out enough to warrant the change. I wouldn't want to do a breaking change now, only to realize in a couple of months that the change wasn't really as good as what it should have been and have to re-break stuff. Maybe it's Buridan's donkey striking again, though, and we should just pick one suggestion at random 🤷‍♂️

thufschmitt avatar Nov 14 '22 13:11 thufschmitt

none seems to stand-out enough to warrant the change. I wouldn't want to do a breaking change now, only to realize in a couple of months that the change wasn't really as good as what it should have been and have to re-break stuff

What's the point of nix-command being an experimental feature for years if we're not willing to make breaking changes? We should be experimenting with our experimental feature or it should be stabilized.

9999years avatar Nov 14 '22 14:11 9999years