diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2022-04-22 15:17:01 +0200 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2022-05-03 13:43:52 +0200 |
commit | 4a79cba5118f29b896f3d50164beacd4901ab01f (patch) | |
tree | 2159770446fb151e12bf82856b6418201ae23bbf /src/libcmd/installables.cc | |
parent | 404c222444b4c8c60148ccf890cd41611f26b0a0 (diff) |
Allow selecting derivation outputs using 'installable!outputs'
E.g. 'nixpkgs#glibc^dev,static' or 'nixpkgs#glibc^*'.
Diffstat (limited to 'src/libcmd/installables.cc')
-rw-r--r-- | src/libcmd/installables.cc | 48 |
1 files changed, 39 insertions, 9 deletions
diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index e2ee47dea..55a5e91e9 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -464,9 +464,19 @@ struct InstallableAttrPath : InstallableValue SourceExprCommand & cmd; RootValue v; std::string attrPath; - - InstallableAttrPath(ref<EvalState> state, SourceExprCommand & cmd, Value * v, const std::string & attrPath) - : InstallableValue(state), cmd(cmd), v(allocRootValue(v)), attrPath(attrPath) + OutputsSpec outputsSpec; + + InstallableAttrPath( + ref<EvalState> state, + SourceExprCommand & cmd, + Value * v, + const std::string & attrPath, + OutputsSpec outputsSpec) + : InstallableValue(state) + , cmd(cmd) + , v(allocRootValue(v)) + , attrPath(attrPath) + , outputsSpec(std::move(outputsSpec)) { } std::string what() const override { return attrPath; } @@ -495,9 +505,15 @@ std::vector<InstallableValue::DerivationInfo> InstallableAttrPath::toDerivations auto drvPath = drvInfo.queryDrvPath(); if (!drvPath) throw Error("'%s' is not a derivation", what()); + std::set<std::string> outputsToInstall; - for (auto & output : drvInfo.queryOutputs(false, true)) - outputsToInstall.insert(output.first); + + if (auto outputNames = std::get_if<OutputNames>(&outputsSpec)) + outputsToInstall = *outputNames; + else + for (auto & output : drvInfo.queryOutputs(false, std::get_if<DefaultOutputs>(&outputsSpec))) + outputsToInstall.insert(output.first); + res.push_back(DerivationInfo { .drvPath = *drvPath, .outputsToInstall = std::move(outputsToInstall) @@ -578,6 +594,7 @@ InstallableFlake::InstallableFlake( ref<EvalState> state, FlakeRef && flakeRef, std::string_view fragment, + OutputsSpec outputsSpec, Strings attrPaths, Strings prefixes, const flake::LockFlags & lockFlags) @@ -585,6 +602,7 @@ InstallableFlake::InstallableFlake( flakeRef(flakeRef), attrPaths(fragment == "" ? attrPaths : Strings{(std::string) fragment}), prefixes(fragment == "" ? Strings{} : prefixes), + outputsSpec(std::move(outputsSpec)), lockFlags(lockFlags) { if (cmd && cmd->getAutoArgs(*state)->size()) @@ -609,14 +627,19 @@ std::tuple<std::string, FlakeRef, InstallableValue::DerivationInfo> InstallableF for (auto & s : aOutputsToInstall->getListOfStrings()) outputsToInstall.insert(s); - if (outputsToInstall.empty()) + if (outputsToInstall.empty() || std::get_if<AllOutputs>(&outputsSpec)) { + outputsToInstall.clear(); if (auto aOutputs = attr->maybeGetAttr(state->sOutputs)) for (auto & s : aOutputs->getListOfStrings()) outputsToInstall.insert(s); + } if (outputsToInstall.empty()) outputsToInstall.insert("out"); + if (auto outputNames = std::get_if<OutputNames>(&outputsSpec)) + outputsToInstall = *outputNames; + auto drvInfo = DerivationInfo { .drvPath = std::move(drvPath), .outputsToInstall = std::move(outputsToInstall), @@ -742,8 +765,14 @@ std::vector<std::shared_ptr<Installable>> SourceExprCommand::parseInstallables( state->eval(e, *vFile); } - for (auto & s : ss) - result.push_back(std::make_shared<InstallableAttrPath>(state, *this, vFile, s == "." ? "" : s)); + for (auto & s : ss) { + auto [prefix, outputsSpec] = parseOutputsSpec(s); + result.push_back( + std::make_shared<InstallableAttrPath>( + state, *this, vFile, + prefix == "." ? "" : prefix, + outputsSpec)); + } } else { @@ -762,12 +791,13 @@ std::vector<std::shared_ptr<Installable>> SourceExprCommand::parseInstallables( } try { - auto [flakeRef, fragment] = parseFlakeRefWithFragment(s, absPath(".")); + auto [flakeRef, fragment, outputsSpec] = parseFlakeRefWithFragmentAndOutputsSpec(s, absPath(".")); result.push_back(std::make_shared<InstallableFlake>( this, getEvalState(), std::move(flakeRef), fragment, + outputsSpec, getDefaultFlakeAttrPaths(), getDefaultFlakeAttrPathPrefixes(), lockFlags)); |