libexpr: eval caches should not have an EvalState&
and for the same reason DrvInfo shouldn't, only even more so. the eval
cache infrastructure wants to be a wrapper around evaluation, with its
lifetimes fully decoupled from the lifetime of the wrapped evaluation.
this can't not create problems when eval lifetime must become bounded.
Change-Id: Ib8eec649995b4decd7290c2266322f67d73b6b46
This commit is contained in:
parent
8468dc65c7
commit
9ff702554d
|
@ -77,12 +77,12 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
|
||||||
|
|
||||||
auto attr = getCursor();
|
auto attr = getCursor();
|
||||||
|
|
||||||
auto attrPath = attr->getAttrPathStr();
|
auto attrPath = attr->getAttrPathStr(*state);
|
||||||
|
|
||||||
if (!attr->isDerivation()) {
|
if (!attr->isDerivation(*state)) {
|
||||||
|
|
||||||
// FIXME: use eval cache?
|
// FIXME: use eval cache?
|
||||||
auto v = attr->forceValue();
|
auto v = attr->forceValue(*state);
|
||||||
|
|
||||||
if (std::optional derivedPathWithInfo = trySinglePathToDerivedPaths(
|
if (std::optional derivedPathWithInfo = trySinglePathToDerivedPaths(
|
||||||
v,
|
v,
|
||||||
|
@ -100,14 +100,14 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto drvPath = attr->forceDerivation();
|
auto drvPath = attr->forceDerivation(*state);
|
||||||
|
|
||||||
std::optional<NixInt::Inner> priority;
|
std::optional<NixInt::Inner> priority;
|
||||||
|
|
||||||
if (attr->maybeGetAttr("outputSpecified")) {
|
if (attr->maybeGetAttr(*state, "outputSpecified")) {
|
||||||
} else if (auto aMeta = attr->maybeGetAttr("meta")) {
|
} else if (auto aMeta = attr->maybeGetAttr(*state, "meta")) {
|
||||||
if (auto aPriority = aMeta->maybeGetAttr("priority"))
|
if (auto aPriority = aMeta->maybeGetAttr(*state, "priority"))
|
||||||
priority = aPriority->getInt().value;
|
priority = aPriority->getInt(*state).value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {{
|
return {{
|
||||||
|
@ -116,14 +116,14 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
|
||||||
.outputs = std::visit(overloaded {
|
.outputs = std::visit(overloaded {
|
||||||
[&](const ExtendedOutputsSpec::Default & d) -> OutputsSpec {
|
[&](const ExtendedOutputsSpec::Default & d) -> OutputsSpec {
|
||||||
std::set<std::string> outputsToInstall;
|
std::set<std::string> outputsToInstall;
|
||||||
if (auto aOutputSpecified = attr->maybeGetAttr("outputSpecified")) {
|
if (auto aOutputSpecified = attr->maybeGetAttr(*state, "outputSpecified")) {
|
||||||
if (aOutputSpecified->getBool()) {
|
if (aOutputSpecified->getBool(*state)) {
|
||||||
if (auto aOutputName = attr->maybeGetAttr("outputName"))
|
if (auto aOutputName = attr->maybeGetAttr(*state, "outputName"))
|
||||||
outputsToInstall = { aOutputName->getString() };
|
outputsToInstall = { aOutputName->getString(*state) };
|
||||||
}
|
}
|
||||||
} else if (auto aMeta = attr->maybeGetAttr("meta")) {
|
} else if (auto aMeta = attr->maybeGetAttr(*state, "meta")) {
|
||||||
if (auto aOutputsToInstall = aMeta->maybeGetAttr("outputsToInstall"))
|
if (auto aOutputsToInstall = aMeta->maybeGetAttr(*state, "outputsToInstall"))
|
||||||
for (auto & s : aOutputsToInstall->getListOfStrings())
|
for (auto & s : aOutputsToInstall->getListOfStrings(*state))
|
||||||
outputsToInstall.insert(s);
|
outputsToInstall.insert(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
|
||||||
|
|
||||||
std::pair<Value *, PosIdx> InstallableFlake::toValue()
|
std::pair<Value *, PosIdx> InstallableFlake::toValue()
|
||||||
{
|
{
|
||||||
return {&getCursor()->forceValue(), noPos};
|
return {&getCursor()->forceValue(*state), noPos};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ref<eval_cache::AttrCursor>>
|
std::vector<ref<eval_cache::AttrCursor>>
|
||||||
|
@ -170,7 +170,7 @@ InstallableFlake::getCursors()
|
||||||
for (auto & attrPath : attrPaths) {
|
for (auto & attrPath : attrPaths) {
|
||||||
debug("trying flake output attribute '%s'", attrPath);
|
debug("trying flake output attribute '%s'", attrPath);
|
||||||
|
|
||||||
auto attr = root->findAlongAttrPath(parseAttrPath(attrPath));
|
auto attr = root->findAlongAttrPath(*state, parseAttrPath(attrPath));
|
||||||
if (attr) {
|
if (attr) {
|
||||||
res.push_back(ref(*attr));
|
res.push_back(ref(*attr));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -317,12 +317,12 @@ void completeFlakeRefWithFragment(
|
||||||
attrPath.pop_back();
|
attrPath.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto attr = root->findAlongAttrPath(attrPath);
|
auto attr = root->findAlongAttrPath(*evalState, attrPath);
|
||||||
if (!attr) continue;
|
if (!attr) continue;
|
||||||
|
|
||||||
for (auto & attr2 : (*attr)->getAttrs()) {
|
for (auto & attr2 : (*attr)->getAttrs(*evalState)) {
|
||||||
if (std::string_view attr2s = attr2; attr2s.starts_with(lastAttr)) {
|
if (std::string_view attr2s = attr2; attr2s.starts_with(lastAttr)) {
|
||||||
auto attrPath2 = (*attr)->getAttrPath(attr2s);
|
auto attrPath2 = (*attr)->getAttrPath(*evalState, attr2s);
|
||||||
/* Strip the attrpath prefix. */
|
/* Strip the attrpath prefix. */
|
||||||
attrPath2.erase(attrPath2.begin(), attrPath2.begin() + attrPathPrefix.size());
|
attrPath2.erase(attrPath2.begin(), attrPath2.begin() + attrPathPrefix.size());
|
||||||
completions.add(flakeRefS + "#" + prefixRoot + concatStringsSep(".", attrPath2));
|
completions.add(flakeRefS + "#" + prefixRoot + concatStringsSep(".", attrPath2));
|
||||||
|
@ -334,7 +334,7 @@ void completeFlakeRefWithFragment(
|
||||||
attrpaths. */
|
attrpaths. */
|
||||||
if (fragment.empty()) {
|
if (fragment.empty()) {
|
||||||
for (auto & attrPath : defaultFlakeAttrPaths) {
|
for (auto & attrPath : defaultFlakeAttrPaths) {
|
||||||
auto attr = root->findAlongAttrPath(parseAttrPath(attrPath));
|
auto attr = root->findAlongAttrPath(*evalState, parseAttrPath(attrPath));
|
||||||
if (!attr) continue;
|
if (!attr) continue;
|
||||||
completions.add(flakeRefS + "#" + prefixRoot);
|
completions.add(flakeRefS + "#" + prefixRoot);
|
||||||
}
|
}
|
||||||
|
|
|
@ -344,7 +344,6 @@ EvalCache::EvalCache(
|
||||||
EvalState & state,
|
EvalState & state,
|
||||||
RootLoader rootLoader)
|
RootLoader rootLoader)
|
||||||
: db(useCache ? makeAttrDb(*state.store, *useCache) : nullptr)
|
: db(useCache ? makeAttrDb(*state.store, *useCache) : nullptr)
|
||||||
, state(state)
|
|
||||||
, rootLoader(rootLoader)
|
, rootLoader(rootLoader)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -385,15 +384,15 @@ AttrKey AttrCursor::getKey()
|
||||||
return {parent->first->cachedValue->first, parent->second};
|
return {parent->first->cachedValue->first, parent->second};
|
||||||
}
|
}
|
||||||
|
|
||||||
Value & AttrCursor::getValue()
|
Value & AttrCursor::getValue(EvalState & state)
|
||||||
{
|
{
|
||||||
if (!_value) {
|
if (!_value) {
|
||||||
if (parent) {
|
if (parent) {
|
||||||
auto & vParent = parent->first->getValue();
|
auto & vParent = parent->first->getValue(state);
|
||||||
root->state.forceAttrs(vParent, noPos, "while searching for an attribute");
|
state.forceAttrs(vParent, noPos, "while searching for an attribute");
|
||||||
auto attr = vParent.attrs->get(root->state.symbols.create(parent->second));
|
auto attr = vParent.attrs->get(state.symbols.create(parent->second));
|
||||||
if (!attr)
|
if (!attr)
|
||||||
throw Error("attribute '%s' is unexpectedly missing", getAttrPathStr());
|
throw Error("attribute '%s' is unexpectedly missing", getAttrPathStr(state));
|
||||||
_value = allocRootValue(attr->value);
|
_value = allocRootValue(attr->value);
|
||||||
} else
|
} else
|
||||||
_value = allocRootValue(root->getRootValue());
|
_value = allocRootValue(root->getRootValue());
|
||||||
|
@ -401,43 +400,43 @@ Value & AttrCursor::getValue()
|
||||||
return **_value;
|
return **_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> AttrCursor::getAttrPath() const
|
std::vector<std::string> AttrCursor::getAttrPath(EvalState & state) const
|
||||||
{
|
{
|
||||||
if (parent) {
|
if (parent) {
|
||||||
auto attrPath = parent->first->getAttrPath();
|
auto attrPath = parent->first->getAttrPath(state);
|
||||||
attrPath.push_back(parent->second);
|
attrPath.push_back(parent->second);
|
||||||
return attrPath;
|
return attrPath;
|
||||||
} else
|
} else
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> AttrCursor::getAttrPath(std::string_view name) const
|
std::vector<std::string> AttrCursor::getAttrPath(EvalState & state, std::string_view name) const
|
||||||
{
|
{
|
||||||
auto attrPath = getAttrPath();
|
auto attrPath = getAttrPath(state);
|
||||||
attrPath.emplace_back(name);
|
attrPath.emplace_back(name);
|
||||||
return attrPath;
|
return attrPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AttrCursor::getAttrPathStr() const
|
std::string AttrCursor::getAttrPathStr(EvalState & state) const
|
||||||
{
|
{
|
||||||
return concatStringsSep(".", getAttrPath());
|
return concatStringsSep(".", getAttrPath(state));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AttrCursor::getAttrPathStr(std::string_view name) const
|
std::string AttrCursor::getAttrPathStr(EvalState & state, std::string_view name) const
|
||||||
{
|
{
|
||||||
return concatStringsSep(".", getAttrPath(name));
|
return concatStringsSep(".", getAttrPath(state, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
Value & AttrCursor::forceValue()
|
Value & AttrCursor::forceValue(EvalState & state)
|
||||||
{
|
{
|
||||||
debug("evaluating uncached attribute '%s'", getAttrPathStr());
|
debug("evaluating uncached attribute '%s'", getAttrPathStr(state));
|
||||||
|
|
||||||
auto & v = getValue();
|
auto & v = getValue(state);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
root->state.forceValue(v, noPos);
|
state.forceValue(v, noPos);
|
||||||
} catch (EvalError &) {
|
} catch (EvalError &) {
|
||||||
debug("setting '%s' to failed", getAttrPathStr());
|
debug("setting '%s' to failed", getAttrPathStr(state));
|
||||||
if (root->db)
|
if (root->db)
|
||||||
cachedValue = {root->db->setFailed(getKey()), failed_t()};
|
cachedValue = {root->db->setFailed(getKey()), failed_t()};
|
||||||
throw;
|
throw;
|
||||||
|
@ -464,13 +463,13 @@ Value & AttrCursor::forceValue()
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
Suggestions AttrCursor::getSuggestionsForAttr(const std::string & name)
|
Suggestions AttrCursor::getSuggestionsForAttr(EvalState & state, const std::string & name)
|
||||||
{
|
{
|
||||||
auto attrNames = getAttrs();
|
auto attrNames = getAttrs(state);
|
||||||
return Suggestions::bestMatches({attrNames.begin(), attrNames.end()}, name);
|
return Suggestions::bestMatches({attrNames.begin(), attrNames.end()}, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<AttrCursor> AttrCursor::maybeGetAttr(const std::string & name)
|
std::shared_ptr<AttrCursor> AttrCursor::maybeGetAttr(EvalState & state, const std::string & name)
|
||||||
{
|
{
|
||||||
if (root->db) {
|
if (root->db) {
|
||||||
if (!cachedValue)
|
if (!cachedValue)
|
||||||
|
@ -488,7 +487,7 @@ std::shared_ptr<AttrCursor> AttrCursor::maybeGetAttr(const std::string & name)
|
||||||
if (std::get_if<missing_t>(&attr->second))
|
if (std::get_if<missing_t>(&attr->second))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
else if (std::get_if<failed_t>(&attr->second)) {
|
else if (std::get_if<failed_t>(&attr->second)) {
|
||||||
debug("reevaluating failed cached attribute '%s'", getAttrPathStr(name));
|
debug("reevaluating failed cached attribute '%s'", getAttrPathStr(state, name));
|
||||||
} else
|
} else
|
||||||
return std::make_shared<AttrCursor>(root,
|
return std::make_shared<AttrCursor>(root,
|
||||||
std::make_pair(shared_from_this(), name), nullptr, std::move(attr));
|
std::make_pair(shared_from_this(), name), nullptr, std::move(attr));
|
||||||
|
@ -501,13 +500,13 @@ std::shared_ptr<AttrCursor> AttrCursor::maybeGetAttr(const std::string & name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto & v = forceValue();
|
auto & v = forceValue(state);
|
||||||
|
|
||||||
if (v.type() != nAttrs)
|
if (v.type() != nAttrs)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
//errors.make<TypeError>("'%s' is not an attribute set", getAttrPathStr()).debugThrow();
|
//errors.make<TypeError>("'%s' is not an attribute set", getAttrPathStr()).debugThrow();
|
||||||
|
|
||||||
auto attr = v.attrs->get(root->state.symbols.create(name));
|
auto attr = v.attrs->get(state.symbols.create(name));
|
||||||
|
|
||||||
if (!attr) {
|
if (!attr) {
|
||||||
if (root->db) {
|
if (root->db) {
|
||||||
|
@ -529,21 +528,21 @@ std::shared_ptr<AttrCursor> AttrCursor::maybeGetAttr(const std::string & name)
|
||||||
root, std::make_pair(shared_from_this(), name), attr->value, std::move(cachedValue2));
|
root, std::make_pair(shared_from_this(), name), attr->value, std::move(cachedValue2));
|
||||||
}
|
}
|
||||||
|
|
||||||
ref<AttrCursor> AttrCursor::getAttr(const std::string & name)
|
ref<AttrCursor> AttrCursor::getAttr(EvalState & state, const std::string & name)
|
||||||
{
|
{
|
||||||
auto p = maybeGetAttr(name);
|
auto p = maybeGetAttr(state, name);
|
||||||
if (!p)
|
if (!p)
|
||||||
throw Error("attribute '%s' does not exist", getAttrPathStr(name));
|
throw Error("attribute '%s' does not exist", getAttrPathStr(state, name));
|
||||||
return ref(p);
|
return ref(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
OrSuggestions<ref<AttrCursor>> AttrCursor::findAlongAttrPath(const Strings & attrPath)
|
OrSuggestions<ref<AttrCursor>> AttrCursor::findAlongAttrPath(EvalState & state, const Strings & attrPath)
|
||||||
{
|
{
|
||||||
auto res = shared_from_this();
|
auto res = shared_from_this();
|
||||||
for (auto & attr : attrPath) {
|
for (auto & attr : attrPath) {
|
||||||
auto child = res->maybeGetAttr(attr);
|
auto child = res->maybeGetAttr(state, attr);
|
||||||
if (!child) {
|
if (!child) {
|
||||||
auto suggestions = res->getSuggestionsForAttr(attr);
|
auto suggestions = res->getSuggestionsForAttr(state, attr);
|
||||||
return OrSuggestions<ref<AttrCursor>>::failed(suggestions);
|
return OrSuggestions<ref<AttrCursor>>::failed(suggestions);
|
||||||
}
|
}
|
||||||
res = child;
|
res = child;
|
||||||
|
@ -551,30 +550,30 @@ OrSuggestions<ref<AttrCursor>> AttrCursor::findAlongAttrPath(const Strings & att
|
||||||
return ref(res);
|
return ref(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AttrCursor::getString()
|
std::string AttrCursor::getString(EvalState & state)
|
||||||
{
|
{
|
||||||
if (root->db) {
|
if (root->db) {
|
||||||
if (!cachedValue)
|
if (!cachedValue)
|
||||||
cachedValue = root->db->getAttr(getKey());
|
cachedValue = root->db->getAttr(getKey());
|
||||||
if (cachedValue && !std::get_if<placeholder_t>(&cachedValue->second)) {
|
if (cachedValue && !std::get_if<placeholder_t>(&cachedValue->second)) {
|
||||||
if (auto s = std::get_if<string_t>(&cachedValue->second)) {
|
if (auto s = std::get_if<string_t>(&cachedValue->second)) {
|
||||||
debug("using cached string attribute '%s'", getAttrPathStr());
|
debug("using cached string attribute '%s'", getAttrPathStr(state));
|
||||||
return s->first;
|
return s->first;
|
||||||
} else
|
} else
|
||||||
root->state.errors.make<TypeError>("'%s' is not a string", getAttrPathStr()).debugThrow();
|
state.errors.make<TypeError>("'%s' is not a string", getAttrPathStr(state)).debugThrow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto & v = forceValue();
|
auto & v = forceValue(state);
|
||||||
|
|
||||||
if (v.type() != nString && v.type() != nPath) {
|
if (v.type() != nString && v.type() != nPath) {
|
||||||
root->state.errors.make<TypeError>("'%s' is not a string but %s", getAttrPathStr(), v.type()).debugThrow();
|
state.errors.make<TypeError>("'%s' is not a string but %s", getAttrPathStr(state), v.type()).debugThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
return v.type() == nString ? v.string.s : v.path().to_string();
|
return v.type() == nString ? v.string.s : v.path().to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
string_t AttrCursor::getStringWithContext()
|
string_t AttrCursor::getStringWithContext(EvalState & state)
|
||||||
{
|
{
|
||||||
if (root->db) {
|
if (root->db) {
|
||||||
if (!cachedValue)
|
if (!cachedValue)
|
||||||
|
@ -594,21 +593,21 @@ string_t AttrCursor::getStringWithContext()
|
||||||
return o.path;
|
return o.path;
|
||||||
},
|
},
|
||||||
}, c.raw);
|
}, c.raw);
|
||||||
if (!root->state.store->isValidPath(path)) {
|
if (!state.store->isValidPath(path)) {
|
||||||
valid = false;
|
valid = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (valid) {
|
if (valid) {
|
||||||
debug("using cached string attribute '%s'", getAttrPathStr());
|
debug("using cached string attribute '%s'", getAttrPathStr(state));
|
||||||
return *s;
|
return *s;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
root->state.errors.make<TypeError>("'%s' is not a string", getAttrPathStr()).debugThrow();
|
state.errors.make<TypeError>("'%s' is not a string", getAttrPathStr(state)).debugThrow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto & v = forceValue();
|
auto & v = forceValue(state);
|
||||||
|
|
||||||
if (v.type() == nString) {
|
if (v.type() == nString) {
|
||||||
NixStringContext context;
|
NixStringContext context;
|
||||||
|
@ -617,80 +616,80 @@ string_t AttrCursor::getStringWithContext()
|
||||||
} else if (v.type() == nPath) {
|
} else if (v.type() == nPath) {
|
||||||
return {v.path().to_string(), {}};
|
return {v.path().to_string(), {}};
|
||||||
} else {
|
} else {
|
||||||
root->state.errors.make<TypeError>("'%s' is not a string but %s", getAttrPathStr(), v.type()).debugThrow();
|
state.errors.make<TypeError>("'%s' is not a string but %s", getAttrPathStr(state), v.type()).debugThrow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AttrCursor::getBool()
|
bool AttrCursor::getBool(EvalState & state)
|
||||||
{
|
{
|
||||||
if (root->db) {
|
if (root->db) {
|
||||||
if (!cachedValue)
|
if (!cachedValue)
|
||||||
cachedValue = root->db->getAttr(getKey());
|
cachedValue = root->db->getAttr(getKey());
|
||||||
if (cachedValue && !std::get_if<placeholder_t>(&cachedValue->second)) {
|
if (cachedValue && !std::get_if<placeholder_t>(&cachedValue->second)) {
|
||||||
if (auto b = std::get_if<bool>(&cachedValue->second)) {
|
if (auto b = std::get_if<bool>(&cachedValue->second)) {
|
||||||
debug("using cached Boolean attribute '%s'", getAttrPathStr());
|
debug("using cached Boolean attribute '%s'", getAttrPathStr(state));
|
||||||
return *b;
|
return *b;
|
||||||
} else
|
} else
|
||||||
root->state.errors.make<TypeError>("'%s' is not a Boolean", getAttrPathStr()).debugThrow();
|
state.errors.make<TypeError>("'%s' is not a Boolean", getAttrPathStr(state)).debugThrow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto & v = forceValue();
|
auto & v = forceValue(state);
|
||||||
|
|
||||||
if (v.type() != nBool)
|
if (v.type() != nBool)
|
||||||
root->state.errors.make<TypeError>("'%s' is not a Boolean", getAttrPathStr()).debugThrow();
|
state.errors.make<TypeError>("'%s' is not a Boolean", getAttrPathStr(state)).debugThrow();
|
||||||
|
|
||||||
return v.boolean;
|
return v.boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
NixInt AttrCursor::getInt()
|
NixInt AttrCursor::getInt(EvalState & state)
|
||||||
{
|
{
|
||||||
if (root->db) {
|
if (root->db) {
|
||||||
if (!cachedValue)
|
if (!cachedValue)
|
||||||
cachedValue = root->db->getAttr(getKey());
|
cachedValue = root->db->getAttr(getKey());
|
||||||
if (cachedValue && !std::get_if<placeholder_t>(&cachedValue->second)) {
|
if (cachedValue && !std::get_if<placeholder_t>(&cachedValue->second)) {
|
||||||
if (auto i = std::get_if<int_t>(&cachedValue->second)) {
|
if (auto i = std::get_if<int_t>(&cachedValue->second)) {
|
||||||
debug("using cached integer attribute '%s'", getAttrPathStr());
|
debug("using cached integer attribute '%s'", getAttrPathStr(state));
|
||||||
return i->x;
|
return i->x;
|
||||||
} else
|
} else
|
||||||
root->state.errors.make<TypeError>("'%s' is not an integer", getAttrPathStr()).debugThrow();
|
state.errors.make<TypeError>("'%s' is not an integer", getAttrPathStr(state)).debugThrow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto & v = forceValue();
|
auto & v = forceValue(state);
|
||||||
|
|
||||||
if (v.type() != nInt)
|
if (v.type() != nInt)
|
||||||
root->state.errors.make<TypeError>("'%s' is not an integer", getAttrPathStr()).debugThrow();
|
state.errors.make<TypeError>("'%s' is not an integer", getAttrPathStr(state)).debugThrow();
|
||||||
|
|
||||||
return v.integer;
|
return v.integer;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> AttrCursor::getListOfStrings()
|
std::vector<std::string> AttrCursor::getListOfStrings(EvalState & state)
|
||||||
{
|
{
|
||||||
if (root->db) {
|
if (root->db) {
|
||||||
if (!cachedValue)
|
if (!cachedValue)
|
||||||
cachedValue = root->db->getAttr(getKey());
|
cachedValue = root->db->getAttr(getKey());
|
||||||
if (cachedValue && !std::get_if<placeholder_t>(&cachedValue->second)) {
|
if (cachedValue && !std::get_if<placeholder_t>(&cachedValue->second)) {
|
||||||
if (auto l = std::get_if<std::vector<std::string>>(&cachedValue->second)) {
|
if (auto l = std::get_if<std::vector<std::string>>(&cachedValue->second)) {
|
||||||
debug("using cached list of strings attribute '%s'", getAttrPathStr());
|
debug("using cached list of strings attribute '%s'", getAttrPathStr(state));
|
||||||
return *l;
|
return *l;
|
||||||
} else
|
} else
|
||||||
root->state.errors.make<TypeError>("'%s' is not a list of strings", getAttrPathStr()).debugThrow();
|
state.errors.make<TypeError>("'%s' is not a list of strings", getAttrPathStr(state)).debugThrow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("evaluating uncached attribute '%s'", getAttrPathStr());
|
debug("evaluating uncached attribute '%s'", getAttrPathStr(state));
|
||||||
|
|
||||||
auto & v = getValue();
|
auto & v = getValue(state);
|
||||||
root->state.forceValue(v, noPos);
|
state.forceValue(v, noPos);
|
||||||
|
|
||||||
if (v.type() != nList)
|
if (v.type() != nList)
|
||||||
root->state.errors.make<TypeError>("'%s' is not a list", getAttrPathStr()).debugThrow();
|
state.errors.make<TypeError>("'%s' is not a list", getAttrPathStr(state)).debugThrow();
|
||||||
|
|
||||||
std::vector<std::string> res;
|
std::vector<std::string> res;
|
||||||
|
|
||||||
for (auto & elem : v.listItems())
|
for (auto & elem : v.listItems())
|
||||||
res.push_back(std::string(root->state.forceStringNoCtx(*elem, noPos, "while evaluating an attribute for caching")));
|
res.push_back(std::string(state.forceStringNoCtx(*elem, noPos, "while evaluating an attribute for caching")));
|
||||||
|
|
||||||
if (root->db)
|
if (root->db)
|
||||||
cachedValue = {root->db->setListOfStrings(getKey(), res), res};
|
cachedValue = {root->db->setListOfStrings(getKey(), res), res};
|
||||||
|
@ -698,28 +697,28 @@ std::vector<std::string> AttrCursor::getListOfStrings()
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> AttrCursor::getAttrs()
|
std::vector<std::string> AttrCursor::getAttrs(EvalState & state)
|
||||||
{
|
{
|
||||||
if (root->db) {
|
if (root->db) {
|
||||||
if (!cachedValue)
|
if (!cachedValue)
|
||||||
cachedValue = root->db->getAttr(getKey());
|
cachedValue = root->db->getAttr(getKey());
|
||||||
if (cachedValue && !std::get_if<placeholder_t>(&cachedValue->second)) {
|
if (cachedValue && !std::get_if<placeholder_t>(&cachedValue->second)) {
|
||||||
if (auto attrs = std::get_if<fullattr_t>(&cachedValue->second)) {
|
if (auto attrs = std::get_if<fullattr_t>(&cachedValue->second)) {
|
||||||
debug("using cached attrset attribute '%s'", getAttrPathStr());
|
debug("using cached attrset attribute '%s'", getAttrPathStr(state));
|
||||||
return attrs->p;
|
return attrs->p;
|
||||||
} else
|
} else
|
||||||
root->state.errors.make<TypeError>("'%s' is not an attribute set", getAttrPathStr()).debugThrow();
|
state.errors.make<TypeError>("'%s' is not an attribute set", getAttrPathStr(state)).debugThrow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto & v = forceValue();
|
auto & v = forceValue(state);
|
||||||
|
|
||||||
if (v.type() != nAttrs)
|
if (v.type() != nAttrs)
|
||||||
root->state.errors.make<TypeError>("'%s' is not an attribute set", getAttrPathStr()).debugThrow();
|
state.errors.make<TypeError>("'%s' is not an attribute set", getAttrPathStr(state)).debugThrow();
|
||||||
|
|
||||||
fullattr_t attrs;
|
fullattr_t attrs;
|
||||||
for (auto & attr : *getValue().attrs)
|
for (auto & attr : *getValue(state).attrs)
|
||||||
attrs.p.push_back(root->state.symbols[attr.name]);
|
attrs.p.push_back(state.symbols[attr.name]);
|
||||||
std::sort(attrs.p.begin(), attrs.p.end());
|
std::sort(attrs.p.begin(), attrs.p.end());
|
||||||
|
|
||||||
if (root->db)
|
if (root->db)
|
||||||
|
@ -728,23 +727,23 @@ std::vector<std::string> AttrCursor::getAttrs()
|
||||||
return attrs.p;
|
return attrs.p;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AttrCursor::isDerivation()
|
bool AttrCursor::isDerivation(EvalState & state)
|
||||||
{
|
{
|
||||||
auto aType = maybeGetAttr("type");
|
auto aType = maybeGetAttr(state, "type");
|
||||||
return aType && aType->getString() == "derivation";
|
return aType && aType->getString(state) == "derivation";
|
||||||
}
|
}
|
||||||
|
|
||||||
StorePath AttrCursor::forceDerivation()
|
StorePath AttrCursor::forceDerivation(EvalState & state)
|
||||||
{
|
{
|
||||||
auto aDrvPath = getAttr("drvPath");
|
auto aDrvPath = getAttr(state, "drvPath");
|
||||||
auto drvPath = root->state.store->parseStorePath(aDrvPath->getString());
|
auto drvPath = state.store->parseStorePath(aDrvPath->getString(state));
|
||||||
if (!root->state.store->isValidPath(drvPath) && !settings.readOnlyMode) {
|
if (!state.store->isValidPath(drvPath) && !settings.readOnlyMode) {
|
||||||
/* The eval cache contains 'drvPath', but the actual path has
|
/* The eval cache contains 'drvPath', but the actual path has
|
||||||
been garbage-collected. So force it to be regenerated. */
|
been garbage-collected. So force it to be regenerated. */
|
||||||
aDrvPath->forceValue();
|
aDrvPath->forceValue(state);
|
||||||
if (!root->state.store->isValidPath(drvPath))
|
if (!state.store->isValidPath(drvPath))
|
||||||
throw Error("don't know how to recreate store derivation '%s'!",
|
throw Error("don't know how to recreate store derivation '%s'!",
|
||||||
root->state.store->printStorePath(drvPath));
|
state.store->printStorePath(drvPath));
|
||||||
}
|
}
|
||||||
return drvPath;
|
return drvPath;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,6 @@ class EvalCache : public std::enable_shared_from_this<EvalCache>
|
||||||
friend class AttrCursor;
|
friend class AttrCursor;
|
||||||
|
|
||||||
std::shared_ptr<AttrDb> db;
|
std::shared_ptr<AttrDb> db;
|
||||||
EvalState & state;
|
|
||||||
RootLoader rootLoader;
|
RootLoader rootLoader;
|
||||||
RootValue value;
|
RootValue value;
|
||||||
|
|
||||||
|
@ -102,7 +101,7 @@ class AttrCursor : public std::enable_shared_from_this<AttrCursor>
|
||||||
|
|
||||||
AttrKey getKey();
|
AttrKey getKey();
|
||||||
|
|
||||||
Value & getValue();
|
Value & getValue(EvalState & state);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -112,46 +111,46 @@ public:
|
||||||
Value * value = nullptr,
|
Value * value = nullptr,
|
||||||
std::optional<std::pair<AttrId, AttrValue>> && cachedValue = {});
|
std::optional<std::pair<AttrId, AttrValue>> && cachedValue = {});
|
||||||
|
|
||||||
std::vector<std::string> getAttrPath() const;
|
std::vector<std::string> getAttrPath(EvalState & state) const;
|
||||||
|
|
||||||
std::vector<std::string> getAttrPath(std::string_view name) const;
|
std::vector<std::string> getAttrPath(EvalState & state, std::string_view name) const;
|
||||||
|
|
||||||
std::string getAttrPathStr() const;
|
std::string getAttrPathStr(EvalState & state) const;
|
||||||
|
|
||||||
std::string getAttrPathStr(std::string_view name) const;
|
std::string getAttrPathStr(EvalState & state, std::string_view name) const;
|
||||||
|
|
||||||
Suggestions getSuggestionsForAttr(const std::string & name);
|
Suggestions getSuggestionsForAttr(EvalState & state, const std::string & name);
|
||||||
|
|
||||||
std::shared_ptr<AttrCursor> maybeGetAttr(const std::string & name);
|
std::shared_ptr<AttrCursor> maybeGetAttr(EvalState & state, const std::string & name);
|
||||||
|
|
||||||
ref<AttrCursor> getAttr(const std::string & name);
|
ref<AttrCursor> getAttr(EvalState & state, const std::string & name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an attribute along a chain of attrsets. Note that this does
|
* Get an attribute along a chain of attrsets. Note that this does
|
||||||
* not auto-call functors or functions.
|
* not auto-call functors or functions.
|
||||||
*/
|
*/
|
||||||
OrSuggestions<ref<AttrCursor>> findAlongAttrPath(const Strings & attrPath);
|
OrSuggestions<ref<AttrCursor>> findAlongAttrPath(EvalState & state, const Strings & attrPath);
|
||||||
|
|
||||||
std::string getString();
|
std::string getString(EvalState & state);
|
||||||
|
|
||||||
string_t getStringWithContext();
|
string_t getStringWithContext(EvalState & state);
|
||||||
|
|
||||||
bool getBool();
|
bool getBool(EvalState & state);
|
||||||
|
|
||||||
NixInt getInt();
|
NixInt getInt(EvalState & state);
|
||||||
|
|
||||||
std::vector<std::string> getListOfStrings();
|
std::vector<std::string> getListOfStrings(EvalState & state);
|
||||||
|
|
||||||
std::vector<std::string> getAttrs();
|
std::vector<std::string> getAttrs(EvalState & state);
|
||||||
|
|
||||||
bool isDerivation();
|
bool isDerivation(EvalState & state);
|
||||||
|
|
||||||
Value & forceValue();
|
Value & forceValue(EvalState & state);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Force creation of the .drv file in the Nix store.
|
* Force creation of the .drv file in the Nix store.
|
||||||
*/
|
*/
|
||||||
StorePath forceDerivation();
|
StorePath forceDerivation(EvalState & state);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,18 +54,18 @@ std::string resolveString(
|
||||||
UnresolvedApp InstallableValue::toApp()
|
UnresolvedApp InstallableValue::toApp()
|
||||||
{
|
{
|
||||||
auto cursor = getCursor();
|
auto cursor = getCursor();
|
||||||
auto attrPath = cursor->getAttrPath();
|
auto attrPath = cursor->getAttrPath(*state);
|
||||||
|
|
||||||
auto type = cursor->getAttr("type")->getString();
|
auto type = cursor->getAttr(*state, "type")->getString(*state);
|
||||||
|
|
||||||
std::string expected = !attrPath.empty() &&
|
std::string expected = !attrPath.empty() &&
|
||||||
(attrPath[0] == "apps" || attrPath[0] == "defaultApp")
|
(attrPath[0] == "apps" || attrPath[0] == "defaultApp")
|
||||||
? "app" : "derivation";
|
? "app" : "derivation";
|
||||||
if (type != expected)
|
if (type != expected)
|
||||||
throw Error("attribute '%s' should have type '%s'", cursor->getAttrPathStr(), expected);
|
throw Error("attribute '%s' should have type '%s'", cursor->getAttrPathStr(*state), expected);
|
||||||
|
|
||||||
if (type == "app") {
|
if (type == "app") {
|
||||||
auto [program, context] = cursor->getAttr("program")->getStringWithContext();
|
auto [program, context] = cursor->getAttr(*state, "program")->getStringWithContext(*state);
|
||||||
|
|
||||||
std::vector<DerivedPath> context2;
|
std::vector<DerivedPath> context2;
|
||||||
for (auto & c : context) {
|
for (auto & c : context) {
|
||||||
|
@ -98,18 +98,18 @@ UnresolvedApp InstallableValue::toApp()
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (type == "derivation") {
|
else if (type == "derivation") {
|
||||||
auto drvPath = cursor->forceDerivation();
|
auto drvPath = cursor->forceDerivation(*state);
|
||||||
auto outPath = cursor->getAttr("outPath")->getString();
|
auto outPath = cursor->getAttr(*state, "outPath")->getString(*state);
|
||||||
auto outputName = cursor->getAttr("outputName")->getString();
|
auto outputName = cursor->getAttr(*state, "outputName")->getString(*state);
|
||||||
auto name = cursor->getAttr("name")->getString();
|
auto name = cursor->getAttr(*state, "name")->getString(*state);
|
||||||
auto aPname = cursor->maybeGetAttr("pname");
|
auto aPname = cursor->maybeGetAttr(*state, "pname");
|
||||||
auto aMeta = cursor->maybeGetAttr("meta");
|
auto aMeta = cursor->maybeGetAttr(*state, "meta");
|
||||||
auto aMainProgram = aMeta ? aMeta->maybeGetAttr("mainProgram") : nullptr;
|
auto aMainProgram = aMeta ? aMeta->maybeGetAttr(*state, "mainProgram") : nullptr;
|
||||||
auto mainProgram =
|
auto mainProgram =
|
||||||
aMainProgram
|
aMainProgram
|
||||||
? aMainProgram->getString()
|
? aMainProgram->getString(*state)
|
||||||
: aPname
|
: aPname
|
||||||
? aPname->getString()
|
? aPname->getString(*state)
|
||||||
: DrvName(name).name;
|
: DrvName(name).name;
|
||||||
auto program = outPath + "/bin/" + mainProgram;
|
auto program = outPath + "/bin/" + mainProgram;
|
||||||
return UnresolvedApp { App {
|
return UnresolvedApp { App {
|
||||||
|
@ -122,7 +122,7 @@ UnresolvedApp InstallableValue::toApp()
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
throw Error("attribute '%s' has unsupported type '%s'", cursor->getAttrPathStr(), type);
|
throw Error("attribute '%s' has unsupported type '%s'", cursor->getAttrPathStr(*state), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: move to libcmd
|
// FIXME: move to libcmd
|
||||||
|
|
|
@ -864,14 +864,14 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand
|
||||||
|
|
||||||
auto cursor = installable.getCursor();
|
auto cursor = installable.getCursor();
|
||||||
|
|
||||||
auto templateDirAttr = cursor->getAttr("path");
|
auto templateDirAttr = cursor->getAttr(*evalState, "path");
|
||||||
auto templateDir = templateDirAttr->getString();
|
auto templateDir = templateDirAttr->getString(*evalState);
|
||||||
|
|
||||||
if (!store->isInStore(templateDir))
|
if (!store->isInStore(templateDir))
|
||||||
evalState->errors.make<TypeError>(
|
evalState->errors.make<TypeError>(
|
||||||
"'%s' was not found in the Nix store\n"
|
"'%s' was not found in the Nix store\n"
|
||||||
"If you've set '%s' to a string, try using a path instead.",
|
"If you've set '%s' to a string, try using a path instead.",
|
||||||
templateDir, templateDirAttr->getAttrPathStr()).debugThrow();
|
templateDir, templateDirAttr->getAttrPathStr(*evalState)).debugThrow();
|
||||||
|
|
||||||
std::vector<Path> changedFiles;
|
std::vector<Path> changedFiles;
|
||||||
std::vector<Path> conflictedFiles;
|
std::vector<Path> conflictedFiles;
|
||||||
|
@ -928,10 +928,10 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand
|
||||||
for (auto & s : changedFiles) args.push_back(s);
|
for (auto & s : changedFiles) args.push_back(s);
|
||||||
runProgram("git", true, args);
|
runProgram("git", true, args);
|
||||||
}
|
}
|
||||||
auto welcomeText = cursor->maybeGetAttr("welcomeText");
|
auto welcomeText = cursor->maybeGetAttr(*evalState, "welcomeText");
|
||||||
if (welcomeText) {
|
if (welcomeText) {
|
||||||
notice("\n");
|
notice("\n");
|
||||||
notice(renderMarkdownToTerminal(welcomeText->getString()));
|
notice(renderMarkdownToTerminal(welcomeText->getString(*evalState)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!conflictedFiles.empty())
|
if (!conflictedFiles.empty())
|
||||||
|
@ -1152,7 +1152,7 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
{
|
{
|
||||||
attrPath.push_back(attr);
|
attrPath.push_back(attr);
|
||||||
|
|
||||||
auto visitor2 = visitor.getAttr(attr);
|
auto visitor2 = visitor.getAttr(*state, attr);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ((attrPath[0] == "apps"
|
if ((attrPath[0] == "apps"
|
||||||
|
@ -1161,7 +1161,7 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
|| attrPath[0] == "legacyPackages"
|
|| attrPath[0] == "legacyPackages"
|
||||||
|| attrPath[0] == "packages")
|
|| attrPath[0] == "packages")
|
||||||
&& (attrPath.size() == 1 || attrPath.size() == 2)) {
|
&& (attrPath.size() == 1 || attrPath.size() == 2)) {
|
||||||
for (const auto &subAttr : visitor2->getAttrs()) {
|
for (const auto &subAttr : visitor2->getAttrs(*state)) {
|
||||||
if (hasContent(*visitor2, attrPath, subAttr)) {
|
if (hasContent(*visitor2, attrPath, subAttr)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1175,7 +1175,7 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
|| attrPath[0] == "nixosModules"
|
|| attrPath[0] == "nixosModules"
|
||||||
|| attrPath[0] == "overlays"
|
|| attrPath[0] == "overlays"
|
||||||
)) {
|
)) {
|
||||||
for (const auto &subAttr : visitor2->getAttrs()) {
|
for (const auto &subAttr : visitor2->getAttrs(*state)) {
|
||||||
if (hasContent(*visitor2, attrPath, subAttr)) {
|
if (hasContent(*visitor2, attrPath, subAttr)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1217,14 +1217,14 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
if (!json)
|
if (!json)
|
||||||
logger->cout("%s", headerPrefix);
|
logger->cout("%s", headerPrefix);
|
||||||
std::vector<std::string> attrs;
|
std::vector<std::string> attrs;
|
||||||
for (const auto &attr : visitor.getAttrs()) {
|
for (const auto &attr : visitor.getAttrs(*state)) {
|
||||||
if (hasContent(visitor, attrPath, attr))
|
if (hasContent(visitor, attrPath, attr))
|
||||||
attrs.push_back(attr);
|
attrs.push_back(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto & [i, attr] : enumerate(attrs)) {
|
for (const auto & [i, attr] : enumerate(attrs)) {
|
||||||
bool last = i + 1 == attrs.size();
|
bool last = i + 1 == attrs.size();
|
||||||
auto visitor2 = visitor.getAttr(attr);
|
auto visitor2 = visitor.getAttr(*state, attr);
|
||||||
auto attrPath2(attrPath);
|
auto attrPath2(attrPath);
|
||||||
attrPath2.push_back(attr);
|
attrPath2.push_back(attr);
|
||||||
auto j2 = visit(*visitor2, attrPath2,
|
auto j2 = visit(*visitor2, attrPath2,
|
||||||
|
@ -1236,11 +1236,11 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
|
|
||||||
auto showDerivation = [&]()
|
auto showDerivation = [&]()
|
||||||
{
|
{
|
||||||
auto name = visitor.getAttr("name")->getString();
|
auto name = visitor.getAttr(*state, "name")->getString(*state);
|
||||||
std::optional<std::string> description;
|
std::optional<std::string> description;
|
||||||
if (auto aMeta = visitor.maybeGetAttr("meta")) {
|
if (auto aMeta = visitor.maybeGetAttr(*state, "meta")) {
|
||||||
if (auto aDescription = aMeta->maybeGetAttr("description"))
|
if (auto aDescription = aMeta->maybeGetAttr(*state, "description"))
|
||||||
description = aDescription->getString();
|
description = aDescription->getString(*state);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
|
@ -1324,7 +1324,7 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
logger->warn(fmt("%s omitted (use '--all-systems' to show)", concatStringsSep(".", attrPath)));
|
logger->warn(fmt("%s omitted (use '--all-systems' to show)", concatStringsSep(".", attrPath)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (visitor.isDerivation())
|
if (visitor.isDerivation(*state))
|
||||||
showDerivation();
|
showDerivation();
|
||||||
else
|
else
|
||||||
throw Error("expected a derivation");
|
throw Error("expected a derivation");
|
||||||
|
@ -1332,7 +1332,7 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (attrPath.size() > 0 && attrPath[0] == "hydraJobs") {
|
else if (attrPath.size() > 0 && attrPath[0] == "hydraJobs") {
|
||||||
if (visitor.isDerivation())
|
if (visitor.isDerivation(*state))
|
||||||
showDerivation();
|
showDerivation();
|
||||||
else
|
else
|
||||||
recurse();
|
recurse();
|
||||||
|
@ -1354,7 +1354,7 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
logger->warn(fmt("%s omitted (use '--all-systems' to show)", concatStringsSep(".", attrPath)));
|
logger->warn(fmt("%s omitted (use '--all-systems' to show)", concatStringsSep(".", attrPath)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (visitor.isDerivation())
|
if (visitor.isDerivation(*state))
|
||||||
showDerivation();
|
showDerivation();
|
||||||
else if (attrPath.size() <= 2)
|
else if (attrPath.size() <= 2)
|
||||||
// FIXME: handle recurseIntoAttrs
|
// FIXME: handle recurseIntoAttrs
|
||||||
|
@ -1366,8 +1366,8 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
(attrPath.size() == 2 && attrPath[0] == "defaultApp") ||
|
(attrPath.size() == 2 && attrPath[0] == "defaultApp") ||
|
||||||
(attrPath.size() == 3 && attrPath[0] == "apps"))
|
(attrPath.size() == 3 && attrPath[0] == "apps"))
|
||||||
{
|
{
|
||||||
auto aType = visitor.maybeGetAttr("type");
|
auto aType = visitor.maybeGetAttr(*state, "type");
|
||||||
if (!aType || aType->getString() != "app")
|
if (!aType || aType->getString(*state) != "app")
|
||||||
state->errors.make<EvalError>("not an app definition").debugThrow();
|
state->errors.make<EvalError>("not an app definition").debugThrow();
|
||||||
if (json) {
|
if (json) {
|
||||||
j.emplace("type", "app");
|
j.emplace("type", "app");
|
||||||
|
@ -1380,7 +1380,7 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
(attrPath.size() == 1 && attrPath[0] == "defaultTemplate") ||
|
(attrPath.size() == 1 && attrPath[0] == "defaultTemplate") ||
|
||||||
(attrPath.size() == 2 && attrPath[0] == "templates"))
|
(attrPath.size() == 2 && attrPath[0] == "templates"))
|
||||||
{
|
{
|
||||||
auto description = visitor.getAttr("description")->getString();
|
auto description = visitor.getAttr(*state, "description")->getString(*state);
|
||||||
if (json) {
|
if (json) {
|
||||||
j.emplace("type", "template");
|
j.emplace("type", "template");
|
||||||
j.emplace("description", description);
|
j.emplace("description", description);
|
||||||
|
|
|
@ -100,20 +100,20 @@ struct CmdSearch : InstallableCommand, MixJSON
|
||||||
try {
|
try {
|
||||||
auto recurse = [&]()
|
auto recurse = [&]()
|
||||||
{
|
{
|
||||||
for (const auto & attr : cursor.getAttrs()) {
|
for (const auto & attr : cursor.getAttrs(*state)) {
|
||||||
auto cursor2 = cursor.getAttr(attr);
|
auto cursor2 = cursor.getAttr(*state, attr);
|
||||||
auto attrPath2(attrPath);
|
auto attrPath2(attrPath);
|
||||||
attrPath2.emplace_back(attr);
|
attrPath2.emplace_back(attr);
|
||||||
visit(*cursor2, attrPath2, false);
|
visit(*cursor2, attrPath2, false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (cursor.isDerivation()) {
|
if (cursor.isDerivation(*state)) {
|
||||||
DrvName name(cursor.getAttr("name")->getString());
|
DrvName name(cursor.getAttr(*state, "name")->getString(*state));
|
||||||
|
|
||||||
auto aMeta = cursor.maybeGetAttr("meta");
|
auto aMeta = cursor.maybeGetAttr(*state, "meta");
|
||||||
auto aDescription = aMeta ? aMeta->maybeGetAttr("description") : nullptr;
|
auto aDescription = aMeta ? aMeta->maybeGetAttr(*state, "description") : nullptr;
|
||||||
auto description = aDescription ? aDescription->getString() : "";
|
auto description = aDescription ? aDescription->getString(*state) : "";
|
||||||
std::replace(description.begin(), description.end(), '\n', ' ');
|
std::replace(description.begin(), description.end(), '\n', ' ');
|
||||||
auto attrPath2 = concatStringsSep(".", attrPath);
|
auto attrPath2 = concatStringsSep(".", attrPath);
|
||||||
|
|
||||||
|
@ -181,8 +181,8 @@ struct CmdSearch : InstallableCommand, MixJSON
|
||||||
recurse();
|
recurse();
|
||||||
|
|
||||||
else if (attrPath[0] == "legacyPackages" && attrPath.size() > 2) {
|
else if (attrPath[0] == "legacyPackages" && attrPath.size() > 2) {
|
||||||
auto attr = cursor.maybeGetAttr("recurseForDerivations");
|
auto attr = cursor.maybeGetAttr(*state, "recurseForDerivations");
|
||||||
if (attr && attr->getBool())
|
if (attr && attr->getBool(*state))
|
||||||
recurse();
|
recurse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@ struct CmdSearch : InstallableCommand, MixJSON
|
||||||
};
|
};
|
||||||
|
|
||||||
for (auto & cursor : installableValue->getCursors())
|
for (auto & cursor : installableValue->getCursors())
|
||||||
visit(*cursor, cursor->getAttrPath(), true);
|
visit(*cursor, cursor->getAttrPath(*state), true);
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
logger->cout("%s", *jsonOut);
|
logger->cout("%s", *jsonOut);
|
||||||
|
|
Loading…
Reference in a new issue