forked from lix-project/lix
Merge pull request #6522 from elikoga/master
Add priority for nix profile install
This commit is contained in:
commit
fdc97fc3f9
7 changed files with 103 additions and 5 deletions
|
@ -621,11 +621,15 @@ std::tuple<std::string, FlakeRef, InstallableValue::DerivationInfo> InstallableF
|
|||
auto drvPath = attr->forceDerivation();
|
||||
|
||||
std::set<std::string> outputsToInstall;
|
||||
std::optional<NixInt> 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<AllOutputs>(&outputsSpec)) {
|
||||
outputsToInstall.clear();
|
||||
|
@ -643,6 +647,7 @@ std::tuple<std::string, FlakeRef, InstallableValue::DerivationInfo> InstallableF
|
|||
auto drvInfo = DerivationInfo {
|
||||
.drvPath = std::move(drvPath),
|
||||
.outputsToInstall = std::move(outputsToInstall),
|
||||
.priority = priority,
|
||||
};
|
||||
|
||||
return {attrPath, getLockedFlake()->flake.lockedRef, std::move(drvInfo)};
|
||||
|
|
|
@ -142,6 +142,7 @@ struct InstallableValue : Installable
|
|||
{
|
||||
StorePath drvPath;
|
||||
std::set<std::string> outputsToInstall;
|
||||
std::optional<NixInt> priority;
|
||||
};
|
||||
|
||||
virtual std::vector<DerivationInfo> toDerivations() = 0;
|
||||
|
|
|
@ -47,7 +47,7 @@ struct AttrDb
|
|||
{
|
||||
auto state(_state->lock());
|
||||
|
||||
Path cacheDir = getCacheDir() + "/nix/eval-cache-v3";
|
||||
Path cacheDir = getCacheDir() + "/nix/eval-cache-v4";
|
||||
createDirs(cacheDir);
|
||||
|
||||
Path dbPath = cacheDir + "/" + fingerprint.to_string(Base16, false) + ".sqlite";
|
||||
|
@ -175,6 +175,24 @@ struct AttrDb
|
|||
});
|
||||
}
|
||||
|
||||
AttrId setInt(
|
||||
AttrKey key,
|
||||
int n)
|
||||
{
|
||||
return doSQLite([&]()
|
||||
{
|
||||
auto state(_state->lock());
|
||||
|
||||
state->insertAttribute.use()
|
||||
(key.first)
|
||||
(symbols[key.second])
|
||||
(AttrType::Int)
|
||||
(n).exec();
|
||||
|
||||
return state->db.getLastInsertedRowId();
|
||||
});
|
||||
}
|
||||
|
||||
AttrId setListOfStrings(
|
||||
AttrKey key,
|
||||
const std::vector<std::string> & l)
|
||||
|
@ -287,6 +305,8 @@ struct AttrDb
|
|||
}
|
||||
case AttrType::Bool:
|
||||
return {{rowId, queryAttribute.getInt(2) != 0}};
|
||||
case AttrType::Int:
|
||||
return {{rowId, int_t{queryAttribute.getInt(2)}}};
|
||||
case AttrType::ListOfStrings:
|
||||
return {{rowId, tokenizeString<std::vector<std::string>>(queryAttribute.getStr(2), "\t")}};
|
||||
case AttrType::Missing:
|
||||
|
@ -426,6 +446,8 @@ Value & AttrCursor::forceValue()
|
|||
cachedValue = {root->db->setString(getKey(), v.path), string_t{v.path, {}}};
|
||||
else if (v.type() == nBool)
|
||||
cachedValue = {root->db->setBool(getKey(), v.boolean), v.boolean};
|
||||
else if (v.type() == nInt)
|
||||
cachedValue = {root->db->setInt(getKey(), v.integer), int_t{v.integer}};
|
||||
else if (v.type() == nAttrs)
|
||||
; // FIXME: do something?
|
||||
else
|
||||
|
@ -621,6 +643,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<placeholder_t>(&cachedValue->second)) {
|
||||
if (auto i = std::get_if<int_t>(&cachedValue->second)) {
|
||||
debug("using cached Integer attribute '%s'", getAttrPathStr());
|
||||
return i->x;
|
||||
} 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<std::string> AttrCursor::getListOfStrings()
|
||||
{
|
||||
if (root->db) {
|
||||
|
|
|
@ -45,12 +45,14 @@ enum AttrType {
|
|||
Failed = 5,
|
||||
Bool = 6,
|
||||
ListOfStrings = 7,
|
||||
Int = 8,
|
||||
};
|
||||
|
||||
struct placeholder_t {};
|
||||
struct missing_t {};
|
||||
struct misc_t {};
|
||||
struct failed_t {};
|
||||
struct int_t { NixInt x; };
|
||||
typedef uint64_t AttrId;
|
||||
typedef std::pair<AttrId, Symbol> AttrKey;
|
||||
typedef std::pair<std::string, NixStringContext> string_t;
|
||||
|
@ -63,6 +65,7 @@ typedef std::variant<
|
|||
misc_t,
|
||||
failed_t,
|
||||
bool,
|
||||
int_t,
|
||||
std::vector<std::string>
|
||||
> AttrValue;
|
||||
|
||||
|
@ -116,6 +119,8 @@ public:
|
|||
|
||||
bool getBool();
|
||||
|
||||
NixInt getInt();
|
||||
|
||||
std::vector<std::string> getListOfStrings();
|
||||
|
||||
std::vector<Symbol> getAttrs();
|
||||
|
|
|
@ -93,8 +93,9 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir,
|
|||
auto prevPriority = state.priorities[dstFile];
|
||||
if (prevPriority == priority)
|
||||
throw Error(
|
||||
"packages '%1%' and '%2%' have the same priority %3%; "
|
||||
"files '%1%' and '%2%' have the same priority %3%; "
|
||||
"use 'nix-env --set-flag priority NUMBER INSTALLED_PKGNAME' "
|
||||
"or type 'nix profile install --help' if using 'nix profile' to find out how"
|
||||
"to change the priority of one of the conflicting packages"
|
||||
" (0 being the highest priority)",
|
||||
srcFile, readLink(dstFile), priority);
|
||||
|
|
|
@ -37,7 +37,7 @@ struct ProfileElement
|
|||
StorePathSet storePaths;
|
||||
std::optional<ProfileElementSource> source;
|
||||
bool active = true;
|
||||
// FIXME: priority
|
||||
int priority = 5;
|
||||
|
||||
std::string describe() const
|
||||
{
|
||||
|
@ -116,6 +116,9 @@ struct ProfileManifest
|
|||
for (auto & p : e["storePaths"])
|
||||
element.storePaths.insert(state.store->parseStorePath((std::string) p));
|
||||
element.active = e["active"];
|
||||
if(e.contains("priority")) {
|
||||
element.priority = e["priority"];
|
||||
}
|
||||
if (e.value(sUrl, "") != "") {
|
||||
element.source = ProfileElementSource {
|
||||
parseFlakeRef(e[sOriginalUrl]),
|
||||
|
@ -153,6 +156,7 @@ struct ProfileManifest
|
|||
nlohmann::json obj;
|
||||
obj["storePaths"] = paths;
|
||||
obj["active"] = element.active;
|
||||
obj["priority"] = element.priority;
|
||||
if (element.source) {
|
||||
obj["originalUrl"] = element.source->originalRef.to_string();
|
||||
obj["url"] = element.source->resolvedRef.to_string();
|
||||
|
@ -177,7 +181,7 @@ struct ProfileManifest
|
|||
for (auto & element : elements) {
|
||||
for (auto & path : element.storePaths) {
|
||||
if (element.active)
|
||||
pkgs.emplace_back(store->printStorePath(path), true, 5);
|
||||
pkgs.emplace_back(store->printStorePath(path), true, element.priority);
|
||||
references.insert(path);
|
||||
}
|
||||
}
|
||||
|
@ -259,6 +263,16 @@ builtPathsPerInstallable(
|
|||
|
||||
struct CmdProfileInstall : InstallablesCommand, MixDefaultProfile
|
||||
{
|
||||
std::optional<int> priority;
|
||||
CmdProfileInstall() {
|
||||
addFlag({
|
||||
.longName = "priority",
|
||||
.description = "The priority of the package to install.",
|
||||
.labels = {"priority"},
|
||||
.handler = {&priority},
|
||||
});
|
||||
};
|
||||
|
||||
std::string description() override
|
||||
{
|
||||
return "install a package into a profile";
|
||||
|
@ -282,6 +296,8 @@ struct CmdProfileInstall : InstallablesCommand, MixDefaultProfile
|
|||
for (auto & installable : installables) {
|
||||
ProfileElement element;
|
||||
|
||||
|
||||
|
||||
if (auto installable2 = std::dynamic_pointer_cast<InstallableFlake>(installable)) {
|
||||
// FIXME: make build() return this?
|
||||
auto [attrPath, resolvedRef, drv] = installable2->toDerivation();
|
||||
|
@ -291,8 +307,16 @@ struct CmdProfileInstall : InstallablesCommand, MixDefaultProfile
|
|||
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));
|
||||
|
|
|
@ -120,3 +120,21 @@ nix profile install "$flake1Dir^man"
|
|||
(! [ -e $TEST_HOME/.nix-profile/bin/hello ])
|
||||
[ -e $TEST_HOME/.nix-profile/share/man ]
|
||||
(! [ -e $TEST_HOME/.nix-profile/include ])
|
||||
|
||||
# test priority
|
||||
nix profile remove 0
|
||||
|
||||
# Make another flake.
|
||||
flake2Dir=$TEST_ROOT/flake2
|
||||
printf World > $flake1Dir/who
|
||||
cp -r $flake1Dir $flake2Dir
|
||||
printf World2 > $flake2Dir/who
|
||||
|
||||
nix profile install $flake1Dir
|
||||
[[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello World" ]]
|
||||
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" ]]
|
||||
|
|
Loading…
Reference in a new issue