aboutsummaryrefslogtreecommitdiff
path: root/src/libcmd/installables.cc
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2022-04-19 11:53:27 +0200
committerGitHub <noreply@github.com>2022-04-19 11:53:27 +0200
commit018db1c42065715dc175880e887299b7da5aa093 (patch)
tree3c67be9145689c611eedac04fe55b035e1ee4fb0 /src/libcmd/installables.cc
parentcabd07d8b11a4a21f2f679b23fd10cdc9acb25ce (diff)
parentd89840b103e57e81e5245c3fe9edfbf7c3477ad5 (diff)
Merge pull request #6404 from edolstra/unify-flake-attr-eval
Make InstallableFlake::toValue() and toDerivation() behave consistently
Diffstat (limited to 'src/libcmd/installables.cc')
-rw-r--r--src/libcmd/installables.cc117
1 files changed, 53 insertions, 64 deletions
diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc
index 4e7262432..05e479739 100644
--- a/src/libcmd/installables.cc
+++ b/src/libcmd/installables.cc
@@ -346,16 +346,16 @@ DerivedPath Installable::toDerivedPath()
return std::move(buildables[0]);
}
-std::vector<std::pair<std::shared_ptr<eval_cache::AttrCursor>, std::string>>
+std::vector<ref<eval_cache::AttrCursor>>
Installable::getCursors(EvalState & state)
{
auto evalCache =
std::make_shared<nix::eval_cache::EvalCache>(std::nullopt, state,
[&]() { return toValue(state).first; });
- return {{evalCache->getRoot(), ""}};
+ return {evalCache->getRoot()};
}
-std::pair<std::shared_ptr<eval_cache::AttrCursor>, std::string>
+ref<eval_cache::AttrCursor>
Installable::getCursor(EvalState & state)
{
auto cursors = getCursors(state);
@@ -578,43 +578,21 @@ InstallableFlake::InstallableFlake(
std::tuple<std::string, FlakeRef, InstallableValue::DerivationInfo> InstallableFlake::toDerivation()
{
- auto lockedFlake = getLockedFlake();
-
- auto cache = openEvalCache(*state, lockedFlake);
- auto root = cache->getRoot();
-
- Suggestions suggestions;
-
- for (auto & attrPath : getActualAttrPaths()) {
- debug("trying flake output attribute '%s'", attrPath);
+ auto attr = getCursor(*state);
- auto attrOrSuggestions = root->findAlongAttrPath(
- parseAttrPath(*state, attrPath),
- true
- );
-
- if (!attrOrSuggestions) {
- suggestions += attrOrSuggestions.getSuggestions();
- continue;
- }
+ auto attrPath = attr->getAttrPathStr();
- auto attr = *attrOrSuggestions;
+ if (!attr->isDerivation())
+ throw Error("flake output attribute '%s' is not a derivation", attrPath);
- if (!attr->isDerivation())
- throw Error("flake output attribute '%s' is not a derivation", attrPath);
+ auto drvPath = attr->forceDerivation();
- auto drvPath = attr->forceDerivation();
-
- auto drvInfo = DerivationInfo {
- std::move(drvPath),
- attr->getAttr(state->sOutputName)->getString()
- };
-
- return {attrPath, lockedFlake->flake.lockedRef, std::move(drvInfo)};
- }
+ auto drvInfo = DerivationInfo {
+ std::move(drvPath),
+ attr->getAttr(state->sOutputName)->getString()
+ };
- throw Error(suggestions, "flake '%s' does not provide attribute %s",
- flakeRef, showAttrPaths(getActualAttrPaths()));
+ return {attrPath, getLockedFlake()->flake.lockedRef, std::move(drvInfo)};
}
std::vector<InstallableValue::DerivationInfo> InstallableFlake::toDerivations()
@@ -626,33 +604,10 @@ std::vector<InstallableValue::DerivationInfo> InstallableFlake::toDerivations()
std::pair<Value *, Pos> InstallableFlake::toValue(EvalState & state)
{
- auto lockedFlake = getLockedFlake();
-
- auto vOutputs = getFlakeOutputs(state, *lockedFlake);
-
- auto emptyArgs = state.allocBindings(0);
-
- Suggestions suggestions;
-
- for (auto & attrPath : getActualAttrPaths()) {
- try {
- auto [v, pos] = findAlongAttrPath(state, attrPath, *emptyArgs, *vOutputs);
- state.forceValue(*v, pos);
- return {v, pos};
- } catch (AttrPathNotFound & e) {
- suggestions += e.info().suggestions;
- }
- }
-
- throw Error(
- suggestions,
- "flake '%s' does not provide attribute %s",
- flakeRef,
- showAttrPaths(getActualAttrPaths())
- );
+ return {&getCursor(state)->forceValue(), noPos};
}
-std::vector<std::pair<std::shared_ptr<eval_cache::AttrCursor>, std::string>>
+std::vector<ref<eval_cache::AttrCursor>>
InstallableFlake::getCursors(EvalState & state)
{
auto evalCache = openEvalCache(state,
@@ -660,21 +615,55 @@ InstallableFlake::getCursors(EvalState & state)
auto root = evalCache->getRoot();
- std::vector<std::pair<std::shared_ptr<eval_cache::AttrCursor>, std::string>> res;
+ std::vector<ref<eval_cache::AttrCursor>> res;
for (auto & attrPath : getActualAttrPaths()) {
auto attr = root->findAlongAttrPath(parseAttrPath(state, attrPath));
- if (attr) res.push_back({*attr, attrPath});
+ if (attr) res.push_back(ref(*attr));
}
return res;
}
+ref<eval_cache::AttrCursor> InstallableFlake::getCursor(EvalState & state)
+{
+ auto lockedFlake = getLockedFlake();
+
+ auto cache = openEvalCache(state, lockedFlake);
+ auto root = cache->getRoot();
+
+ Suggestions suggestions;
+
+ auto attrPaths = getActualAttrPaths();
+
+ for (auto & attrPath : attrPaths) {
+ debug("trying flake output attribute '%s'", attrPath);
+
+ auto attrOrSuggestions = root->findAlongAttrPath(
+ parseAttrPath(state, attrPath),
+ true
+ );
+
+ if (!attrOrSuggestions) {
+ suggestions += attrOrSuggestions.getSuggestions();
+ continue;
+ }
+
+ return *attrOrSuggestions;
+ }
+
+ throw Error(
+ suggestions,
+ "flake '%s' does not provide attribute %s",
+ flakeRef,
+ showAttrPaths(attrPaths));
+}
+
std::shared_ptr<flake::LockedFlake> InstallableFlake::getLockedFlake() const
{
- flake::LockFlags lockFlagsApplyConfig = lockFlags;
- lockFlagsApplyConfig.applyNixConfig = true;
if (!_lockedFlake) {
+ flake::LockFlags lockFlagsApplyConfig = lockFlags;
+ lockFlagsApplyConfig.applyNixConfig = true;
_lockedFlake = std::make_shared<flake::LockedFlake>(lockFlake(*state, flakeRef, lockFlagsApplyConfig));
}
return _lockedFlake;