From 2123305725d9a6621f9f44a79c7f593c237db19a Mon Sep 17 00:00:00 2001 From: Bob van der Linden Date: Fri, 8 Mar 2024 22:47:59 +0100 Subject: [PATCH 1/2] profile: add installable matcher This allows removing and upgrading packages using flake urls. --- src/nix/profile.cc | 40 +++++++++++++++++++++++++++++++++ tests/functional/nix-profile.sh | 21 ++++++++++++++++- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/nix/profile.cc b/src/nix/profile.cc index a5a40e4f6..1a7b46546 100644 --- a/src/nix/profile.cc +++ b/src/nix/profile.cc @@ -541,6 +541,43 @@ struct NameMatcher final : public Matcher } }; +std::regex defaultPackageFragmentPattern("(?:legacyPackages|packages)\\.(?:[^\\.]+)\\.default"); +std::regex packageFragmentPattern("(?:legacyPackages|packages)\\.(?:[^\\.]+)\\.(.+)"); +struct InstallableMatcher : public Matcher +{ + const FlakeRef flakeRef; + const std::string fragment; + + InstallableMatcher(const FlakeRef flakeRef, const std::string fragment) : flakeRef(flakeRef), fragment(fragment) + { } + + std::string getTitle() override + { + return fmt("Installable '%s#%s'", flakeRef.to_string(), fragment); + } + + bool matches(const std::string & name, const ProfileElement & element) override + { + if (element.source->originalRef != flakeRef) { + return false; + } + // Match "#packages.{system}.default" + if (fragment == "") { + return std::regex_match(element.source->attrPath, defaultPackageFragmentPattern); + } + // Match "#{name}" + if (element.source->attrPath == fragment) { + return true; + } + // Match "#packages.{system}.{name}" + std::smatch match; + if (std::regex_match(element.source->attrPath, match, packageFragmentPattern)) { + return match.str(1) == fragment; + } + return false; + } +}; + struct AllMatcher final : public Matcher { std::string getTitle() override @@ -588,6 +625,9 @@ public: throw Error("'nix profile' no longer supports indices ('%d')", *n); } else if (getStore()->isStorePath(arg)) { _matchers.push_back(make_ref(getStore()->parseStorePath(arg))); + } else if (std::regex_match(arg, std::regex(".*[#:].*"))) { + auto pair = parseFlakeRefWithFragment(arg); + _matchers.push_back(make_ref(pair.first, pair.second)); } else { _matchers.push_back(make_ref(arg)); } diff --git a/tests/functional/nix-profile.sh b/tests/functional/nix-profile.sh index 7c4da6283..07d770851 100644 --- a/tests/functional/nix-profile.sh +++ b/tests/functional/nix-profile.sh @@ -106,9 +106,28 @@ warning: No packages to upgrade. Use 'nix profile list' to see the current profi EOF # Test removing all packages using regular expression. -nix profile remove --regex '.*' 2>&1 | grep "removed 2 packages, kept 0 packages" +assertStderr nix --offline profile remove --regex '.*' << EOF +removing 'path:$flake1Dir#packages.$system.default' +removing 'foo' +removed 2 packages, kept 0 packages +EOF nix profile rollback +# Test removing package using full url. +nix profile remove "path:$flake1Dir#packages.$system.default" +[[ ! -f $TEST_HOME/.nix-profile/bin/hello ]] +nix profile install $flake1Dir + +# Test removing package using shorthand flake url. +nix profile remove path:$flake1Dir +[[ ! -f $TEST_HOME/.nix-profile/bin/hello ]] +nix profile install $flake1Dir + +# Test removing package using shorthand package name. +nix profile remove path:$flake1Dir#default +[[ ! -f $TEST_HOME/.nix-profile/bin/hello ]] +nix profile install $flake1Dir + # Test 'history', 'diff-closures'. nix profile diff-closures From 10a6dff3b8e47eb998cce3fc2491f4120bc02de3 Mon Sep 17 00:00:00 2001 From: Bob van der Linden Date: Fri, 8 Mar 2024 23:04:16 +0100 Subject: [PATCH 2/2] add release note --- doc/manual/rl-next/profile-flake-url.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 doc/manual/rl-next/profile-flake-url.md diff --git a/doc/manual/rl-next/profile-flake-url.md b/doc/manual/rl-next/profile-flake-url.md new file mode 100644 index 000000000..e9b546650 --- /dev/null +++ b/doc/manual/rl-next/profile-flake-url.md @@ -0,0 +1,12 @@ +--- +synopsis: Removing and upgrading packages using flake URLs +prs: 10198 +--- + +It is now possible to remove and upgrade packages in `nix profile` using flake URLs. + +```console +$ nix profile install nixpkgs#firefox +$ nix profile upgrade nixpkgs#firefox +$ nix profile remove nixpkgs#firefox +```