libexpr: standardize on strings for attr cache traversal
it's all strings anyway. the db stores strings, the cli wants to
interact with attr paths as strings, so we will just use strings
Change-Id: Id9ea07d92343de77e8d47af8fec1e86ae225e9a1
This commit is contained in:
parent
dd7d7450a5
commit
9a3e3a5560
|
@ -118,8 +118,8 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
|
||||||
|
|
||||||
std::optional<NixInt::Inner> priority;
|
std::optional<NixInt::Inner> priority;
|
||||||
|
|
||||||
if (attr->maybeGetAttr(state->s.outputSpecified)) {
|
if (attr->maybeGetAttr("outputSpecified")) {
|
||||||
} else if (auto aMeta = attr->maybeGetAttr(state->s.meta)) {
|
} else if (auto aMeta = attr->maybeGetAttr("meta")) {
|
||||||
if (auto aPriority = aMeta->maybeGetAttr("priority"))
|
if (auto aPriority = aMeta->maybeGetAttr("priority"))
|
||||||
priority = aPriority->getInt().value;
|
priority = aPriority->getInt().value;
|
||||||
}
|
}
|
||||||
|
@ -130,12 +130,12 @@ 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(state->s.outputSpecified)) {
|
if (auto aOutputSpecified = attr->maybeGetAttr("outputSpecified")) {
|
||||||
if (aOutputSpecified->getBool()) {
|
if (aOutputSpecified->getBool()) {
|
||||||
if (auto aOutputName = attr->maybeGetAttr("outputName"))
|
if (auto aOutputName = attr->maybeGetAttr("outputName"))
|
||||||
outputsToInstall = { aOutputName->getString() };
|
outputsToInstall = { aOutputName->getString() };
|
||||||
}
|
}
|
||||||
} else if (auto aMeta = attr->maybeGetAttr(state->s.meta)) {
|
} else if (auto aMeta = attr->maybeGetAttr("meta")) {
|
||||||
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);
|
||||||
|
@ -184,7 +184,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(*state, attrPath));
|
auto attr = root->findAlongAttrPath(parseAttrPath(attrPath));
|
||||||
if (attr) {
|
if (attr) {
|
||||||
res.push_back(ref(*attr));
|
res.push_back(ref(*attr));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -305,13 +305,13 @@ void completeFlakeRefWithFragment(
|
||||||
attrPathPrefixes.push_back("");
|
attrPathPrefixes.push_back("");
|
||||||
|
|
||||||
for (auto & attrPathPrefixS : attrPathPrefixes) {
|
for (auto & attrPathPrefixS : attrPathPrefixes) {
|
||||||
auto attrPathPrefix = parseAttrPath(*evalState, attrPathPrefixS);
|
auto attrPathPrefix = parseAttrPath(attrPathPrefixS);
|
||||||
auto attrPathS = attrPathPrefixS + std::string(fragment);
|
auto attrPathS = attrPathPrefixS + std::string(fragment);
|
||||||
auto attrPath = parseAttrPath(*evalState, attrPathS);
|
auto attrPath = parseAttrPath(attrPathS);
|
||||||
|
|
||||||
std::string lastAttr;
|
std::string lastAttr;
|
||||||
if (!attrPath.empty() && !attrPathS.ends_with(".")) {
|
if (!attrPath.empty() && !attrPathS.ends_with(".")) {
|
||||||
lastAttr = evalState->symbols[attrPath.back()];
|
lastAttr = attrPath.back();
|
||||||
attrPath.pop_back();
|
attrPath.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,11 +319,11 @@ void completeFlakeRefWithFragment(
|
||||||
if (!attr) continue;
|
if (!attr) continue;
|
||||||
|
|
||||||
for (auto & attr2 : (*attr)->getAttrs()) {
|
for (auto & attr2 : (*attr)->getAttrs()) {
|
||||||
if (std::string_view(evalState->symbols[attr2]).starts_with(lastAttr)) {
|
if (std::string_view attr2s = attr2; attr2s.starts_with(lastAttr)) {
|
||||||
auto attrPath2 = (*attr)->getAttrPath(attr2);
|
auto attrPath2 = (*attr)->getAttrPath(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(".", evalState->symbols.resolve(attrPath2)));
|
completions.add(flakeRefS + "#" + prefixRoot + concatStringsSep(".", attrPath2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -332,7 +332,7 @@ void completeFlakeRefWithFragment(
|
||||||
attrpaths. */
|
attrpaths. */
|
||||||
if (fragment.empty()) {
|
if (fragment.empty()) {
|
||||||
for (auto & attrPath : defaultFlakeAttrPaths) {
|
for (auto & attrPath : defaultFlakeAttrPaths) {
|
||||||
auto attr = root->findAlongAttrPath(parseAttrPath(*evalState, attrPath));
|
auto attr = root->findAlongAttrPath(parseAttrPath(attrPath));
|
||||||
if (!attr) continue;
|
if (!attr) continue;
|
||||||
completions.add(flakeRefS + "#" + prefixRoot);
|
completions.add(flakeRefS + "#" + prefixRoot);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
static Strings parseAttrPath(std::string_view s)
|
Strings parseAttrPath(std::string_view s)
|
||||||
{
|
{
|
||||||
Strings res;
|
Strings res;
|
||||||
std::string cur;
|
std::string cur;
|
||||||
|
@ -31,15 +31,6 @@ static Strings parseAttrPath(std::string_view s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<Symbol> parseAttrPath(EvalState & state, std::string_view s)
|
|
||||||
{
|
|
||||||
std::vector<Symbol> res;
|
|
||||||
for (auto & a : parseAttrPath(s))
|
|
||||||
res.push_back(state.symbols.create(a));
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::pair<Value *, PosIdx> findAlongAttrPath(EvalState & state, const std::string & attrPath,
|
std::pair<Value *, PosIdx> findAlongAttrPath(EvalState & state, const std::string & attrPath,
|
||||||
Bindings & autoArgs, Value & vIn)
|
Bindings & autoArgs, Value & vIn)
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,6 +22,6 @@ std::pair<Value *, PosIdx> findAlongAttrPath(
|
||||||
*/
|
*/
|
||||||
std::pair<SourcePath, uint32_t> findPackageFilename(EvalState & state, Value & v, std::string what);
|
std::pair<SourcePath, uint32_t> findPackageFilename(EvalState & state, Value & v, std::string what);
|
||||||
|
|
||||||
std::vector<Symbol> parseAttrPath(EvalState & state, std::string_view s);
|
Strings parseAttrPath(std::string_view s);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,15 +35,11 @@ struct AttrDb
|
||||||
|
|
||||||
std::unique_ptr<Sync<State>> _state;
|
std::unique_ptr<Sync<State>> _state;
|
||||||
|
|
||||||
SymbolTable & symbols;
|
|
||||||
|
|
||||||
AttrDb(
|
AttrDb(
|
||||||
const Store & cfg,
|
const Store & cfg,
|
||||||
const Hash & fingerprint,
|
const Hash & fingerprint)
|
||||||
SymbolTable & symbols)
|
|
||||||
: cfg(cfg)
|
: cfg(cfg)
|
||||||
, _state(std::make_unique<Sync<State>>())
|
, _state(std::make_unique<Sync<State>>())
|
||||||
, symbols(symbols)
|
|
||||||
{
|
{
|
||||||
auto state(_state->lock());
|
auto state(_state->lock());
|
||||||
|
|
||||||
|
@ -98,7 +94,7 @@ struct AttrDb
|
||||||
|
|
||||||
AttrId setAttrs(
|
AttrId setAttrs(
|
||||||
AttrKey key,
|
AttrKey key,
|
||||||
const std::vector<Symbol> & attrs)
|
const fullattr_t & attrs)
|
||||||
{
|
{
|
||||||
return doSQLite([&]()
|
return doSQLite([&]()
|
||||||
{
|
{
|
||||||
|
@ -106,17 +102,17 @@ struct AttrDb
|
||||||
|
|
||||||
state->insertAttribute.use()
|
state->insertAttribute.use()
|
||||||
(key.first)
|
(key.first)
|
||||||
(symbols[key.second])
|
(key.second)
|
||||||
(AttrType::FullAttrs)
|
(AttrType::FullAttrs)
|
||||||
(0, false).exec();
|
(0, false).exec();
|
||||||
|
|
||||||
AttrId rowId = state->db.getLastInsertedRowId();
|
AttrId rowId = state->db.getLastInsertedRowId();
|
||||||
assert(rowId);
|
assert(rowId);
|
||||||
|
|
||||||
for (auto & attr : attrs)
|
for (auto & attr : attrs.p)
|
||||||
state->insertAttribute.use()
|
state->insertAttribute.use()
|
||||||
(rowId)
|
(rowId)
|
||||||
(symbols[attr])
|
(attr)
|
||||||
(AttrType::Placeholder)
|
(AttrType::Placeholder)
|
||||||
(0, false).exec();
|
(0, false).exec();
|
||||||
|
|
||||||
|
@ -141,14 +137,14 @@ struct AttrDb
|
||||||
}
|
}
|
||||||
state->insertAttributeWithContext.use()
|
state->insertAttributeWithContext.use()
|
||||||
(key.first)
|
(key.first)
|
||||||
(symbols[key.second])
|
(key.second)
|
||||||
(AttrType::String)
|
(AttrType::String)
|
||||||
(s)
|
(s)
|
||||||
(ctx).exec();
|
(ctx).exec();
|
||||||
} else {
|
} else {
|
||||||
state->insertAttribute.use()
|
state->insertAttribute.use()
|
||||||
(key.first)
|
(key.first)
|
||||||
(symbols[key.second])
|
(key.second)
|
||||||
(AttrType::String)
|
(AttrType::String)
|
||||||
(s).exec();
|
(s).exec();
|
||||||
}
|
}
|
||||||
|
@ -167,7 +163,7 @@ struct AttrDb
|
||||||
|
|
||||||
state->insertAttribute.use()
|
state->insertAttribute.use()
|
||||||
(key.first)
|
(key.first)
|
||||||
(symbols[key.second])
|
(key.second)
|
||||||
(AttrType::Bool)
|
(AttrType::Bool)
|
||||||
(b ? 1 : 0).exec();
|
(b ? 1 : 0).exec();
|
||||||
|
|
||||||
|
@ -185,7 +181,7 @@ struct AttrDb
|
||||||
|
|
||||||
state->insertAttribute.use()
|
state->insertAttribute.use()
|
||||||
(key.first)
|
(key.first)
|
||||||
(symbols[key.second])
|
(key.second)
|
||||||
(AttrType::Int)
|
(AttrType::Int)
|
||||||
(n).exec();
|
(n).exec();
|
||||||
|
|
||||||
|
@ -203,7 +199,7 @@ struct AttrDb
|
||||||
|
|
||||||
state->insertAttribute.use()
|
state->insertAttribute.use()
|
||||||
(key.first)
|
(key.first)
|
||||||
(symbols[key.second])
|
(key.second)
|
||||||
(AttrType::ListOfStrings)
|
(AttrType::ListOfStrings)
|
||||||
(concatStringsSep("\t", l)).exec();
|
(concatStringsSep("\t", l)).exec();
|
||||||
|
|
||||||
|
@ -219,7 +215,7 @@ struct AttrDb
|
||||||
|
|
||||||
state->insertAttribute.use()
|
state->insertAttribute.use()
|
||||||
(key.first)
|
(key.first)
|
||||||
(symbols[key.second])
|
(key.second)
|
||||||
(AttrType::Placeholder)
|
(AttrType::Placeholder)
|
||||||
(0, false).exec();
|
(0, false).exec();
|
||||||
|
|
||||||
|
@ -235,7 +231,7 @@ struct AttrDb
|
||||||
|
|
||||||
state->insertAttribute.use()
|
state->insertAttribute.use()
|
||||||
(key.first)
|
(key.first)
|
||||||
(symbols[key.second])
|
(key.second)
|
||||||
(AttrType::Missing)
|
(AttrType::Missing)
|
||||||
(0, false).exec();
|
(0, false).exec();
|
||||||
|
|
||||||
|
@ -251,7 +247,7 @@ struct AttrDb
|
||||||
|
|
||||||
state->insertAttribute.use()
|
state->insertAttribute.use()
|
||||||
(key.first)
|
(key.first)
|
||||||
(symbols[key.second])
|
(key.second)
|
||||||
(AttrType::Misc)
|
(AttrType::Misc)
|
||||||
(0, false).exec();
|
(0, false).exec();
|
||||||
|
|
||||||
|
@ -267,7 +263,7 @@ struct AttrDb
|
||||||
|
|
||||||
state->insertAttribute.use()
|
state->insertAttribute.use()
|
||||||
(key.first)
|
(key.first)
|
||||||
(symbols[key.second])
|
(key.second)
|
||||||
(AttrType::Failed)
|
(AttrType::Failed)
|
||||||
(0, false).exec();
|
(0, false).exec();
|
||||||
|
|
||||||
|
@ -279,7 +275,7 @@ struct AttrDb
|
||||||
{
|
{
|
||||||
auto state(_state->lock());
|
auto state(_state->lock());
|
||||||
|
|
||||||
auto queryAttribute(state->queryAttribute.use()(key.first)(symbols[key.second]));
|
auto queryAttribute(state->queryAttribute.use()(key.first)(key.second));
|
||||||
if (!queryAttribute.next()) return {};
|
if (!queryAttribute.next()) return {};
|
||||||
|
|
||||||
auto rowId = (AttrId) queryAttribute.getInt(0);
|
auto rowId = (AttrId) queryAttribute.getInt(0);
|
||||||
|
@ -290,10 +286,10 @@ struct AttrDb
|
||||||
return {{rowId, placeholder_t()}};
|
return {{rowId, placeholder_t()}};
|
||||||
case AttrType::FullAttrs: {
|
case AttrType::FullAttrs: {
|
||||||
// FIXME: expensive, should separate this out.
|
// FIXME: expensive, should separate this out.
|
||||||
std::vector<Symbol> attrs;
|
fullattr_t attrs;
|
||||||
auto queryAttributes(state->queryAttributes.use()(rowId));
|
auto queryAttributes(state->queryAttributes.use()(rowId));
|
||||||
while (queryAttributes.next())
|
while (queryAttributes.next())
|
||||||
attrs.emplace_back(symbols.create(queryAttributes.getStr(0)));
|
attrs.p.emplace_back(queryAttributes.getStr(0));
|
||||||
return {{rowId, attrs}};
|
return {{rowId, attrs}};
|
||||||
}
|
}
|
||||||
case AttrType::String: {
|
case AttrType::String: {
|
||||||
|
@ -323,11 +319,10 @@ struct AttrDb
|
||||||
|
|
||||||
static std::shared_ptr<AttrDb> makeAttrDb(
|
static std::shared_ptr<AttrDb> makeAttrDb(
|
||||||
const Store & cfg,
|
const Store & cfg,
|
||||||
const Hash & fingerprint,
|
const Hash & fingerprint)
|
||||||
SymbolTable & symbols)
|
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return std::make_shared<AttrDb>(cfg, fingerprint, symbols);
|
return std::make_shared<AttrDb>(cfg, fingerprint);
|
||||||
} catch (SQLiteError &) {
|
} catch (SQLiteError &) {
|
||||||
ignoreExceptionExceptInterrupt();
|
ignoreExceptionExceptInterrupt();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -348,7 +343,7 @@ EvalCache::EvalCache(
|
||||||
std::optional<std::reference_wrapper<const Hash>> useCache,
|
std::optional<std::reference_wrapper<const Hash>> useCache,
|
||||||
EvalState & state,
|
EvalState & state,
|
||||||
RootLoader rootLoader)
|
RootLoader rootLoader)
|
||||||
: db(useCache ? makeAttrDb(*state.store, *useCache, state.symbols) : nullptr)
|
: db(useCache ? makeAttrDb(*state.store, *useCache) : nullptr)
|
||||||
, state(state)
|
, state(state)
|
||||||
, rootLoader(rootLoader)
|
, rootLoader(rootLoader)
|
||||||
{
|
{
|
||||||
|
@ -382,7 +377,7 @@ AttrCursor::AttrCursor(
|
||||||
AttrKey AttrCursor::getKey()
|
AttrKey AttrCursor::getKey()
|
||||||
{
|
{
|
||||||
if (!parent)
|
if (!parent)
|
||||||
return {0, root->state.s.epsilon};
|
return {0, ""};
|
||||||
if (!parent->first->cachedValue) {
|
if (!parent->first->cachedValue) {
|
||||||
parent->first->cachedValue = root->db->getAttr(parent->first->getKey());
|
parent->first->cachedValue = root->db->getAttr(parent->first->getKey());
|
||||||
assert(parent->first->cachedValue);
|
assert(parent->first->cachedValue);
|
||||||
|
@ -396,7 +391,7 @@ Value & AttrCursor::getValue()
|
||||||
if (parent) {
|
if (parent) {
|
||||||
auto & vParent = parent->first->getValue();
|
auto & vParent = parent->first->getValue();
|
||||||
root->state.forceAttrs(vParent, noPos, "while searching for an attribute");
|
root->state.forceAttrs(vParent, noPos, "while searching for an attribute");
|
||||||
auto attr = vParent.attrs->get(parent->second);
|
auto attr = vParent.attrs->get(root->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());
|
||||||
_value = allocRootValue(attr->value);
|
_value = allocRootValue(attr->value);
|
||||||
|
@ -406,7 +401,7 @@ Value & AttrCursor::getValue()
|
||||||
return **_value;
|
return **_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Symbol> AttrCursor::getAttrPath() const
|
std::vector<std::string> AttrCursor::getAttrPath() const
|
||||||
{
|
{
|
||||||
if (parent) {
|
if (parent) {
|
||||||
auto attrPath = parent->first->getAttrPath();
|
auto attrPath = parent->first->getAttrPath();
|
||||||
|
@ -416,21 +411,21 @@ std::vector<Symbol> AttrCursor::getAttrPath() const
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Symbol> AttrCursor::getAttrPath(Symbol name) const
|
std::vector<std::string> AttrCursor::getAttrPath(std::string_view name) const
|
||||||
{
|
{
|
||||||
auto attrPath = getAttrPath();
|
auto attrPath = getAttrPath();
|
||||||
attrPath.push_back(name);
|
attrPath.emplace_back(name);
|
||||||
return attrPath;
|
return attrPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AttrCursor::getAttrPathStr() const
|
std::string AttrCursor::getAttrPathStr() const
|
||||||
{
|
{
|
||||||
return concatStringsSep(".", root->state.symbols.resolve(getAttrPath()));
|
return concatStringsSep(".", getAttrPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AttrCursor::getAttrPathStr(Symbol name) const
|
std::string AttrCursor::getAttrPathStr(std::string_view name) const
|
||||||
{
|
{
|
||||||
return concatStringsSep(".", root->state.symbols.resolve(getAttrPath(name)));
|
return concatStringsSep(".", getAttrPath(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
Value & AttrCursor::forceValue()
|
Value & AttrCursor::forceValue()
|
||||||
|
@ -469,27 +464,23 @@ Value & AttrCursor::forceValue()
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
Suggestions AttrCursor::getSuggestionsForAttr(Symbol name)
|
Suggestions AttrCursor::getSuggestionsForAttr(const std::string & name)
|
||||||
{
|
{
|
||||||
auto attrNames = getAttrs();
|
auto attrNames = getAttrs();
|
||||||
std::set<std::string> strAttrNames;
|
return Suggestions::bestMatches({attrNames.begin(), attrNames.end()}, name);
|
||||||
for (auto & name : attrNames)
|
|
||||||
strAttrNames.insert(root->state.symbols[name]);
|
|
||||||
|
|
||||||
return Suggestions::bestMatches(strAttrNames, root->state.symbols[name]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<AttrCursor> AttrCursor::maybeGetAttr(Symbol name)
|
std::shared_ptr<AttrCursor> AttrCursor::maybeGetAttr(const std::string & name)
|
||||||
{
|
{
|
||||||
if (root->db) {
|
if (root->db) {
|
||||||
if (!cachedValue)
|
if (!cachedValue)
|
||||||
cachedValue = root->db->getAttr(getKey());
|
cachedValue = root->db->getAttr(getKey());
|
||||||
|
|
||||||
if (cachedValue) {
|
if (cachedValue) {
|
||||||
if (auto attrs = std::get_if<std::vector<Symbol>>(&cachedValue->second)) {
|
if (auto attrs = std::get_if<fullattr_t>(&cachedValue->second)) {
|
||||||
for (auto & attr : *attrs)
|
for (auto & attr : attrs->p)
|
||||||
if (attr == name)
|
if (attr == name)
|
||||||
return std::make_shared<AttrCursor>(root, std::make_pair(shared_from_this(), attr));
|
return std::make_shared<AttrCursor>(root, std::make_pair(shared_from_this(), name));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
} else if (std::get_if<placeholder_t>(&cachedValue->second)) {
|
} else if (std::get_if<placeholder_t>(&cachedValue->second)) {
|
||||||
auto attr = root->db->getAttr({cachedValue->first, name});
|
auto attr = root->db->getAttr({cachedValue->first, name});
|
||||||
|
@ -516,7 +507,7 @@ std::shared_ptr<AttrCursor> AttrCursor::maybeGetAttr(Symbol name)
|
||||||
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(name);
|
auto attr = v.attrs->get(root->state.symbols.create(name));
|
||||||
|
|
||||||
if (!attr) {
|
if (!attr) {
|
||||||
if (root->db) {
|
if (root->db) {
|
||||||
|
@ -538,12 +529,7 @@ std::shared_ptr<AttrCursor> AttrCursor::maybeGetAttr(Symbol 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<AttrCursor> AttrCursor::maybeGetAttr(std::string_view name)
|
ref<AttrCursor> AttrCursor::getAttr(const std::string & name)
|
||||||
{
|
|
||||||
return maybeGetAttr(root->state.symbols.create(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
ref<AttrCursor> AttrCursor::getAttr(Symbol name)
|
|
||||||
{
|
{
|
||||||
auto p = maybeGetAttr(name);
|
auto p = maybeGetAttr(name);
|
||||||
if (!p)
|
if (!p)
|
||||||
|
@ -551,12 +537,7 @@ ref<AttrCursor> AttrCursor::getAttr(Symbol name)
|
||||||
return ref(p);
|
return ref(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
ref<AttrCursor> AttrCursor::getAttr(std::string_view name)
|
OrSuggestions<ref<AttrCursor>> AttrCursor::findAlongAttrPath(const Strings & attrPath)
|
||||||
{
|
|
||||||
return getAttr(root->state.symbols.create(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
OrSuggestions<ref<AttrCursor>> AttrCursor::findAlongAttrPath(const std::vector<Symbol> & attrPath)
|
|
||||||
{
|
{
|
||||||
auto res = shared_from_this();
|
auto res = shared_from_this();
|
||||||
for (auto & attr : attrPath) {
|
for (auto & attr : attrPath) {
|
||||||
|
@ -717,15 +698,15 @@ std::vector<std::string> AttrCursor::getListOfStrings()
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Symbol> AttrCursor::getAttrs()
|
std::vector<std::string> AttrCursor::getAttrs()
|
||||||
{
|
{
|
||||||
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<std::vector<Symbol>>(&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());
|
||||||
return *attrs;
|
return attrs->p;
|
||||||
} else
|
} else
|
||||||
root->state.errors.make<TypeError>("'%s' is not an attribute set", getAttrPathStr()).debugThrow();
|
root->state.errors.make<TypeError>("'%s' is not an attribute set", getAttrPathStr()).debugThrow();
|
||||||
}
|
}
|
||||||
|
@ -736,18 +717,15 @@ std::vector<Symbol> AttrCursor::getAttrs()
|
||||||
if (v.type() != nAttrs)
|
if (v.type() != nAttrs)
|
||||||
root->state.errors.make<TypeError>("'%s' is not an attribute set", getAttrPathStr()).debugThrow();
|
root->state.errors.make<TypeError>("'%s' is not an attribute set", getAttrPathStr()).debugThrow();
|
||||||
|
|
||||||
std::vector<Symbol> attrs;
|
fullattr_t attrs;
|
||||||
for (auto & attr : *getValue().attrs)
|
for (auto & attr : *getValue().attrs)
|
||||||
attrs.push_back(attr.name);
|
attrs.p.push_back(root->state.symbols[attr.name]);
|
||||||
std::sort(attrs.begin(), attrs.end(), [&](Symbol a, Symbol b) {
|
std::sort(attrs.p.begin(), attrs.p.end());
|
||||||
std::string_view sa = root->state.symbols[a], sb = root->state.symbols[b];
|
|
||||||
return sa < sb;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (root->db)
|
if (root->db)
|
||||||
cachedValue = {root->db->setAttrs(getKey(), attrs), attrs};
|
cachedValue = {root->db->setAttrs(getKey(), attrs), attrs};
|
||||||
|
|
||||||
return attrs;
|
return attrs.p;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AttrCursor::isDerivation()
|
bool AttrCursor::isDerivation()
|
||||||
|
@ -758,7 +736,7 @@ bool AttrCursor::isDerivation()
|
||||||
|
|
||||||
StorePath AttrCursor::forceDerivation()
|
StorePath AttrCursor::forceDerivation()
|
||||||
{
|
{
|
||||||
auto aDrvPath = getAttr(root->state.s.drvPath);
|
auto aDrvPath = getAttr("drvPath");
|
||||||
auto drvPath = root->state.store->parseStorePath(aDrvPath->getString());
|
auto drvPath = root->state.store->parseStorePath(aDrvPath->getString());
|
||||||
if (!root->state.store->isValidPath(drvPath) && !settings.readOnlyMode) {
|
if (!root->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
|
||||||
|
|
|
@ -69,16 +69,17 @@ enum AttrType {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct placeholder_t {};
|
struct placeholder_t {};
|
||||||
|
struct fullattr_t { std::vector<std::string> p; };
|
||||||
struct missing_t {};
|
struct missing_t {};
|
||||||
struct misc_t {};
|
struct misc_t {};
|
||||||
struct failed_t {};
|
struct failed_t {};
|
||||||
struct int_t { NixInt x; };
|
struct int_t { NixInt x; };
|
||||||
typedef uint64_t AttrId;
|
typedef uint64_t AttrId;
|
||||||
typedef std::pair<AttrId, Symbol> AttrKey;
|
typedef std::pair<AttrId, std::string> AttrKey;
|
||||||
typedef std::pair<std::string, NixStringContext> string_t;
|
typedef std::pair<std::string, NixStringContext> string_t;
|
||||||
|
|
||||||
typedef std::variant<
|
typedef std::variant<
|
||||||
std::vector<Symbol>,
|
fullattr_t,
|
||||||
string_t,
|
string_t,
|
||||||
placeholder_t,
|
placeholder_t,
|
||||||
missing_t,
|
missing_t,
|
||||||
|
@ -94,7 +95,7 @@ class AttrCursor : public std::enable_shared_from_this<AttrCursor>
|
||||||
friend class EvalCache;
|
friend class EvalCache;
|
||||||
|
|
||||||
ref<EvalCache> root;
|
ref<EvalCache> root;
|
||||||
typedef std::optional<std::pair<std::shared_ptr<AttrCursor>, Symbol>> Parent;
|
typedef std::optional<std::pair<std::shared_ptr<AttrCursor>, std::string>> Parent;
|
||||||
Parent parent;
|
Parent parent;
|
||||||
RootValue _value;
|
RootValue _value;
|
||||||
std::optional<std::pair<AttrId, AttrValue>> cachedValue;
|
std::optional<std::pair<AttrId, AttrValue>> cachedValue;
|
||||||
|
@ -111,29 +112,25 @@ public:
|
||||||
Value * value = nullptr,
|
Value * value = nullptr,
|
||||||
std::optional<std::pair<AttrId, AttrValue>> && cachedValue = {});
|
std::optional<std::pair<AttrId, AttrValue>> && cachedValue = {});
|
||||||
|
|
||||||
std::vector<Symbol> getAttrPath() const;
|
std::vector<std::string> getAttrPath() const;
|
||||||
|
|
||||||
std::vector<Symbol> getAttrPath(Symbol name) const;
|
std::vector<std::string> getAttrPath(std::string_view name) const;
|
||||||
|
|
||||||
std::string getAttrPathStr() const;
|
std::string getAttrPathStr() const;
|
||||||
|
|
||||||
std::string getAttrPathStr(Symbol name) const;
|
std::string getAttrPathStr(std::string_view name) const;
|
||||||
|
|
||||||
Suggestions getSuggestionsForAttr(Symbol name);
|
Suggestions getSuggestionsForAttr(const std::string & name);
|
||||||
|
|
||||||
std::shared_ptr<AttrCursor> maybeGetAttr(Symbol name);
|
std::shared_ptr<AttrCursor> maybeGetAttr(const std::string & name);
|
||||||
|
|
||||||
std::shared_ptr<AttrCursor> maybeGetAttr(std::string_view name);
|
ref<AttrCursor> getAttr(const std::string & name);
|
||||||
|
|
||||||
ref<AttrCursor> getAttr(Symbol name);
|
|
||||||
|
|
||||||
ref<AttrCursor> getAttr(std::string_view 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 std::vector<Symbol> & attrPath);
|
OrSuggestions<ref<AttrCursor>> findAlongAttrPath(const Strings & attrPath);
|
||||||
|
|
||||||
std::string getString();
|
std::string getString();
|
||||||
|
|
||||||
|
@ -145,7 +142,7 @@ public:
|
||||||
|
|
||||||
std::vector<std::string> getListOfStrings();
|
std::vector<std::string> getListOfStrings();
|
||||||
|
|
||||||
std::vector<Symbol> getAttrs();
|
std::vector<std::string> getAttrs();
|
||||||
|
|
||||||
bool isDerivation();
|
bool isDerivation();
|
||||||
|
|
||||||
|
|
|
@ -228,7 +228,6 @@ StaticSymbols::StaticSymbols(SymbolTable & symbols)
|
||||||
, recurseForDerivations(symbols.create("recurseForDerivations"))
|
, recurseForDerivations(symbols.create("recurseForDerivations"))
|
||||||
, description(symbols.create("description"))
|
, description(symbols.create("description"))
|
||||||
, self(symbols.create("self"))
|
, self(symbols.create("self"))
|
||||||
, epsilon(symbols.create(""))
|
|
||||||
, startSet(symbols.create("startSet"))
|
, startSet(symbols.create("startSet"))
|
||||||
, operator_(symbols.create("operator"))
|
, operator_(symbols.create("operator"))
|
||||||
, key(symbols.create("key"))
|
, key(symbols.create("key"))
|
||||||
|
|
|
@ -210,7 +210,7 @@ struct StaticSymbols
|
||||||
ignoreNulls, file, line, column, functor, toString, right, wrong, structuredAttrs,
|
ignoreNulls, file, line, column, functor, toString, right, wrong, structuredAttrs,
|
||||||
allowedReferences, allowedRequisites, disallowedReferences, disallowedRequisites, maxSize,
|
allowedReferences, allowedRequisites, disallowedReferences, disallowedRequisites, maxSize,
|
||||||
maxClosureSize, builder, args, contentAddressed, impure, outputHash, outputHashAlgo,
|
maxClosureSize, builder, args, contentAddressed, impure, outputHash, outputHashAlgo,
|
||||||
outputHashMode, recurseForDerivations, description, self, epsilon, startSet, operator_, key,
|
outputHashMode, recurseForDerivations, description, self, startSet, operator_, key,
|
||||||
path, prefix, outputSpecified;
|
path, prefix, outputSpecified;
|
||||||
|
|
||||||
const Expr::AstSymbols exprSymbols;
|
const Expr::AstSymbols exprSymbols;
|
||||||
|
|
|
@ -97,15 +97,6 @@ public:
|
||||||
return Symbol(idx + 1);
|
return Symbol(idx + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<SymbolStr> resolve(const std::vector<Symbol> & symbols) const
|
|
||||||
{
|
|
||||||
std::vector<SymbolStr> result;
|
|
||||||
result.reserve(symbols.size());
|
|
||||||
for (auto sym : symbols)
|
|
||||||
result.push_back((*this)[sym]);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
SymbolStr operator[](Symbol s) const
|
SymbolStr operator[](Symbol s) const
|
||||||
{
|
{
|
||||||
if (s.id == 0 || s.id > store.size())
|
if (s.id == 0 || s.id > store.size())
|
||||||
|
|
|
@ -59,7 +59,7 @@ UnresolvedApp InstallableValue::toApp()
|
||||||
auto type = cursor->getAttr("type")->getString();
|
auto type = cursor->getAttr("type")->getString();
|
||||||
|
|
||||||
std::string expected = !attrPath.empty() &&
|
std::string expected = !attrPath.empty() &&
|
||||||
(state->symbols[attrPath[0]] == "apps" || state->symbols[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(), expected);
|
||||||
|
@ -99,11 +99,11 @@ UnresolvedApp InstallableValue::toApp()
|
||||||
|
|
||||||
else if (type == "derivation") {
|
else if (type == "derivation") {
|
||||||
auto drvPath = cursor->forceDerivation();
|
auto drvPath = cursor->forceDerivation();
|
||||||
auto outPath = cursor->getAttr(state->s.outPath)->getString();
|
auto outPath = cursor->getAttr("outPath")->getString();
|
||||||
auto outputName = cursor->getAttr(state->s.outputName)->getString();
|
auto outputName = cursor->getAttr("outputName")->getString();
|
||||||
auto name = cursor->getAttr(state->s.name)->getString();
|
auto name = cursor->getAttr("name")->getString();
|
||||||
auto aPname = cursor->maybeGetAttr("pname");
|
auto aPname = cursor->maybeGetAttr("pname");
|
||||||
auto aMeta = cursor->maybeGetAttr(state->s.meta);
|
auto aMeta = cursor->maybeGetAttr("meta");
|
||||||
auto aMainProgram = aMeta ? aMeta->maybeGetAttr("mainProgram") : nullptr;
|
auto aMainProgram = aMeta ? aMeta->maybeGetAttr("mainProgram") : nullptr;
|
||||||
auto mainProgram =
|
auto mainProgram =
|
||||||
aMainProgram
|
aMainProgram
|
||||||
|
|
134
lix/nix/flake.cc
134
lix/nix/flake.cc
|
@ -1136,8 +1136,8 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
|
|
||||||
std::function<bool(
|
std::function<bool(
|
||||||
eval_cache::AttrCursor & visitor,
|
eval_cache::AttrCursor & visitor,
|
||||||
const std::vector<Symbol> &attrPath,
|
std::vector<std::string> attrPath,
|
||||||
const Symbol &attr)> hasContent;
|
const std::string &attr)> hasContent;
|
||||||
|
|
||||||
// For frameworks it's important that structures are as lazy as possible
|
// For frameworks it's important that structures are as lazy as possible
|
||||||
// to prevent infinite recursions, performance issues and errors that
|
// to prevent infinite recursions, performance issues and errors that
|
||||||
|
@ -1147,39 +1147,36 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
// so we omit them.
|
// so we omit them.
|
||||||
hasContent = [&](
|
hasContent = [&](
|
||||||
eval_cache::AttrCursor & visitor,
|
eval_cache::AttrCursor & visitor,
|
||||||
const std::vector<Symbol> &attrPath,
|
std::vector<std::string> attrPath,
|
||||||
const Symbol &attr) -> bool
|
const std::string &attr) -> bool
|
||||||
{
|
{
|
||||||
auto attrPath2(attrPath);
|
attrPath.push_back(attr);
|
||||||
attrPath2.push_back(attr);
|
|
||||||
auto attrPathS = state->symbols.resolve(attrPath2);
|
|
||||||
const auto & attrName = state->symbols[attr];
|
|
||||||
|
|
||||||
auto visitor2 = visitor.getAttr(attrName);
|
auto visitor2 = visitor.getAttr(attr);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ((attrPathS[0] == "apps"
|
if ((attrPath[0] == "apps"
|
||||||
|| attrPathS[0] == "checks"
|
|| attrPath[0] == "checks"
|
||||||
|| attrPathS[0] == "devShells"
|
|| attrPath[0] == "devShells"
|
||||||
|| attrPathS[0] == "legacyPackages"
|
|| attrPath[0] == "legacyPackages"
|
||||||
|| attrPathS[0] == "packages")
|
|| attrPath[0] == "packages")
|
||||||
&& (attrPathS.size() == 1 || attrPathS.size() == 2)) {
|
&& (attrPath.size() == 1 || attrPath.size() == 2)) {
|
||||||
for (const auto &subAttr : visitor2->getAttrs()) {
|
for (const auto &subAttr : visitor2->getAttrs()) {
|
||||||
if (hasContent(*visitor2, attrPath2, subAttr)) {
|
if (hasContent(*visitor2, attrPath, subAttr)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((attrPathS.size() == 1)
|
if ((attrPath.size() == 1)
|
||||||
&& (attrPathS[0] == "formatter"
|
&& (attrPath[0] == "formatter"
|
||||||
|| attrPathS[0] == "nixosConfigurations"
|
|| attrPath[0] == "nixosConfigurations"
|
||||||
|| attrPathS[0] == "nixosModules"
|
|| attrPath[0] == "nixosModules"
|
||||||
|| attrPathS[0] == "overlays"
|
|| attrPath[0] == "overlays"
|
||||||
)) {
|
)) {
|
||||||
for (const auto &subAttr : visitor2->getAttrs()) {
|
for (const auto &subAttr : visitor2->getAttrs()) {
|
||||||
if (hasContent(*visitor2, attrPath2, subAttr)) {
|
if (hasContent(*visitor2, attrPath, subAttr)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1198,54 +1195,51 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
|
|
||||||
std::function<nlohmann::json(
|
std::function<nlohmann::json(
|
||||||
eval_cache::AttrCursor & visitor,
|
eval_cache::AttrCursor & visitor,
|
||||||
const std::vector<Symbol> & attrPath,
|
const std::vector<std::string> & attrPath,
|
||||||
const std::string & headerPrefix,
|
const std::string & headerPrefix,
|
||||||
const std::string & nextPrefix)> visit;
|
const std::string & nextPrefix)> visit;
|
||||||
|
|
||||||
visit = [&](
|
visit = [&](
|
||||||
eval_cache::AttrCursor & visitor,
|
eval_cache::AttrCursor & visitor,
|
||||||
const std::vector<Symbol> & attrPath,
|
const std::vector<std::string> & attrPath,
|
||||||
const std::string & headerPrefix,
|
const std::string & headerPrefix,
|
||||||
const std::string & nextPrefix)
|
const std::string & nextPrefix)
|
||||||
-> nlohmann::json
|
-> nlohmann::json
|
||||||
{
|
{
|
||||||
auto j = nlohmann::json::object();
|
auto j = nlohmann::json::object();
|
||||||
|
|
||||||
auto attrPathS = state->symbols.resolve(attrPath);
|
|
||||||
|
|
||||||
Activity act(*logger, lvlInfo, actUnknown,
|
Activity act(*logger, lvlInfo, actUnknown,
|
||||||
fmt("evaluating '%s'", concatStringsSep(".", attrPathS)));
|
fmt("evaluating '%s'", concatStringsSep(".", attrPath)));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto recurse = [&]()
|
auto recurse = [&]()
|
||||||
{
|
{
|
||||||
if (!json)
|
if (!json)
|
||||||
logger->cout("%s", headerPrefix);
|
logger->cout("%s", headerPrefix);
|
||||||
std::vector<Symbol> attrs;
|
std::vector<std::string> attrs;
|
||||||
for (const auto &attr : visitor.getAttrs()) {
|
for (const auto &attr : visitor.getAttrs()) {
|
||||||
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)) {
|
||||||
const auto & attrName = state->symbols[attr];
|
|
||||||
bool last = i + 1 == attrs.size();
|
bool last = i + 1 == attrs.size();
|
||||||
auto visitor2 = visitor.getAttr(attrName);
|
auto visitor2 = visitor.getAttr(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,
|
||||||
fmt(ANSI_GREEN "%s%s" ANSI_NORMAL ANSI_BOLD "%s" ANSI_NORMAL, nextPrefix, last ? treeLast : treeConn, attrName),
|
fmt(ANSI_GREEN "%s%s" ANSI_NORMAL ANSI_BOLD "%s" ANSI_NORMAL, nextPrefix, last ? treeLast : treeConn, attr),
|
||||||
nextPrefix + (last ? treeNull : treeLine));
|
nextPrefix + (last ? treeNull : treeLine));
|
||||||
if (json) j.emplace(attrName, std::move(j2));
|
if (json) j.emplace(attr, std::move(j2));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto showDerivation = [&]()
|
auto showDerivation = [&]()
|
||||||
{
|
{
|
||||||
auto name = visitor.getAttr(state->s.name)->getString();
|
auto name = visitor.getAttr("name")->getString();
|
||||||
std::optional<std::string> description;
|
std::optional<std::string> description;
|
||||||
if (auto aMeta = visitor.maybeGetAttr(state->s.meta)) {
|
if (auto aMeta = visitor.maybeGetAttr("meta")) {
|
||||||
if (auto aDescription = aMeta->maybeGetAttr(state->s.description))
|
if (auto aDescription = aMeta->maybeGetAttr("description"))
|
||||||
description = aDescription->getString();
|
description = aDescription->getString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1256,10 +1250,10 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
j.emplace("description", *description);
|
j.emplace("description", *description);
|
||||||
} else {
|
} else {
|
||||||
auto type =
|
auto type =
|
||||||
attrPath.size() == 2 && attrPathS[0] == "devShell" ? "development environment" :
|
attrPath.size() == 2 && attrPath[0] == "devShell" ? "development environment" :
|
||||||
attrPath.size() >= 2 && attrPathS[0] == "devShells" ? "development environment" :
|
attrPath.size() >= 2 && attrPath[0] == "devShells" ? "development environment" :
|
||||||
attrPath.size() == 3 && attrPathS[0] == "checks" ? "derivation" :
|
attrPath.size() == 3 && attrPath[0] == "checks" ? "derivation" :
|
||||||
attrPath.size() >= 1 && attrPathS[0] == "hydraJobs" ? "derivation" :
|
attrPath.size() >= 1 && attrPath[0] == "hydraJobs" ? "derivation" :
|
||||||
"package";
|
"package";
|
||||||
|
|
||||||
std::string output = fmt("%s: %s '%s'", headerPrefix, type, name);
|
std::string output = fmt("%s: %s '%s'", headerPrefix, type, name);
|
||||||
|
@ -1300,34 +1294,34 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
|
|
||||||
if (attrPath.size() == 0
|
if (attrPath.size() == 0
|
||||||
|| (attrPath.size() == 1 && (
|
|| (attrPath.size() == 1 && (
|
||||||
attrPathS[0] == "defaultPackage"
|
attrPath[0] == "defaultPackage"
|
||||||
|| attrPathS[0] == "devShell"
|
|| attrPath[0] == "devShell"
|
||||||
|| attrPathS[0] == "formatter"
|
|| attrPath[0] == "formatter"
|
||||||
|| attrPathS[0] == "nixosConfigurations"
|
|| attrPath[0] == "nixosConfigurations"
|
||||||
|| attrPathS[0] == "nixosModules"
|
|| attrPath[0] == "nixosModules"
|
||||||
|| attrPathS[0] == "defaultApp"
|
|| attrPath[0] == "defaultApp"
|
||||||
|| attrPathS[0] == "templates"
|
|| attrPath[0] == "templates"
|
||||||
|| attrPathS[0] == "overlays"))
|
|| attrPath[0] == "overlays"))
|
||||||
|| ((attrPath.size() == 1 || attrPath.size() == 2)
|
|| ((attrPath.size() == 1 || attrPath.size() == 2)
|
||||||
&& (attrPathS[0] == "checks"
|
&& (attrPath[0] == "checks"
|
||||||
|| attrPathS[0] == "packages"
|
|| attrPath[0] == "packages"
|
||||||
|| attrPathS[0] == "devShells"
|
|| attrPath[0] == "devShells"
|
||||||
|| attrPathS[0] == "apps"))
|
|| attrPath[0] == "apps"))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
recurse();
|
recurse();
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (
|
else if (
|
||||||
(attrPath.size() == 2 && (attrPathS[0] == "defaultPackage" || attrPathS[0] == "devShell" || attrPathS[0] == "formatter"))
|
(attrPath.size() == 2 && (attrPath[0] == "defaultPackage" || attrPath[0] == "devShell" || attrPath[0] == "formatter"))
|
||||||
|| (attrPath.size() == 3 && (attrPathS[0] == "checks" || attrPathS[0] == "packages" || attrPathS[0] == "devShells"))
|
|| (attrPath.size() == 3 && (attrPath[0] == "checks" || attrPath[0] == "packages" || attrPath[0] == "devShells"))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (!showAllSystems && std::string(attrPathS[1]) != localSystem) {
|
if (!showAllSystems && attrPath[1] != localSystem) {
|
||||||
if (!json)
|
if (!json)
|
||||||
logger->cout(fmt("%s " ANSI_WARNING "omitted" ANSI_NORMAL " (use '--all-systems' to show)", headerPrefix));
|
logger->cout(fmt("%s " ANSI_WARNING "omitted" ANSI_NORMAL " (use '--all-systems' to show)", headerPrefix));
|
||||||
else {
|
else {
|
||||||
logger->warn(fmt("%s omitted (use '--all-systems' to show)", concatStringsSep(".", attrPathS)));
|
logger->warn(fmt("%s omitted (use '--all-systems' to show)", concatStringsSep(".", attrPath)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (visitor.isDerivation())
|
if (visitor.isDerivation())
|
||||||
|
@ -1337,27 +1331,27 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (attrPath.size() > 0 && attrPathS[0] == "hydraJobs") {
|
else if (attrPath.size() > 0 && attrPath[0] == "hydraJobs") {
|
||||||
if (visitor.isDerivation())
|
if (visitor.isDerivation())
|
||||||
showDerivation();
|
showDerivation();
|
||||||
else
|
else
|
||||||
recurse();
|
recurse();
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (attrPath.size() > 0 && attrPathS[0] == "legacyPackages") {
|
else if (attrPath.size() > 0 && attrPath[0] == "legacyPackages") {
|
||||||
if (attrPath.size() == 1)
|
if (attrPath.size() == 1)
|
||||||
recurse();
|
recurse();
|
||||||
else if (!showLegacy){
|
else if (!showLegacy){
|
||||||
if (!json)
|
if (!json)
|
||||||
logger->cout(fmt("%s " ANSI_WARNING "omitted" ANSI_NORMAL " (use '--legacy' to show)", headerPrefix));
|
logger->cout(fmt("%s " ANSI_WARNING "omitted" ANSI_NORMAL " (use '--legacy' to show)", headerPrefix));
|
||||||
else {
|
else {
|
||||||
logger->warn(fmt("%s omitted (use '--legacy' to show)", concatStringsSep(".", attrPathS)));
|
logger->warn(fmt("%s omitted (use '--legacy' to show)", concatStringsSep(".", attrPath)));
|
||||||
}
|
}
|
||||||
} else if (!showAllSystems && std::string(attrPathS[1]) != localSystem) {
|
} else if (!showAllSystems && attrPath[1] != localSystem) {
|
||||||
if (!json)
|
if (!json)
|
||||||
logger->cout(fmt("%s " ANSI_WARNING "omitted" ANSI_NORMAL " (use '--all-systems' to show)", headerPrefix));
|
logger->cout(fmt("%s " ANSI_WARNING "omitted" ANSI_NORMAL " (use '--all-systems' to show)", headerPrefix));
|
||||||
else {
|
else {
|
||||||
logger->warn(fmt("%s omitted (use '--all-systems' to show)", concatStringsSep(".", attrPathS)));
|
logger->warn(fmt("%s omitted (use '--all-systems' to show)", concatStringsSep(".", attrPath)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (visitor.isDerivation())
|
if (visitor.isDerivation())
|
||||||
|
@ -1369,8 +1363,8 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (
|
else if (
|
||||||
(attrPath.size() == 2 && attrPathS[0] == "defaultApp") ||
|
(attrPath.size() == 2 && attrPath[0] == "defaultApp") ||
|
||||||
(attrPath.size() == 3 && attrPathS[0] == "apps"))
|
(attrPath.size() == 3 && attrPath[0] == "apps"))
|
||||||
{
|
{
|
||||||
auto aType = visitor.maybeGetAttr("type");
|
auto aType = visitor.maybeGetAttr("type");
|
||||||
if (!aType || aType->getString() != "app")
|
if (!aType || aType->getString() != "app")
|
||||||
|
@ -1383,8 +1377,8 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (
|
else if (
|
||||||
(attrPath.size() == 1 && attrPathS[0] == "defaultTemplate") ||
|
(attrPath.size() == 1 && attrPath[0] == "defaultTemplate") ||
|
||||||
(attrPath.size() == 2 && attrPathS[0] == "templates"))
|
(attrPath.size() == 2 && attrPath[0] == "templates"))
|
||||||
{
|
{
|
||||||
auto description = visitor.getAttr("description")->getString();
|
auto description = visitor.getAttr("description")->getString();
|
||||||
if (json) {
|
if (json) {
|
||||||
|
@ -1397,11 +1391,11 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
|
|
||||||
else {
|
else {
|
||||||
auto [type, description] =
|
auto [type, description] =
|
||||||
(attrPath.size() == 1 && attrPathS[0] == "overlay")
|
(attrPath.size() == 1 && attrPath[0] == "overlay")
|
||||||
|| (attrPath.size() == 2 && attrPathS[0] == "overlays") ? std::make_pair("nixpkgs-overlay", "Nixpkgs overlay") :
|
|| (attrPath.size() == 2 && attrPath[0] == "overlays") ? std::make_pair("nixpkgs-overlay", "Nixpkgs overlay") :
|
||||||
attrPath.size() == 2 && attrPathS[0] == "nixosConfigurations" ? std::make_pair("nixos-configuration", "NixOS configuration") :
|
attrPath.size() == 2 && attrPath[0] == "nixosConfigurations" ? std::make_pair("nixos-configuration", "NixOS configuration") :
|
||||||
(attrPath.size() == 1 && attrPathS[0] == "nixosModule")
|
(attrPath.size() == 1 && attrPath[0] == "nixosModule")
|
||||||
|| (attrPath.size() == 2 && attrPathS[0] == "nixosModules") ? std::make_pair("nixos-module", "NixOS module") :
|
|| (attrPath.size() == 2 && attrPath[0] == "nixosModules") ? std::make_pair("nixos-module", "NixOS module") :
|
||||||
std::make_pair("unknown", "unknown");
|
std::make_pair("unknown", "unknown");
|
||||||
if (json) {
|
if (json) {
|
||||||
j.emplace("type", type);
|
j.emplace("type", type);
|
||||||
|
@ -1410,7 +1404,7 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (EvalError & e) {
|
} catch (EvalError & e) {
|
||||||
if (!(attrPath.size() > 0 && attrPathS[0] == "legacyPackages"))
|
if (!(attrPath.size() > 0 && attrPath[0] == "legacyPackages"))
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,33 +91,31 @@ struct CmdSearch : InstallableCommand, MixJSON
|
||||||
|
|
||||||
uint64_t results = 0;
|
uint64_t results = 0;
|
||||||
|
|
||||||
std::function<void(eval_cache::AttrCursor & cursor, const std::vector<Symbol> & attrPath, bool initialRecurse)> visit;
|
std::function<void(eval_cache::AttrCursor & cursor, const std::vector<std::string> & attrPath, bool initialRecurse)> visit;
|
||||||
|
|
||||||
visit = [&](eval_cache::AttrCursor & cursor, const std::vector<Symbol> & attrPath, bool initialRecurse)
|
visit = [&](eval_cache::AttrCursor & cursor, const std::vector<std::string> & attrPath, bool initialRecurse)
|
||||||
{
|
{
|
||||||
auto attrPathS = state->symbols.resolve(attrPath);
|
|
||||||
|
|
||||||
Activity act(*logger, lvlInfo, actUnknown,
|
Activity act(*logger, lvlInfo, actUnknown,
|
||||||
fmt("evaluating '%s'", concatStringsSep(".", attrPathS)));
|
fmt("evaluating '%s'", concatStringsSep(".", attrPath)));
|
||||||
try {
|
try {
|
||||||
auto recurse = [&]()
|
auto recurse = [&]()
|
||||||
{
|
{
|
||||||
for (const auto & attr : cursor.getAttrs()) {
|
for (const auto & attr : cursor.getAttrs()) {
|
||||||
auto cursor2 = cursor.getAttr(state->symbols[attr]);
|
auto cursor2 = cursor.getAttr(attr);
|
||||||
auto attrPath2(attrPath);
|
auto attrPath2(attrPath);
|
||||||
attrPath2.push_back(attr);
|
attrPath2.emplace_back(attr);
|
||||||
visit(*cursor2, attrPath2, false);
|
visit(*cursor2, attrPath2, false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (cursor.isDerivation()) {
|
if (cursor.isDerivation()) {
|
||||||
DrvName name(cursor.getAttr(state->s.name)->getString());
|
DrvName name(cursor.getAttr("name")->getString());
|
||||||
|
|
||||||
auto aMeta = cursor.maybeGetAttr(state->s.meta);
|
auto aMeta = cursor.maybeGetAttr("meta");
|
||||||
auto aDescription = aMeta ? aMeta->maybeGetAttr(state->s.description) : nullptr;
|
auto aDescription = aMeta ? aMeta->maybeGetAttr("description") : nullptr;
|
||||||
auto description = aDescription ? aDescription->getString() : "";
|
auto description = aDescription ? aDescription->getString() : "";
|
||||||
std::replace(description.begin(), description.end(), '\n', ' ');
|
std::replace(description.begin(), description.end(), '\n', ' ');
|
||||||
auto attrPath2 = concatStringsSep(".", attrPathS);
|
auto attrPath2 = concatStringsSep(".", attrPath);
|
||||||
|
|
||||||
std::vector<std::smatch> attrPathMatches;
|
std::vector<std::smatch> attrPathMatches;
|
||||||
std::vector<std::smatch> descriptionMatches;
|
std::vector<std::smatch> descriptionMatches;
|
||||||
|
@ -175,21 +173,21 @@ struct CmdSearch : InstallableCommand, MixJSON
|
||||||
|
|
||||||
else if (
|
else if (
|
||||||
attrPath.size() == 0
|
attrPath.size() == 0
|
||||||
|| (attrPathS[0] == "legacyPackages" && attrPath.size() <= 2)
|
|| (attrPath[0] == "legacyPackages" && attrPath.size() <= 2)
|
||||||
|| (attrPathS[0] == "packages" && attrPath.size() <= 2))
|
|| (attrPath[0] == "packages" && attrPath.size() <= 2))
|
||||||
recurse();
|
recurse();
|
||||||
|
|
||||||
else if (initialRecurse)
|
else if (initialRecurse)
|
||||||
recurse();
|
recurse();
|
||||||
|
|
||||||
else if (attrPathS[0] == "legacyPackages" && attrPath.size() > 2) {
|
else if (attrPath[0] == "legacyPackages" && attrPath.size() > 2) {
|
||||||
auto attr = cursor.maybeGetAttr(state->s.recurseForDerivations);
|
auto attr = cursor.maybeGetAttr("recurseForDerivations");
|
||||||
if (attr && attr->getBool())
|
if (attr && attr->getBool())
|
||||||
recurse();
|
recurse();
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (EvalError & e) {
|
} catch (EvalError & e) {
|
||||||
if (!(attrPath.size() > 0 && attrPathS[0] == "legacyPackages"))
|
if (!(attrPath.size() > 0 && attrPath[0] == "legacyPackages"))
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue