diff --git a/doc/manual/source/command-ref/nix-env/install.md b/doc/manual/source/command-ref/nix-env/install.md index 748dd1e7a..aa5c2fbba 100644 --- a/doc/manual/source/command-ref/nix-env/install.md +++ b/doc/manual/source/command-ref/nix-env/install.md @@ -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 ``` - diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index e9eb52708..fa6d6afb3 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -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 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 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 diff --git a/tests/functional/user-envs-test-case.sh b/tests/functional/user-envs-test-case.sh index 117c6c7a4..3483a4600 100644 --- a/tests/functional/user-envs-test-case.sh +++ b/tests/functional/user-envs-test-case.sh @@ -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 ]