diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index a94e60aca..3f6dfd592 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -609,7 +609,7 @@ InstallableFlake::InstallableFlake( throw UsageError("'--arg' and '--argstr' are incompatible with flakes"); } -std::tuple InstallableFlake::toDerivation() +std::tuple> InstallableFlake::toDerivation() { auto attr = getCursor(*state); @@ -621,11 +621,15 @@ std::tuple InstallableF auto drvPath = attr->forceDerivation(); std::set outputsToInstall; + std::optional priority; - if (auto aMeta = attr->maybeGetAttr(state->sMeta)) + if (auto aMeta = attr->maybeGetAttr(state->sMeta)) { if (auto aOutputsToInstall = aMeta->maybeGetAttr("outputsToInstall")) for (auto & s : aOutputsToInstall->getListOfStrings()) outputsToInstall.insert(s); + if (auto aPriority = aMeta->maybeGetAttr("priority")) + priority = aPriority->getInt(); + } if (outputsToInstall.empty() || std::get_if(&outputsSpec)) { outputsToInstall.clear(); @@ -643,9 +647,10 @@ std::tuple InstallableF auto drvInfo = DerivationInfo { .drvPath = std::move(drvPath), .outputsToInstall = std::move(outputsToInstall), + .priority = priority, }; - return {attrPath, getLockedFlake()->flake.lockedRef, std::move(drvInfo)}; + return {attrPath, getLockedFlake()->flake.lockedRef, std::move(drvInfo), priority}; } std::vector InstallableFlake::toDerivations() diff --git a/src/libcmd/installables.hh b/src/libcmd/installables.hh index 1a5a96153..d7b61f1b8 100644 --- a/src/libcmd/installables.hh +++ b/src/libcmd/installables.hh @@ -142,6 +142,7 @@ struct InstallableValue : Installable { StorePath drvPath; std::set outputsToInstall; + std::optional priority; }; virtual std::vector toDerivations() = 0; @@ -176,7 +177,7 @@ struct InstallableFlake : InstallableValue Value * getFlakeOutputs(EvalState & state, const flake::LockedFlake & lockedFlake); - std::tuple toDerivation(); + std::tuple> toDerivation(); std::vector toDerivations() override; diff --git a/src/libexpr/eval-cache.cc b/src/libexpr/eval-cache.cc index 0eb4bc79e..b4bce512b 100644 --- a/src/libexpr/eval-cache.cc +++ b/src/libexpr/eval-cache.cc @@ -621,6 +621,28 @@ bool AttrCursor::getBool() return v.boolean; } +NixInt AttrCursor::getInt() +{ + if (root->db) { + if (!cachedValue) + cachedValue = root->db->getAttr(getKey()); + if (cachedValue && !std::get_if(&cachedValue->second)) { + if (auto i = std::get_if(&cachedValue->second)) { + debug("using cached Integer attribute '%s'", getAttrPathStr()); + return *i; + } else + throw TypeError("'%s' is not an Integer", getAttrPathStr()); + } + } + + auto & v = forceValue(); + + if (v.type() != nInt) + throw TypeError("'%s' is not an Integer", getAttrPathStr()); + + return v.integer; +} + std::vector AttrCursor::getListOfStrings() { if (root->db) { diff --git a/src/libexpr/eval-cache.hh b/src/libexpr/eval-cache.hh index 636e293ad..105e9217b 100644 --- a/src/libexpr/eval-cache.hh +++ b/src/libexpr/eval-cache.hh @@ -63,6 +63,7 @@ typedef std::variant< misc_t, failed_t, bool, + NixInt, std::vector > AttrValue; @@ -116,6 +117,8 @@ public: bool getBool(); + NixInt getInt(); + std::vector getListOfStrings(); std::vector getAttrs(); diff --git a/src/libstore/builtins/buildenv.cc b/src/libstore/builtins/buildenv.cc index c17c76e71..58ef89a1c 100644 --- a/src/libstore/builtins/buildenv.cc +++ b/src/libstore/builtins/buildenv.cc @@ -95,7 +95,7 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir, throw Error( "files '%1%' and '%2%' have the same priority %3%; " "use 'nix-env --set-flag priority NUMBER INSTALLED_PKGNAME' " - "or 'nix profile --priority NUMBER INSTALLED_PKGNAME' " + "or 'nix profile install --priority NUMBER INSTALLED_PKGNAME' " "to change the priority of one of the conflicting packages" " (0 being the highest priority)", srcFile, readLink(dstFile), priority); diff --git a/src/nix/profile.cc b/src/nix/profile.cc index fb8bef670..ca5041873 100644 --- a/src/nix/profile.cc +++ b/src/nix/profile.cc @@ -269,14 +269,7 @@ struct CmdProfileInstall : InstallablesCommand, MixDefaultProfile .longName = "priority", .description = "The priority of the package to install.", .labels = {"priority"}, - .handler = {[&](std::string s) { - try{ - priority = std::stoi(s); - } catch (std::invalid_argument & e) { - throw ParseError("invalid priority '%s'", s); - } - }}, - // .completer = // no completer since number + .handler = {&priority}, }); }; @@ -303,21 +296,27 @@ struct CmdProfileInstall : InstallablesCommand, MixDefaultProfile for (auto & installable : installables) { ProfileElement element; - if(priority) { - element.priority = *priority; - }; + if (auto installable2 = std::dynamic_pointer_cast(installable)) { // FIXME: make build() return this? - auto [attrPath, resolvedRef, drv] = installable2->toDerivation(); + auto [attrPath, resolvedRef, drv, priority] = installable2->toDerivation(); element.source = ProfileElementSource { installable2->flakeRef, resolvedRef, attrPath, installable2->outputsSpec }; + + if(drv.priority) { + element.priority = *drv.priority; + } } + if(priority) { // if --priority was specified we want to override the priority of the installable + element.priority = *priority; + }; + element.updateStorePaths(getEvalStore(), store, builtPaths[installable.get()]); manifest.elements.push_back(std::move(element)); @@ -476,7 +475,7 @@ struct CmdProfileUpgrade : virtual SourceExprCommand, MixDefaultProfile, MixProf Strings{}, lockFlags); - auto [attrPath, resolvedRef, drv] = installable->toDerivation(); + auto [attrPath, resolvedRef, drv, priority] = installable->toDerivation(); if (element.source->resolvedRef == resolvedRef) continue; diff --git a/tests/nix-profile.sh b/tests/nix-profile.sh index 1cc724483..7ba3235fa 100644 --- a/tests/nix-profile.sh +++ b/tests/nix-profile.sh @@ -136,3 +136,5 @@ nix profile install $flake2Dir --priority 100 [[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello World" ]] nix profile install $flake2Dir --priority 0 [[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello World2" ]] +# nix profile install $flake1Dir --priority 100 +# [[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello World" ]]