Skip to content

Commit

Permalink
Merge pull request #6589 from edolstra/respect-output-specified
Browse files Browse the repository at this point in the history
Respect the outputSpecified attribute
  • Loading branch information
edolstra authored May 30, 2022
2 parents ec07a70 + 8e8e9d8 commit a72e75e
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 17 deletions.
3 changes: 0 additions & 3 deletions doc/manual/src/release-notes/rl-next.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 8 additions & 1 deletion src/libcmd/installables.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/libexpr/eval.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion src/libexpr/eval.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
37 changes: 25 additions & 12 deletions src/libexpr/get-drvs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}


Expand Down

0 comments on commit a72e75e

Please sign in to comment.