-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
nix profile
: Allow referring to elements by human-readable name
#8678
nix profile
: Allow referring to elements by human-readable name
#8678
Conversation
8658be2
to
3a40929
Compare
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/flakes-as-a-unified-format-for-profiles/29476/16 |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2023-07-14-nix-team-meeting-minutes-71/30472/1 |
This heuristic, whatever it ends up being, is independently useful, i.e. for ecosystem commands such as |
0539674
to
0c4c043
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works really well!
I was a bit confused at first why name
wasn't incorporated into manifest.json
, but I see what you're saying. It's not clear yet if all bases are covered correctly already in terms of naming. I don't see problems with your approach atm compared to what we already have.
I caught myself attempting to make 'this could be better for UX'-type suggestions I realized this PR is a steppingstone. It does the minimal to replace indexes with names for Nix profile. This is already a step in the right direction for nix profile UX 👍 Increments on this can be done in separate PRs I think.
Thanks for the work so far already!
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/flakes-as-a-unified-format-for-profiles/29476/17 |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/nix-flakes-is-an-experiment-that-did-too-much-at-once/32707/11 |
0c4c043
to
e1a74d6
Compare
e1a74d6
to
01ea317
Compare
@bobvanderlinden if you could have another look, that would be great! I updated the documentation a bit as well. The only thing missing are the release notes now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have one small painpoint to raise, and that is that I think users actually expect this interface:
$ nix profile install nixpkgs#vim
$ nix profile upgrade nixpkgs#vim
$ nix profile remove nixpkgs#vim
The feasibility of that is a different question (because unfortunately the meaning of nixpkgs
is neither unique nor clear in all contexts), and either way this change is probably the first step to that.
@bobvanderlinden also mentions potential UX improvements they intended to suggest, and this is probably one of them, I agree this point should not block the PR at all, but I think it's worth mentioning for reference.
Otherwise, this is great, working with names rather than numbers is obviously more human-friendly. Uniqueness is meanwhile guaranteed with numeric postfixes, so as far as I'm concerned this is a clean improvement over the current state.
It's also a beautiful diff, by the way, this is a very clean PR :)
7fbb9c4
to
c1f6b77
Compare
Thank you, I make extensive use of PR is ready for another review, I now added the the release notes as well and would say this is final and ready to merge in my book. The one remaining discussion would have to be decided by a maintainer. |
Users may select specific outputs using the ^output syntax or selecting any output using ^*. URL parsing currently doesn't support these kinds of output references: parsing will fail. Currently `queryRegex` was reused for URL fragments, which didn't include support for ^. Now queryRegex has been split from fragmentRegex, where only the fragmentRegex supports ^.
cfb52e6
to
9c0a09f
Compare
@edolstra @fricklerhandwerk could this get another look? What does this need to get approval/rejection? Or what does this need to speed up the reviewing process? |
It kind of feels like nobody in the Nix team actually uses |
@edolstra said to take a look this week |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2023-12-18-nix-team-meeting-minutes-113/37050/1 |
🥳 thanks for the review + merge! |
#include "url.hh" | ||
#include "url-parts.hh" | ||
#include "util.hh" | ||
#include "split.hh" | ||
|
||
namespace nix { | ||
|
||
/** | ||
* Try to extract a reasonably unique and meaningful, human-readable | ||
* name of a flake output from a parsed URL. | ||
* When nullopt is returned, the callsite should use information available | ||
* to it outside of the URL to determine a useful name. | ||
* This is a heuristic approach intended for user interfaces. | ||
* @return nullopt if the extracted name is not useful to identify a | ||
* flake output, for example because it is empty or "default". | ||
* Otherwise returns the extracted name. | ||
*/ | ||
std::optional<std::string> getNameFromURL(const ParsedURL & url); | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@iFreilicht I would appreciate if you could move this elsewhere. libutil
should be just utilities and not define Nix-specific concepts like store paths or flake things. (In the "Domain-Driven Design" parlance, this is a "application layer" or "domain layer" concept, but libutil is supposed to be the "infrastructure layer".)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. Could you maybe give me a hint where "elsewhere" could be?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. I would put in src/libexpr/flake/
for now. There are other flakes things in there that don't strictly relate to evaluation already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, see #9655
## Summary The latest nix version (2.20) changed how the nix profile output is represented: From the [release notes](https://nixos.org/manual/nix/stable/release-notes/rl-2.20): > nix profile now allows referring to elements by human-readable names NixOS/nix#8678 > [nix profile](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-profile) now uses names to refer to installed packages when running [list](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-profile-list), [remove](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-profile-remove) or [upgrade](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-profile-upgrade) as opposed to indices. Profile element names are generated when a package is installed and remain the same until the package is removed. > Warning: The manifest.nix file used to record the contents of profiles has changed. Nix will automatically upgrade profiles to the new version when you modify the profile. After that, the profile can no longer be used by older versions of Nix. and for `nix search`: > Disallow empty search regex in nix search [#9481](NixOS/nix#9481) > [nix search](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-search) now requires a search regex to be passed. To show all packages, use ^. TODOs: - [x] update `nix.readManifest` to handle the new format - [x] `nix search` requires a regex to be passed - [x] manually test on nix < 2.20 on devbox.sh to verify the older nix still works Fixes #1767 ## How was it tested? CICD should pass Installed nix 2.20.1 locally and am using Devbox with it to add, remove packages and run scripts and shell. verified flake updating works: 1. `examples/flakes/remote`. Did `devbox shell`, dropped the `v0.43.1` from process-compose flake, did `devbox update`, and verified that `process-compose` now had the latest version (IIRC `0.80+`) 2. `examples/flakes/php`. Did `devbox shell`, edited the flake to drop `ds` and did `devbox update`. Verified no `ds` in `php -m | grep ds`
Based off of commit 257b768 Upstream-PR: NixOS/nix#8678 Co-authored-by: Felix Uhl <[email protected]> Change-Id: Idcb7f6191ca3310ef9dc854197f7798260c3f71d
These names are parsed from the URL provided for that package Based off of commit 257b768 Upstream-PR: NixOS/nix#8678 Co-authored-by: Felix Uhl <[email protected]> Change-Id: I76d5f9cfb11d3d2915b3dd1db21d7bb49e91f4fb
Based off of commit 257b768 Upstream-PR: NixOS/nix#8678 Co-authored-by: Felix Uhl <[email protected]> Change-Id: Idcb7f6191ca3310ef9dc854197f7798260c3f71d
These names are parsed from the URL provided for that package Based off of commit 257b768 Upstream-PR: NixOS/nix#8678 Co-authored-by: Felix Uhl <[email protected]> Change-Id: I76d5f9cfb11d3d2915b3dd1db21d7bb49e91f4fb
Motivation
This PR replaces the index as the main handle for user-interaction with packages with a heuristically determined, human-readable name.
This enables commands
nix profile upgrade
andnix profile remove
to refer to packages by their expected name like so:This is desirable as the index is a surprising interaction handle and the better attribute path requires matching with regex to use properly, otherwise the user gets a surprising error message. Using a name that closely matches what the user would expect is more intuitive and in line with the interface of other CLI package managers.
Context
This PR is a starting point for improving the UX of
nix profile
in general, see #7966.In particular, it implements the feature requested in #7967 to fix #7960, #7961 and #7962.
The old index is still displayed, but using it to
upgrade
orremove
a package prints a deprecation warning. Actually removing the index will be done in #9171.Implementation strategy
A heuristic approach is used that generates the names when the profile manifest is loaded. The names are not written to the manifest, and so its structure does not change, making this change 100% backward- and forward-compatible. I deem this a good approach as it allows easy additions to these heuristics should we run into edge-cases in the future.
Duplicate packages are handled by suffixing the name with a number. This is simple and effective, and I assume we don't hit that case too often in reality.
Manually overriding the auto-generated name is not supported yet, as this would only work when installing a single package at once with the current evaluation of command line arguments, which I deemed out-of-scope for this PR.
This change is compatible with profiles managed by
nix-env
as well as profiles managed bynix profile
that still have old packages installed bynix-env
in them.To avoid confusing "does not match any packages" warnings, this PR also adds additional warning messages when packages are found, but can't be upgraded due to having been installed via
nix-env
, a store-path or a locked flake ref:this does not fix silently skipping upgrades for pinned flakes, though, see #8704.
Alternatives
I also considered storing the generated names in the
manifest.json
but decided against it to ensure potential edge-cases in the heuristics would not be permanently stored in the profile. This will us to change the heuristics quickly without any concerns about incompatibility and users will immediately benefit from upgrades without us having to implement additional mechanisms for overriding names manually, upgrading the generated names or anything like that.We could add the names to the output of
nix profile list --json
, and that might actually be useful, but I decided against it for now as I'm not sure we want that command's output to differ frommanifest.json
.For deduplication of names, we might want a smarter strategy or for the names to stay consistent, which would mean storing them in the manifest, but the semantics for that interacting with
remove
are unclear, so I decided against that for now as well.Examples for
nix list
output:New profile managed entirely by
nix profile
:Old profile generated by
nix-env
:In a profile managed by
nix profile
with old packages installed bynix-env
with duplicate packages:My own profile, managed declaratively inside a single, local flake:
To-Do:
nix profile remove
not matching packages installed bynix-env
Checklist for maintainers
Maintainers: tick if completed or explain if not relevant
tests/**.sh
src/*/tests
tests/nixos/*
Priorities
Add 👍 to pull requests you find important.