aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2022-05-30 11:32:37 +0200
committerEelco Dolstra <edolstra@gmail.com>2022-05-30 11:34:47 +0200
commit8e8e9d8705a68e1be63d6d8059c6c07127826525 (patch)
treea55dcac2c7ce445798c239f024cda7a3429e624e
parentec07a70979a86cc436de7e46e03789b4606d25ab (diff)
Respect the outputSpecified attribute
E.g. 'nix build nixpkgs#libxml2.dev' will build the 'dev' output.
-rw-r--r--doc/manual/src/release-notes/rl-next.md3
-rw-r--r--src/libcmd/installables.cc9
-rw-r--r--src/libexpr/eval.cc1
-rw-r--r--src/libexpr/eval.hh3
-rw-r--r--src/libexpr/get-drvs.cc37
5 files changed, 36 insertions, 17 deletions
diff --git a/doc/manual/src/release-notes/rl-next.md b/doc/manual/src/release-notes/rl-next.md
index 878916dc9..7151751dd 100644
--- a/doc/manual/src/release-notes/rl-next.md
+++ b/doc/manual/src/release-notes/rl-next.md
@@ -22,9 +22,6 @@
`meta.outputsToInstall` attribute if it exists, or all outputs
otherwise.
- Selecting derivation outputs using the attribute selection syntax
- (e.g. `nixpkgs#glibc.dev`) no longer works.
-
* Running nix with the new `--debugger` flag will cause it to start a repl session if
there is an exception thrown during eval, or if `builtins.break` is called. From
there one can inspect symbol values and evaluate nix expressions. In debug mode
diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc
index 635ce19b6..21db2b08b 100644
--- a/src/libcmd/installables.cc
+++ b/src/libcmd/installables.cc
@@ -623,7 +623,14 @@ std::tuple<std::string, FlakeRef, InstallableValue::DerivationInfo> InstallableF
std::set<std::string> outputsToInstall;
std::optional<NixInt> priority;
- if (auto aMeta = attr->maybeGetAttr(state->sMeta)) {
+ if (auto aOutputSpecified = attr->maybeGetAttr(state->sOutputSpecified)) {
+ if (aOutputSpecified->getBool()) {
+ if (auto aOutputName = attr->maybeGetAttr("outputName"))
+ outputsToInstall = { aOutputName->getString() };
+ }
+ }
+
+ else if (auto aMeta = attr->maybeGetAttr(state->sMeta)) {
if (auto aOutputsToInstall = aMeta->maybeGetAttr("outputsToInstall"))
for (auto & s : aOutputsToInstall->getListOfStrings())
outputsToInstall.insert(s);
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 18baf1cb7..40462afdf 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -459,6 +459,7 @@ EvalState::EvalState(
, sKey(symbols.create("key"))
, sPath(symbols.create("path"))
, sPrefix(symbols.create("prefix"))
+ , sOutputSpecified(symbols.create("outputSpecified"))
, repair(NoRepair)
, emptyBindings(0)
, store(store)
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 0a32d5885..7b8732169 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -103,7 +103,8 @@ public:
sOutputHash, sOutputHashAlgo, sOutputHashMode,
sRecurseForDerivations,
sDescription, sSelf, sEpsilon, sStartSet, sOperator, sKey, sPath,
- sPrefix;
+ sPrefix,
+ sOutputSpecified;
Symbol sDerivationNix;
/* If set, force copying files to the Nix store even if they
diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc
index d616b3921..346741dd5 100644
--- a/src/libexpr/get-drvs.cc
+++ b/src/libexpr/get-drvs.cc
@@ -132,23 +132,36 @@ DrvInfo::Outputs DrvInfo::queryOutputs(bool withPaths, bool onlyOutputsToInstall
} else
outputs.emplace("out", withPaths ? std::optional{queryOutPath()} : std::nullopt);
}
+
if (!onlyOutputsToInstall || !attrs)
return outputs;
- /* Check for `meta.outputsToInstall` and return `outputs` reduced to that. */
- const Value * outTI = queryMeta("outputsToInstall");
- if (!outTI) return outputs;
- const auto errMsg = Error("this derivation has bad 'meta.outputsToInstall'");
- /* ^ this shows during `nix-env -i` right under the bad derivation */
- if (!outTI->isList()) throw errMsg;
- Outputs result;
- for (auto elem : outTI->listItems()) {
- if (elem->type() != nString) throw errMsg;
- auto out = outputs.find(elem->string.s);
- if (out == outputs.end()) throw errMsg;
+ Bindings::iterator i;
+ if (attrs && (i = attrs->find(state->sOutputSpecified)) != attrs->end() && state->forceBool(*i->value, i->pos)) {
+ Outputs result;
+ auto out = outputs.find(queryOutputName());
+ if (out == outputs.end())
+ throw Error("derivation does not have output '%s'", queryOutputName());
result.insert(*out);
+ return result;
+ }
+
+ else {
+ /* Check for `meta.outputsToInstall` and return `outputs` reduced to that. */
+ const Value * outTI = queryMeta("outputsToInstall");
+ if (!outTI) return outputs;
+ const auto errMsg = Error("this derivation has bad 'meta.outputsToInstall'");
+ /* ^ this shows during `nix-env -i` right under the bad derivation */
+ if (!outTI->isList()) throw errMsg;
+ Outputs result;
+ for (auto elem : outTI->listItems()) {
+ if (elem->type() != nString) throw errMsg;
+ auto out = outputs.find(elem->string.s);
+ if (out == outputs.end()) throw errMsg;
+ result.insert(*out);
+ }
+ return result;
}
- return result;
}