mirror of
https://github.com/NixOS/nix
synced 2025-06-24 22:11:15 +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:
parent
0c101679b4
commit
3716ded8df
3 changed files with 37 additions and 14 deletions
|
@ -11,6 +11,7 @@
|
||||||
[`--from-profile` *path*]
|
[`--from-profile` *path*]
|
||||||
[`--preserve-installed` | `-P`]
|
[`--preserve-installed` | `-P`]
|
||||||
[`--remove-all` | `-r`]
|
[`--remove-all` | `-r`]
|
||||||
|
[`--priority` *priority*]
|
||||||
|
|
||||||
# Description
|
# 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.
|
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.
|
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 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.
|
- If *args* are [store paths] that are not store derivations, then these are [realised] and installed.
|
||||||
|
@ -235,4 +240,3 @@ channel:
|
||||||
```console
|
```console
|
||||||
$ nix-env --file https://github.com/NixOS/nixpkgs/archive/nixos-14.12.tar.gz --install --attr firefox
|
$ nix-env --file https://github.com/NixOS/nixpkgs/archive/nixos-14.12.tar.gz --install --attr firefox
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -501,9 +501,17 @@ static bool keep(PackageInfo & drv)
|
||||||
return drv.queryMetaBool("keep", false);
|
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,
|
static void installDerivations(Globals & globals,
|
||||||
const Strings & args, const Path & profile)
|
const Strings & args, const Path & profile, std::optional<int> priority)
|
||||||
{
|
{
|
||||||
debug("installing derivations");
|
debug("installing derivations");
|
||||||
|
|
||||||
|
@ -527,6 +535,11 @@ static void installDerivations(Globals & globals,
|
||||||
newNames.insert(DrvName(i.queryName()).name);
|
newNames.insert(DrvName(i.queryName()).name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (priority) {
|
||||||
|
for (auto & drv : newElems) {
|
||||||
|
setMetaFlag(*globals.state, drv, "priority", std::to_string((priority.value())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
auto lockToken = optimisticLockProfile(profile);
|
auto lockToken = optimisticLockProfile(profile);
|
||||||
|
@ -564,6 +577,7 @@ static void installDerivations(Globals & globals,
|
||||||
|
|
||||||
static void opInstall(Globals & globals, Strings opFlags, Strings opArgs)
|
static void opInstall(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
|
std::optional<int> priority;
|
||||||
for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) {
|
for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) {
|
||||||
auto arg = *i++;
|
auto arg = *i++;
|
||||||
if (parseInstallSourceOptions(globals, i, opFlags, arg)) ;
|
if (parseInstallSourceOptions(globals, i, opFlags, arg)) ;
|
||||||
|
@ -571,10 +585,15 @@ static void opInstall(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
globals.preserveInstalled = true;
|
globals.preserveInstalled = true;
|
||||||
else if (arg == "--remove-all" || arg == "-r")
|
else if (arg == "--remove-all" || arg == "-r")
|
||||||
globals.removeAll = true;
|
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);
|
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)
|
static void opSetFlag(Globals & globals, Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
if (opFlags.size() > 0)
|
if (opFlags.size() > 0)
|
||||||
|
@ -1507,7 +1517,8 @@ static int main_nix_env(int argc, char * * argv)
|
||||||
opFlags.push_back(*arg);
|
opFlags.push_back(*arg);
|
||||||
/* FIXME: hacky */
|
/* FIXME: hacky */
|
||||||
if (*arg == "--from-profile" ||
|
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));
|
opFlags.push_back(getArg(*arg, arg, end));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -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
|
# 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
|
# 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 -e '*'
|
||||||
nix-env -i foo-0.1 foo-1.0
|
nix-env -i foo-0.1 foo-1.0
|
||||||
[ "$($profiles/test/bin/foo)" = "foo-1.0" ]
|
[ "$($profiles/test/bin/foo)" = "foo-1.0" ]
|
||||||
nix-env --set-flag priority 1 foo-0.1
|
nix-env --set-flag priority 1 foo-0.1
|
||||||
[ "$($profiles/test/bin/foo)" = "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.
|
# Test nix-env --set.
|
||||||
nix-env --set $outPath10
|
nix-env --set $outPath10
|
||||||
[ "$(nix-store -q --resolve $profiles/test)" = $outPath10 ]
|
[ "$(nix-store -q --resolve $profiles/test)" = $outPath10 ]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue