diff options
author | Qyriad <qyriad@qyriad.me> | 2024-05-01 18:51:16 -0600 |
---|---|---|
committer | Qyriad <qyriad@qyriad.me> | 2024-05-02 12:02:28 -0600 |
commit | f88423813f042cf40d9207409cd05cf4b75d87a0 (patch) | |
tree | d02a8cdc30d1978f79b8f98ba199225551ece77e /src/nix/profile.cc | |
parent | 1425aa0b7cd0d3477589f75bea4fb9c74e057fed (diff) |
nix3-profile: allow using human-readable names to select packages
These names are parsed from the URL provided for that package
Based off of commit 257b768436a0e8ab7887f9b790c5b92a7fe51ef5
Upstream-PR: https://github.com/NixOS/nix/pull/8678
Co-authored-by: Felix Uhl <felix.uhl@outlook.com>
Change-Id: I76d5f9cfb11d3d2915b3dd1db21d7bb49e91f4fb
Diffstat (limited to 'src/nix/profile.cc')
-rw-r--r-- | src/nix/profile.cc | 156 |
1 files changed, 107 insertions, 49 deletions
diff --git a/src/nix/profile.cc b/src/nix/profile.cc index 67f97ca9b..f702c7c06 100644 --- a/src/nix/profile.cc +++ b/src/nix/profile.cc @@ -189,13 +189,24 @@ public: { std::vector<Matcher> res; + auto anyIndexMatchers = false; + for (auto & s : _matchers) { - if (auto n = string2Int<size_t>(s)) + if (auto n = string2Int<size_t>(s)) { res.push_back(*n); - else if (store->isStorePath(s)) + anyIndexMatchers = true; + } else if (store->isStorePath(s)) { res.push_back(s); - else + } else { res.push_back(RegexPattern{s,std::regex(s, std::regex::extended | std::regex::icase)}); + } + } + + if (anyIndexMatchers) { + warn( + "Indices are deprecated and be removed in a future version!\n" + " Refer to packages by their `Name` printed by `nix profile list`.\n" + ); } return res; @@ -206,12 +217,13 @@ public: for (auto & matcher : matchers) { if (auto n = std::get_if<size_t>(&matcher)) { if (*n == pos) return true; + } else if (auto path = std::get_if<Path>(&matcher)) { if (element.storePaths.count(store.parseStorePath(*path))) return true; } else if (auto regex = std::get_if<RegexPattern>(&matcher)) { - if (element.source - && std::regex_match(element.source->attrPath, regex->reg)) + if (std::regex_match(element.name, regex->reg)) { return true; + } } } @@ -294,62 +306,100 @@ struct CmdProfileUpgrade : virtual SourceExprCommand, MixDefaultProfile, MixProf Installables installables; std::vector<size_t> indices; + auto matchedCount = 0; auto upgradedCount = 0; for (size_t i = 0; i < manifest.elements.size(); ++i) { auto & element(manifest.elements[i]); - if (element.source - && !element.source->originalRef.input.isLocked() - && matches(*store, element, i, matchers)) - { - upgradedCount++; + if (!matches(*store, element, i, matchers)) { + continue; + } - Activity act(*logger, lvlChatty, actUnknown, - fmt("checking '%s' for updates", element.source->attrPath)); + matchedCount += 1; - auto installable = make_ref<InstallableFlake>( - this, - getEvalState(), - FlakeRef(element.source->originalRef), - "", - element.source->outputs, - Strings{element.source->attrPath}, - Strings{}, - lockFlags); + if (!element.source) { + warn( + "Found package '%s', but it was not installed from a flake, so it can't be checked for upgrades", + element.identifier() + ); + continue; + } - auto derivedPaths = installable->toDerivedPaths(); - if (derivedPaths.empty()) continue; - auto * infop = dynamic_cast<ExtraPathInfoFlake *>(&*derivedPaths[0].info); - // `InstallableFlake` should use `ExtraPathInfoFlake`. - assert(infop); - auto & info = *infop; + if (element.source->originalRef.input.isLocked()) { + warn( + "Found package '%s', but it was installed from a locked flake reference so it can't be upgraded", + element.identifier() + ); + continue; + } - if (element.source->lockedRef == info.flake.lockedRef) continue; + upgradedCount++; - printInfo("upgrading '%s' from flake '%s' to '%s'", - element.source->attrPath, element.source->lockedRef, info.flake.lockedRef); + Activity act( + *logger, + lvlChatty, + actUnknown, + fmt("checking '%s' for updates", element.source->attrPath), + Logger::Fields{element.source->attrPath} + ); - element.source = ProfileElementSource { - .originalRef = installable->flakeRef, - .lockedRef = info.flake.lockedRef, - .attrPath = info.value.attrPath, - .outputs = installable->extendedOutputsSpec, - }; + auto installable = make_ref<InstallableFlake>( + this, + getEvalState(), + FlakeRef(element.source->originalRef), + "", + element.source->outputs, + Strings{element.source->attrPath}, + Strings{}, + lockFlags + ); - installables.push_back(installable); - indices.push_back(i); + auto derivedPaths = installable->toDerivedPaths(); + if (derivedPaths.empty()) { + continue; } + + auto * infop = dynamic_cast<ExtraPathInfoFlake *>(&*derivedPaths[0].info); + // `InstallableFlake` should use `ExtraPathInfoFlake`. + assert(infop); + auto & info = *infop; + + if (element.source->lockedRef == info.flake.lockedRef) { + continue; + } + + printInfo( + "upgrading '%s' from flake '%s' to '%s'", + element.source->attrPath, + element.source->lockedRef, + info.flake.lockedRef + ); + + element.source = ProfileElementSource { + .originalRef = installable->flakeRef, + .lockedRef = info.flake.lockedRef, + .attrPath = info.value.attrPath, + .outputs = installable->extendedOutputsSpec, + }; + + installables.push_back(installable); + indices.push_back(i); + } if (upgradedCount == 0) { - for (auto & matcher : matchers) { - if (const size_t * index = std::get_if<size_t>(&matcher)){ - warn("'%d' is not a valid index", *index); - } else if (const Path * path = std::get_if<Path>(&matcher)){ - warn("'%s' does not match any paths", *path); - } else if (const RegexPattern * regex = std::get_if<RegexPattern>(&matcher)){ - warn("'%s' does not match any packages", regex->pattern); + if (matchedCount == 0) { + for (auto & matcher : matchers) { + if (const size_t * index = std::get_if<size_t>(&matcher)){ + warn("'%d' is not a valid index", *index); + } else if (const Path * path = std::get_if<Path>(&matcher)){ + warn("'%s' does not match any paths", *path); + } else if (const RegexPattern * regex = std::get_if<RegexPattern>(&matcher)){ + warn("'%s' does not match any packages", regex->pattern); + } } + } else { + warn("Found some packages but none of them could be upgraded"); } warn ("Use 'nix profile list' to see the current profile."); } @@ -394,10 +444,18 @@ struct CmdProfileList : virtual EvalCommand, virtual StoreCommand, MixDefaultPro } else { for (size_t i = 0; i < manifest.elements.size(); ++i) { auto & element(manifest.elements[i]); - if (i) logger->cout(""); - logger->cout("Index: " ANSI_BOLD "%s" ANSI_NORMAL "%s", - i, - element.active ? "" : " " ANSI_RED "(inactive)" ANSI_NORMAL); + if (i) { + logger->cout(""); + } + logger->cout( + "Name: " ANSI_BOLD "%s" ANSI_NORMAL "%s", + element.name, + element.active ? "" : " " ANSI_RED "(inactive)" ANSI_NORMAL + ); + logger->cout( + "Index: " ANSI_BOLD "%s" ANSI_NORMAL "%S", + i + ); if (element.source) { logger->cout("Flake attribute: %s%s", element.source->attrPath, element.source->outputs.to_string()); logger->cout("Original flake URL: %s", element.source->originalRef.to_string()); |