Respect the outputSpecified attribute

E.g. 'nix build nixpkgs#libxml2.dev' will build the 'dev' output.
This commit is contained in:
Eelco Dolstra 2022-05-30 11:32:37 +02:00
parent ec07a70979
commit 8e8e9d8705
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
5 changed files with 36 additions and 17 deletions

View file

@ -22,9 +22,6 @@
`meta.outputsToInstall` attribute if it exists, or all outputs `meta.outputsToInstall` attribute if it exists, or all outputs
otherwise. 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 * 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 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 there one can inspect symbol values and evaluate nix expressions. In debug mode

View file

@ -623,7 +623,14 @@ std::tuple<std::string, FlakeRef, InstallableValue::DerivationInfo> InstallableF
std::set<std::string> outputsToInstall; std::set<std::string> outputsToInstall;
std::optional<NixInt> priority; 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")) if (auto aOutputsToInstall = aMeta->maybeGetAttr("outputsToInstall"))
for (auto & s : aOutputsToInstall->getListOfStrings()) for (auto & s : aOutputsToInstall->getListOfStrings())
outputsToInstall.insert(s); outputsToInstall.insert(s);

View file

@ -459,6 +459,7 @@ EvalState::EvalState(
, sKey(symbols.create("key")) , sKey(symbols.create("key"))
, sPath(symbols.create("path")) , sPath(symbols.create("path"))
, sPrefix(symbols.create("prefix")) , sPrefix(symbols.create("prefix"))
, sOutputSpecified(symbols.create("outputSpecified"))
, repair(NoRepair) , repair(NoRepair)
, emptyBindings(0) , emptyBindings(0)
, store(store) , store(store)

View file

@ -103,7 +103,8 @@ public:
sOutputHash, sOutputHashAlgo, sOutputHashMode, sOutputHash, sOutputHashAlgo, sOutputHashMode,
sRecurseForDerivations, sRecurseForDerivations,
sDescription, sSelf, sEpsilon, sStartSet, sOperator, sKey, sPath, sDescription, sSelf, sEpsilon, sStartSet, sOperator, sKey, sPath,
sPrefix; sPrefix,
sOutputSpecified;
Symbol sDerivationNix; Symbol sDerivationNix;
/* If set, force copying files to the Nix store even if they /* If set, force copying files to the Nix store even if they

View file

@ -132,23 +132,36 @@ DrvInfo::Outputs DrvInfo::queryOutputs(bool withPaths, bool onlyOutputsToInstall
} else } else
outputs.emplace("out", withPaths ? std::optional{queryOutPath()} : std::nullopt); outputs.emplace("out", withPaths ? std::optional{queryOutPath()} : std::nullopt);
} }
if (!onlyOutputsToInstall || !attrs) if (!onlyOutputsToInstall || !attrs)
return outputs; return outputs;
/* Check for `meta.outputsToInstall` and return `outputs` reduced to that. */ Bindings::iterator i;
const Value * outTI = queryMeta("outputsToInstall"); if (attrs && (i = attrs->find(state->sOutputSpecified)) != attrs->end() && state->forceBool(*i->value, i->pos)) {
if (!outTI) return outputs; Outputs result;
const auto errMsg = Error("this derivation has bad 'meta.outputsToInstall'"); auto out = outputs.find(queryOutputName());
/* ^ this shows during `nix-env -i` right under the bad derivation */ if (out == outputs.end())
if (!outTI->isList()) throw errMsg; throw Error("derivation does not have output '%s'", queryOutputName());
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); 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;
} }