Describe the bug
Oh this was quite surprising to see:
sudo nix --experimental-features 'nix-command flakes' --pure-eval \
build --profile /nix/var/nix/profiles/system \
--override-input master /home/cole/code/nixpkgs/master \
--override-input stable /home/cole/code/nixpkgs/stable \
--override-input cmpkgs /home/cole/code/nixpkgs/cmpkgs \
--override-input pipkgs /home/cole/code/nixpkgs/pipkgs \
--override-input home /home/cole/code/home-manager/cmhm-flakes
.#nixosConfigurations.xeep.config.system.build.toplevel
warning: Git tree '/home/cole/code/nixcfg' is dirty
warning: updating lock file '/home/cole/code/nixcfg/flake.lock':
* Updated 'home': 'git+file:///home/cole/code/home-manager/cmhm-flakes?ref=cmhm-flakes&rev=7ff1ecdecee6de0924804b1b7fac629d17580c4c' -> 'git+file:///home/cole/code/home-manager/cmhm-flakes?ref=cmhm-flakes&rev=b10c561c1f343f4268ab4d115977bfe1a93608ee'
warning: Git tree '/home/cole/code/nixcfg' is dirty
Expected behavior
In my opinion, a call to nix-build should not touch flake.lock ever. This is very unexpected to me. In fact, I virtually never expect flake.lock to be touched unless I'm making an explicit call to nix flake ....
$ nix-shell --command "nix --version"
nix (Nix) 2.4pre20200622_334e26b
In my opinion, a call to nix-build should not touch flake.lock ever.
Strongly disagree. Our behaviour is consistent with commands like cargo build that also update the lock file if you've made a change to Cargo.toml that requires the lock file to be updated.
But I'm explicitly not changing any files. I'm just specifying some command line args?
It's a build command. I would understand if I wrote nix flake update --change-input, but I wrote nix build --override-input which I feel safe saying naively reads as "do a nix build but temporarily override this input".
What happened here strongly violates my expectations and I'm at least somewhat accustomed to using cargo.
(To be more clear, since I wasn't explicit in the OP, the on-disk flake.nix specifies non-path, git inputs. Hence why I think it's very wrong to see paths in the lock file.)
--override-input is a bit of a misnomer. It really means "change this input to this specific value", whereas --update-input means "update this input to the latest version". I guess "override" gives the wrong impression that it's only a transient override.
I still am left with a case where flake.lock makes no sense based on what is in flake.nix of the repo. I guess I can understand that a flake-author might want to do this at a point in time, but I'd rather see that represented by them doing the pinning in the flake.nix file, just like I'd expect the same of a Rust author to pin a specific input by specifying that constraint in the Cargo.toml file.
At the very least, I would expect nix build to not touch flake.lock (aka not have those flags at all) and restrict such updates to nix flake commands.
So maybe permanent changes to the lock file should only be made through nix flake and transient changes/overrides with any of the other commands.
At the very least, I would expect nix build to not touch flake.lock (aka not have those flags at all) and restrict such updates to nix flake commands.
That's bad UX. It means you would have to manually run nix flake <something> every time you change a flake input. It's much more convenient if this happens automatically.
How about we add an --update-locks flag to nix build which retains the old behavior?
That'd be just as convenient and wouldn't do stuff the user doesn't expect.
BTW, the result of this is that I'm constantly finding out my repos are in bad states because of this, forgetting it, and then pushing flake.locks that make no sense because they refer to local paths.
This issue has been mentioned on NixOS Discourse. There might be relevant details there:
https://discourse.nixos.org/t/to-flake-or-not-to-flake/10047/4
Most helpful comment
So maybe permanent changes to the lock file should only be made through
nix flakeand transient changes/overrides with any of the other commands.