1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-24 18:01:16 +02:00

nix-env: add a --priority flag to --install

nix-env can read priorities from a derivations meta attributes, but this
only works when installing a nix expression.

nix-env can also install bare store paths, however meta attributes are
not readable in that case. This means that a store path can not be
installed with a specific priority.

Some cases where it is advantageous to install a store path: a remote
host following a `nix copy`, or any time you want to save some
evaluation time and happen to already know the store path.

This PR addresses this shortcoming by adding a --priority flag to
nix-env --install.
This commit is contained in:
Andy Hamon 2025-01-16 00:24:47 -08:00
parent 0c101679b4
commit 3716ded8df
3 changed files with 37 additions and 14 deletions

View file

@ -11,6 +11,7 @@
[`--from-profile` *path*]
[`--preserve-installed` | `-P`]
[`--remove-all` | `-r`]
[`--priority` *priority*]
# Description
@ -61,6 +62,10 @@ The arguments *args* map to store paths in a number of possible ways:
The derivations returned by those function calls are installed.
This allows derivations to be specified in an unambiguous way, which is necessary if there are multiple derivations with the same name.
- If `--priority` *priority* is given, the priority of the derivations being installed is set to *priority*.
This can be used to override the priority of the derivations being installed.
This is useful if *args* are [store paths], which don't have any priority information.
- If *args* are [store derivations](@docroot@/glossary.md#gloss-store-derivation), then these are [realised], and the resulting output paths are installed.
- If *args* are [store paths] that are not store derivations, then these are [realised] and installed.
@ -235,4 +240,3 @@ channel:
```console
$ nix-env --file https://github.com/NixOS/nixpkgs/archive/nixos-14.12.tar.gz --install --attr firefox
```

View file

@ -501,9 +501,17 @@ static bool keep(PackageInfo & drv)
return drv.queryMetaBool("keep", false);
}
static void setMetaFlag(EvalState & state, PackageInfo & drv,
const std::string & name, const std::string & value)
{
auto v = state.allocValue();
v->mkString(value);
drv.setMeta(name, v);
}
static void installDerivations(Globals & globals,
const Strings & args, const Path & profile)
const Strings & args, const Path & profile, std::optional<int> priority)
{
debug("installing derivations");
@ -527,6 +535,11 @@ static void installDerivations(Globals & globals,
newNames.insert(DrvName(i.queryName()).name);
}
if (priority) {
for (auto & drv : newElems) {
setMetaFlag(*globals.state, drv, "priority", std::to_string((priority.value())));
}
}
while (true) {
auto lockToken = optimisticLockProfile(profile);
@ -564,6 +577,7 @@ static void installDerivations(Globals & globals,
static void opInstall(Globals & globals, Strings opFlags, Strings opArgs)
{
std::optional<int> priority;
for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) {
auto arg = *i++;
if (parseInstallSourceOptions(globals, i, opFlags, arg)) ;
@ -571,10 +585,15 @@ static void opInstall(Globals & globals, Strings opFlags, Strings opArgs)
globals.preserveInstalled = true;
else if (arg == "--remove-all" || arg == "-r")
globals.removeAll = true;
else if (arg == "--priority") {
if (i == opFlags.end())
throw UsageError("'%1%' requires an argument", arg);
priority = std::stoi(*i++);
}
else throw UsageError("unknown flag '%1%'", arg);
}
installDerivations(globals, opArgs, globals.profile);
installDerivations(globals, opArgs, globals.profile, priority);
}
@ -689,15 +708,6 @@ static void opUpgrade(Globals & globals, Strings opFlags, Strings opArgs)
}
static void setMetaFlag(EvalState & state, PackageInfo & drv,
const std::string & name, const std::string & value)
{
auto v = state.allocValue();
v->mkString(value);
drv.setMeta(name, v);
}
static void opSetFlag(Globals & globals, Strings opFlags, Strings opArgs)
{
if (opFlags.size() > 0)
@ -1507,7 +1517,8 @@ static int main_nix_env(int argc, char * * argv)
opFlags.push_back(*arg);
/* FIXME: hacky */
if (*arg == "--from-profile" ||
(op == opQuery && (*arg == "--attr" || *arg == "-A")))
(op == opQuery && (*arg == "--attr" || *arg == "-A")) ||
(op == opInstall && (*arg == "--priority")))
opFlags.push_back(getArg(*arg, arg, end));
}
else

View file

@ -173,13 +173,21 @@ nix-env -q '*' | grepQuiet bar-0.1.1
# Test priorities: foo-0.1 has a lower priority than foo-1.0, so it
# should be possible to install both without a collision. Also test
# --set-flag priority to manually override the declared priorities.
# '-i --priority' and '--set-flag priority' to manually override the
# declared priorities.
nix-env -e '*'
nix-env -i foo-0.1 foo-1.0
[ "$($profiles/test/bin/foo)" = "foo-1.0" ]
nix-env --set-flag priority 1 foo-0.1
[ "$($profiles/test/bin/foo)" = "foo-0.1" ]
# Priorities can be overridden with the --priority flag
nix-env -e '*'
nix-env -i foo-1.0
[ "$($profiles/test/bin/foo)" = "foo-1.0" ]
nix-env -i --priority 1 foo-0.1
[ "$($profiles/test/bin/foo)" = "foo-0.1" ]
# Test nix-env --set.
nix-env --set $outPath10
[ "$(nix-store -q --resolve $profiles/test)" = $outPath10 ]