From 9a3e3a5560f8ff20df06433f23fa7495208d7821 Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Tue, 3 Dec 2024 20:38:41 +0100 Subject: [PATCH] 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 --- lix/libcmd/installable-flake.cc | 10 +-- lix/libcmd/installables.cc | 14 ++-- lix/libexpr/attr-path.cc | 11 +-- lix/libexpr/attr-path.hh | 2 +- lix/libexpr/eval-cache.cc | 112 +++++++++++--------------- lix/libexpr/eval-cache.hh | 27 +++---- lix/libexpr/eval.cc | 1 - lix/libexpr/eval.hh | 2 +- lix/libexpr/symbol-table.hh | 9 --- lix/nix/app.cc | 10 +-- lix/nix/flake.cc | 134 +++++++++++++++----------------- lix/nix/search.cc | 30 ++++--- 12 files changed, 155 insertions(+), 207 deletions(-) diff --git a/lix/libcmd/installable-flake.cc b/lix/libcmd/installable-flake.cc index c739cd548..27c4efc35 100644 --- a/lix/libcmd/installable-flake.cc +++ b/lix/libcmd/installable-flake.cc @@ -118,8 +118,8 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths() std::optional priority; - if (attr->maybeGetAttr(state->s.outputSpecified)) { - } else if (auto aMeta = attr->maybeGetAttr(state->s.meta)) { + if (attr->maybeGetAttr("outputSpecified")) { + } else if (auto aMeta = attr->maybeGetAttr("meta")) { if (auto aPriority = aMeta->maybeGetAttr("priority")) priority = aPriority->getInt().value; } @@ -130,12 +130,12 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths() .outputs = std::visit(overloaded { [&](const ExtendedOutputsSpec::Default & d) -> OutputsSpec { std::set outputsToInstall; - if (auto aOutputSpecified = attr->maybeGetAttr(state->s.outputSpecified)) { + if (auto aOutputSpecified = attr->maybeGetAttr("outputSpecified")) { if (aOutputSpecified->getBool()) { if (auto aOutputName = attr->maybeGetAttr("outputName")) 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")) for (auto & s : aOutputsToInstall->getListOfStrings()) outputsToInstall.insert(s); @@ -184,7 +184,7 @@ InstallableFlake::getCursors() for (auto & attrPath : attrPaths) { debug("trying flake output attribute '%s'", attrPath); - auto attr = root->findAlongAttrPath(parseAttrPath(*state, attrPath)); + auto attr = root->findAlongAttrPath(parseAttrPath(attrPath)); if (attr) { res.push_back(ref(*attr)); } else { diff --git a/lix/libcmd/installables.cc b/lix/libcmd/installables.cc index 9c910f795..fea944f71 100644 --- a/lix/libcmd/installables.cc +++ b/lix/libcmd/installables.cc @@ -305,13 +305,13 @@ void completeFlakeRefWithFragment( attrPathPrefixes.push_back(""); for (auto & attrPathPrefixS : attrPathPrefixes) { - auto attrPathPrefix = parseAttrPath(*evalState, attrPathPrefixS); + auto attrPathPrefix = parseAttrPath(attrPathPrefixS); auto attrPathS = attrPathPrefixS + std::string(fragment); - auto attrPath = parseAttrPath(*evalState, attrPathS); + auto attrPath = parseAttrPath(attrPathS); std::string lastAttr; if (!attrPath.empty() && !attrPathS.ends_with(".")) { - lastAttr = evalState->symbols[attrPath.back()]; + lastAttr = attrPath.back(); attrPath.pop_back(); } @@ -319,11 +319,11 @@ void completeFlakeRefWithFragment( if (!attr) continue; for (auto & attr2 : (*attr)->getAttrs()) { - if (std::string_view(evalState->symbols[attr2]).starts_with(lastAttr)) { - auto attrPath2 = (*attr)->getAttrPath(attr2); + if (std::string_view attr2s = attr2; attr2s.starts_with(lastAttr)) { + auto attrPath2 = (*attr)->getAttrPath(attr2s); /* Strip the attrpath prefix. */ 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. */ if (fragment.empty()) { for (auto & attrPath : defaultFlakeAttrPaths) { - auto attr = root->findAlongAttrPath(parseAttrPath(*evalState, attrPath)); + auto attr = root->findAlongAttrPath(parseAttrPath(attrPath)); if (!attr) continue; completions.add(flakeRefS + "#" + prefixRoot); } diff --git a/lix/libexpr/attr-path.cc b/lix/libexpr/attr-path.cc index a70d5c6cf..d0d8923e6 100644 --- a/lix/libexpr/attr-path.cc +++ b/lix/libexpr/attr-path.cc @@ -5,7 +5,7 @@ namespace nix { -static Strings parseAttrPath(std::string_view s) +Strings parseAttrPath(std::string_view s) { Strings res; std::string cur; @@ -31,15 +31,6 @@ static Strings parseAttrPath(std::string_view s) } -std::vector parseAttrPath(EvalState & state, std::string_view s) -{ - std::vector res; - for (auto & a : parseAttrPath(s)) - res.push_back(state.symbols.create(a)); - return res; -} - - std::pair findAlongAttrPath(EvalState & state, const std::string & attrPath, Bindings & autoArgs, Value & vIn) { diff --git a/lix/libexpr/attr-path.hh b/lix/libexpr/attr-path.hh index 2f87bbf05..894899f87 100644 --- a/lix/libexpr/attr-path.hh +++ b/lix/libexpr/attr-path.hh @@ -22,6 +22,6 @@ std::pair findAlongAttrPath( */ std::pair findPackageFilename(EvalState & state, Value & v, std::string what); -std::vector parseAttrPath(EvalState & state, std::string_view s); +Strings parseAttrPath(std::string_view s); } diff --git a/lix/libexpr/eval-cache.cc b/lix/libexpr/eval-cache.cc index b041b8375..bf1560fc4 100644 --- a/lix/libexpr/eval-cache.cc +++ b/lix/libexpr/eval-cache.cc @@ -35,15 +35,11 @@ struct AttrDb std::unique_ptr> _state; - SymbolTable & symbols; - AttrDb( const Store & cfg, - const Hash & fingerprint, - SymbolTable & symbols) + const Hash & fingerprint) : cfg(cfg) , _state(std::make_unique>()) - , symbols(symbols) { auto state(_state->lock()); @@ -98,7 +94,7 @@ struct AttrDb AttrId setAttrs( AttrKey key, - const std::vector & attrs) + const fullattr_t & attrs) { return doSQLite([&]() { @@ -106,17 +102,17 @@ struct AttrDb state->insertAttribute.use() (key.first) - (symbols[key.second]) + (key.second) (AttrType::FullAttrs) (0, false).exec(); AttrId rowId = state->db.getLastInsertedRowId(); assert(rowId); - for (auto & attr : attrs) + for (auto & attr : attrs.p) state->insertAttribute.use() (rowId) - (symbols[attr]) + (attr) (AttrType::Placeholder) (0, false).exec(); @@ -141,14 +137,14 @@ struct AttrDb } state->insertAttributeWithContext.use() (key.first) - (symbols[key.second]) + (key.second) (AttrType::String) (s) (ctx).exec(); } else { state->insertAttribute.use() (key.first) - (symbols[key.second]) + (key.second) (AttrType::String) (s).exec(); } @@ -167,7 +163,7 @@ struct AttrDb state->insertAttribute.use() (key.first) - (symbols[key.second]) + (key.second) (AttrType::Bool) (b ? 1 : 0).exec(); @@ -185,7 +181,7 @@ struct AttrDb state->insertAttribute.use() (key.first) - (symbols[key.second]) + (key.second) (AttrType::Int) (n).exec(); @@ -203,7 +199,7 @@ struct AttrDb state->insertAttribute.use() (key.first) - (symbols[key.second]) + (key.second) (AttrType::ListOfStrings) (concatStringsSep("\t", l)).exec(); @@ -219,7 +215,7 @@ struct AttrDb state->insertAttribute.use() (key.first) - (symbols[key.second]) + (key.second) (AttrType::Placeholder) (0, false).exec(); @@ -235,7 +231,7 @@ struct AttrDb state->insertAttribute.use() (key.first) - (symbols[key.second]) + (key.second) (AttrType::Missing) (0, false).exec(); @@ -251,7 +247,7 @@ struct AttrDb state->insertAttribute.use() (key.first) - (symbols[key.second]) + (key.second) (AttrType::Misc) (0, false).exec(); @@ -267,7 +263,7 @@ struct AttrDb state->insertAttribute.use() (key.first) - (symbols[key.second]) + (key.second) (AttrType::Failed) (0, false).exec(); @@ -279,7 +275,7 @@ struct AttrDb { 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 {}; auto rowId = (AttrId) queryAttribute.getInt(0); @@ -290,10 +286,10 @@ struct AttrDb return {{rowId, placeholder_t()}}; case AttrType::FullAttrs: { // FIXME: expensive, should separate this out. - std::vector attrs; + fullattr_t attrs; auto queryAttributes(state->queryAttributes.use()(rowId)); while (queryAttributes.next()) - attrs.emplace_back(symbols.create(queryAttributes.getStr(0))); + attrs.p.emplace_back(queryAttributes.getStr(0)); return {{rowId, attrs}}; } case AttrType::String: { @@ -323,11 +319,10 @@ struct AttrDb static std::shared_ptr makeAttrDb( const Store & cfg, - const Hash & fingerprint, - SymbolTable & symbols) + const Hash & fingerprint) { try { - return std::make_shared(cfg, fingerprint, symbols); + return std::make_shared(cfg, fingerprint); } catch (SQLiteError &) { ignoreExceptionExceptInterrupt(); return nullptr; @@ -348,7 +343,7 @@ EvalCache::EvalCache( std::optional> useCache, EvalState & state, RootLoader rootLoader) - : db(useCache ? makeAttrDb(*state.store, *useCache, state.symbols) : nullptr) + : db(useCache ? makeAttrDb(*state.store, *useCache) : nullptr) , state(state) , rootLoader(rootLoader) { @@ -382,7 +377,7 @@ AttrCursor::AttrCursor( AttrKey AttrCursor::getKey() { if (!parent) - return {0, root->state.s.epsilon}; + return {0, ""}; if (!parent->first->cachedValue) { parent->first->cachedValue = root->db->getAttr(parent->first->getKey()); assert(parent->first->cachedValue); @@ -396,7 +391,7 @@ Value & AttrCursor::getValue() if (parent) { auto & vParent = parent->first->getValue(); 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) throw Error("attribute '%s' is unexpectedly missing", getAttrPathStr()); _value = allocRootValue(attr->value); @@ -406,7 +401,7 @@ Value & AttrCursor::getValue() return **_value; } -std::vector AttrCursor::getAttrPath() const +std::vector AttrCursor::getAttrPath() const { if (parent) { auto attrPath = parent->first->getAttrPath(); @@ -416,21 +411,21 @@ std::vector AttrCursor::getAttrPath() const return {}; } -std::vector AttrCursor::getAttrPath(Symbol name) const +std::vector AttrCursor::getAttrPath(std::string_view name) const { auto attrPath = getAttrPath(); - attrPath.push_back(name); + attrPath.emplace_back(name); return attrPath; } 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() @@ -469,27 +464,23 @@ Value & AttrCursor::forceValue() return v; } -Suggestions AttrCursor::getSuggestionsForAttr(Symbol name) +Suggestions AttrCursor::getSuggestionsForAttr(const std::string & name) { auto attrNames = getAttrs(); - std::set strAttrNames; - for (auto & name : attrNames) - strAttrNames.insert(root->state.symbols[name]); - - return Suggestions::bestMatches(strAttrNames, root->state.symbols[name]); + return Suggestions::bestMatches({attrNames.begin(), attrNames.end()}, name); } -std::shared_ptr AttrCursor::maybeGetAttr(Symbol name) +std::shared_ptr AttrCursor::maybeGetAttr(const std::string & name) { if (root->db) { if (!cachedValue) cachedValue = root->db->getAttr(getKey()); if (cachedValue) { - if (auto attrs = std::get_if>(&cachedValue->second)) { - for (auto & attr : *attrs) + if (auto attrs = std::get_if(&cachedValue->second)) { + for (auto & attr : attrs->p) if (attr == name) - return std::make_shared(root, std::make_pair(shared_from_this(), attr)); + return std::make_shared(root, std::make_pair(shared_from_this(), name)); return nullptr; } else if (std::get_if(&cachedValue->second)) { auto attr = root->db->getAttr({cachedValue->first, name}); @@ -516,7 +507,7 @@ std::shared_ptr AttrCursor::maybeGetAttr(Symbol name) return nullptr; //errors.make("'%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 (root->db) { @@ -538,12 +529,7 @@ std::shared_ptr AttrCursor::maybeGetAttr(Symbol name) root, std::make_pair(shared_from_this(), name), attr->value, std::move(cachedValue2)); } -std::shared_ptr AttrCursor::maybeGetAttr(std::string_view name) -{ - return maybeGetAttr(root->state.symbols.create(name)); -} - -ref AttrCursor::getAttr(Symbol name) +ref AttrCursor::getAttr(const std::string & name) { auto p = maybeGetAttr(name); if (!p) @@ -551,12 +537,7 @@ ref AttrCursor::getAttr(Symbol name) return ref(p); } -ref AttrCursor::getAttr(std::string_view name) -{ - return getAttr(root->state.symbols.create(name)); -} - -OrSuggestions> AttrCursor::findAlongAttrPath(const std::vector & attrPath) +OrSuggestions> AttrCursor::findAlongAttrPath(const Strings & attrPath) { auto res = shared_from_this(); for (auto & attr : attrPath) { @@ -717,15 +698,15 @@ std::vector AttrCursor::getListOfStrings() return res; } -std::vector AttrCursor::getAttrs() +std::vector AttrCursor::getAttrs() { if (root->db) { if (!cachedValue) cachedValue = root->db->getAttr(getKey()); if (cachedValue && !std::get_if(&cachedValue->second)) { - if (auto attrs = std::get_if>(&cachedValue->second)) { + if (auto attrs = std::get_if(&cachedValue->second)) { debug("using cached attrset attribute '%s'", getAttrPathStr()); - return *attrs; + return attrs->p; } else root->state.errors.make("'%s' is not an attribute set", getAttrPathStr()).debugThrow(); } @@ -736,18 +717,15 @@ std::vector AttrCursor::getAttrs() if (v.type() != nAttrs) root->state.errors.make("'%s' is not an attribute set", getAttrPathStr()).debugThrow(); - std::vector attrs; + fullattr_t attrs; for (auto & attr : *getValue().attrs) - attrs.push_back(attr.name); - std::sort(attrs.begin(), attrs.end(), [&](Symbol a, Symbol b) { - std::string_view sa = root->state.symbols[a], sb = root->state.symbols[b]; - return sa < sb; - }); + attrs.p.push_back(root->state.symbols[attr.name]); + std::sort(attrs.p.begin(), attrs.p.end()); if (root->db) cachedValue = {root->db->setAttrs(getKey(), attrs), attrs}; - return attrs; + return attrs.p; } bool AttrCursor::isDerivation() @@ -758,7 +736,7 @@ bool AttrCursor::isDerivation() StorePath AttrCursor::forceDerivation() { - auto aDrvPath = getAttr(root->state.s.drvPath); + auto aDrvPath = getAttr("drvPath"); auto drvPath = root->state.store->parseStorePath(aDrvPath->getString()); if (!root->state.store->isValidPath(drvPath) && !settings.readOnlyMode) { /* The eval cache contains 'drvPath', but the actual path has diff --git a/lix/libexpr/eval-cache.hh b/lix/libexpr/eval-cache.hh index 255cb2255..bff81dc1e 100644 --- a/lix/libexpr/eval-cache.hh +++ b/lix/libexpr/eval-cache.hh @@ -69,16 +69,17 @@ enum AttrType { }; struct placeholder_t {}; +struct fullattr_t { std::vector p; }; struct missing_t {}; struct misc_t {}; struct failed_t {}; struct int_t { NixInt x; }; typedef uint64_t AttrId; -typedef std::pair AttrKey; +typedef std::pair AttrKey; typedef std::pair string_t; typedef std::variant< - std::vector, + fullattr_t, string_t, placeholder_t, missing_t, @@ -94,7 +95,7 @@ class AttrCursor : public std::enable_shared_from_this friend class EvalCache; ref root; - typedef std::optional, Symbol>> Parent; + typedef std::optional, std::string>> Parent; Parent parent; RootValue _value; std::optional> cachedValue; @@ -111,29 +112,25 @@ public: Value * value = nullptr, std::optional> && cachedValue = {}); - std::vector getAttrPath() const; + std::vector getAttrPath() const; - std::vector getAttrPath(Symbol name) const; + std::vector getAttrPath(std::string_view name) 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 maybeGetAttr(Symbol name); + std::shared_ptr maybeGetAttr(const std::string & name); - std::shared_ptr maybeGetAttr(std::string_view name); - - ref getAttr(Symbol name); - - ref getAttr(std::string_view name); + ref getAttr(const std::string & name); /** * Get an attribute along a chain of attrsets. Note that this does * not auto-call functors or functions. */ - OrSuggestions> findAlongAttrPath(const std::vector & attrPath); + OrSuggestions> findAlongAttrPath(const Strings & attrPath); std::string getString(); @@ -145,7 +142,7 @@ public: std::vector getListOfStrings(); - std::vector getAttrs(); + std::vector getAttrs(); bool isDerivation(); diff --git a/lix/libexpr/eval.cc b/lix/libexpr/eval.cc index 7a7f44c54..677f554d2 100644 --- a/lix/libexpr/eval.cc +++ b/lix/libexpr/eval.cc @@ -228,7 +228,6 @@ StaticSymbols::StaticSymbols(SymbolTable & symbols) , recurseForDerivations(symbols.create("recurseForDerivations")) , description(symbols.create("description")) , self(symbols.create("self")) - , epsilon(symbols.create("")) , startSet(symbols.create("startSet")) , operator_(symbols.create("operator")) , key(symbols.create("key")) diff --git a/lix/libexpr/eval.hh b/lix/libexpr/eval.hh index 90fca9443..a42bdbe0b 100644 --- a/lix/libexpr/eval.hh +++ b/lix/libexpr/eval.hh @@ -210,7 +210,7 @@ struct StaticSymbols ignoreNulls, file, line, column, functor, toString, right, wrong, structuredAttrs, allowedReferences, allowedRequisites, disallowedReferences, disallowedRequisites, maxSize, 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; const Expr::AstSymbols exprSymbols; diff --git a/lix/libexpr/symbol-table.hh b/lix/libexpr/symbol-table.hh index 846685050..84f62cea3 100644 --- a/lix/libexpr/symbol-table.hh +++ b/lix/libexpr/symbol-table.hh @@ -97,15 +97,6 @@ public: return Symbol(idx + 1); } - std::vector resolve(const std::vector & symbols) const - { - std::vector result; - result.reserve(symbols.size()); - for (auto sym : symbols) - result.push_back((*this)[sym]); - return result; - } - SymbolStr operator[](Symbol s) const { if (s.id == 0 || s.id > store.size()) diff --git a/lix/nix/app.cc b/lix/nix/app.cc index 32de7050d..8bcc54c75 100644 --- a/lix/nix/app.cc +++ b/lix/nix/app.cc @@ -59,7 +59,7 @@ UnresolvedApp InstallableValue::toApp() auto type = cursor->getAttr("type")->getString(); std::string expected = !attrPath.empty() && - (state->symbols[attrPath[0]] == "apps" || state->symbols[attrPath[0]] == "defaultApp") + (attrPath[0] == "apps" || attrPath[0] == "defaultApp") ? "app" : "derivation"; if (type != expected) throw Error("attribute '%s' should have type '%s'", cursor->getAttrPathStr(), expected); @@ -99,11 +99,11 @@ UnresolvedApp InstallableValue::toApp() else if (type == "derivation") { auto drvPath = cursor->forceDerivation(); - auto outPath = cursor->getAttr(state->s.outPath)->getString(); - auto outputName = cursor->getAttr(state->s.outputName)->getString(); - auto name = cursor->getAttr(state->s.name)->getString(); + auto outPath = cursor->getAttr("outPath")->getString(); + auto outputName = cursor->getAttr("outputName")->getString(); + auto name = cursor->getAttr("name")->getString(); 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 mainProgram = aMainProgram diff --git a/lix/nix/flake.cc b/lix/nix/flake.cc index e8a239c39..5cbaece47 100644 --- a/lix/nix/flake.cc +++ b/lix/nix/flake.cc @@ -1136,8 +1136,8 @@ struct CmdFlakeShow : FlakeCommand, MixJSON std::function &attrPath, - const Symbol &attr)> hasContent; + std::vector attrPath, + const std::string &attr)> hasContent; // For frameworks it's important that structures are as lazy as possible // to prevent infinite recursions, performance issues and errors that @@ -1147,39 +1147,36 @@ struct CmdFlakeShow : FlakeCommand, MixJSON // so we omit them. hasContent = [&]( eval_cache::AttrCursor & visitor, - const std::vector &attrPath, - const Symbol &attr) -> bool + std::vector attrPath, + const std::string &attr) -> bool { - auto attrPath2(attrPath); - attrPath2.push_back(attr); - auto attrPathS = state->symbols.resolve(attrPath2); - const auto & attrName = state->symbols[attr]; + attrPath.push_back(attr); - auto visitor2 = visitor.getAttr(attrName); + auto visitor2 = visitor.getAttr(attr); try { - if ((attrPathS[0] == "apps" - || attrPathS[0] == "checks" - || attrPathS[0] == "devShells" - || attrPathS[0] == "legacyPackages" - || attrPathS[0] == "packages") - && (attrPathS.size() == 1 || attrPathS.size() == 2)) { + if ((attrPath[0] == "apps" + || attrPath[0] == "checks" + || attrPath[0] == "devShells" + || attrPath[0] == "legacyPackages" + || attrPath[0] == "packages") + && (attrPath.size() == 1 || attrPath.size() == 2)) { for (const auto &subAttr : visitor2->getAttrs()) { - if (hasContent(*visitor2, attrPath2, subAttr)) { + if (hasContent(*visitor2, attrPath, subAttr)) { return true; } } return false; } - if ((attrPathS.size() == 1) - && (attrPathS[0] == "formatter" - || attrPathS[0] == "nixosConfigurations" - || attrPathS[0] == "nixosModules" - || attrPathS[0] == "overlays" + if ((attrPath.size() == 1) + && (attrPath[0] == "formatter" + || attrPath[0] == "nixosConfigurations" + || attrPath[0] == "nixosModules" + || attrPath[0] == "overlays" )) { for (const auto &subAttr : visitor2->getAttrs()) { - if (hasContent(*visitor2, attrPath2, subAttr)) { + if (hasContent(*visitor2, attrPath, subAttr)) { return true; } } @@ -1198,54 +1195,51 @@ struct CmdFlakeShow : FlakeCommand, MixJSON std::function & attrPath, + const std::vector & attrPath, const std::string & headerPrefix, const std::string & nextPrefix)> visit; visit = [&]( eval_cache::AttrCursor & visitor, - const std::vector & attrPath, + const std::vector & attrPath, const std::string & headerPrefix, const std::string & nextPrefix) -> nlohmann::json { auto j = nlohmann::json::object(); - auto attrPathS = state->symbols.resolve(attrPath); - Activity act(*logger, lvlInfo, actUnknown, - fmt("evaluating '%s'", concatStringsSep(".", attrPathS))); + fmt("evaluating '%s'", concatStringsSep(".", attrPath))); try { auto recurse = [&]() { if (!json) logger->cout("%s", headerPrefix); - std::vector attrs; + std::vector attrs; for (const auto &attr : visitor.getAttrs()) { if (hasContent(visitor, attrPath, attr)) attrs.push_back(attr); } for (const auto & [i, attr] : enumerate(attrs)) { - const auto & attrName = state->symbols[attr]; bool last = i + 1 == attrs.size(); - auto visitor2 = visitor.getAttr(attrName); + auto visitor2 = visitor.getAttr(attr); auto attrPath2(attrPath); attrPath2.push_back(attr); 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)); - if (json) j.emplace(attrName, std::move(j2)); + if (json) j.emplace(attr, std::move(j2)); } }; auto showDerivation = [&]() { - auto name = visitor.getAttr(state->s.name)->getString(); + auto name = visitor.getAttr("name")->getString(); std::optional description; - if (auto aMeta = visitor.maybeGetAttr(state->s.meta)) { - if (auto aDescription = aMeta->maybeGetAttr(state->s.description)) + if (auto aMeta = visitor.maybeGetAttr("meta")) { + if (auto aDescription = aMeta->maybeGetAttr("description")) description = aDescription->getString(); } @@ -1256,10 +1250,10 @@ struct CmdFlakeShow : FlakeCommand, MixJSON j.emplace("description", *description); } else { auto type = - attrPath.size() == 2 && attrPathS[0] == "devShell" ? "development environment" : - attrPath.size() >= 2 && attrPathS[0] == "devShells" ? "development environment" : - attrPath.size() == 3 && attrPathS[0] == "checks" ? "derivation" : - attrPath.size() >= 1 && attrPathS[0] == "hydraJobs" ? "derivation" : + attrPath.size() == 2 && attrPath[0] == "devShell" ? "development environment" : + attrPath.size() >= 2 && attrPath[0] == "devShells" ? "development environment" : + attrPath.size() == 3 && attrPath[0] == "checks" ? "derivation" : + attrPath.size() >= 1 && attrPath[0] == "hydraJobs" ? "derivation" : "package"; std::string output = fmt("%s: %s '%s'", headerPrefix, type, name); @@ -1300,34 +1294,34 @@ struct CmdFlakeShow : FlakeCommand, MixJSON if (attrPath.size() == 0 || (attrPath.size() == 1 && ( - attrPathS[0] == "defaultPackage" - || attrPathS[0] == "devShell" - || attrPathS[0] == "formatter" - || attrPathS[0] == "nixosConfigurations" - || attrPathS[0] == "nixosModules" - || attrPathS[0] == "defaultApp" - || attrPathS[0] == "templates" - || attrPathS[0] == "overlays")) + attrPath[0] == "defaultPackage" + || attrPath[0] == "devShell" + || attrPath[0] == "formatter" + || attrPath[0] == "nixosConfigurations" + || attrPath[0] == "nixosModules" + || attrPath[0] == "defaultApp" + || attrPath[0] == "templates" + || attrPath[0] == "overlays")) || ((attrPath.size() == 1 || attrPath.size() == 2) - && (attrPathS[0] == "checks" - || attrPathS[0] == "packages" - || attrPathS[0] == "devShells" - || attrPathS[0] == "apps")) + && (attrPath[0] == "checks" + || attrPath[0] == "packages" + || attrPath[0] == "devShells" + || attrPath[0] == "apps")) ) { recurse(); } else if ( - (attrPath.size() == 2 && (attrPathS[0] == "defaultPackage" || attrPathS[0] == "devShell" || attrPathS[0] == "formatter")) - || (attrPath.size() == 3 && (attrPathS[0] == "checks" || attrPathS[0] == "packages" || attrPathS[0] == "devShells")) + (attrPath.size() == 2 && (attrPath[0] == "defaultPackage" || attrPath[0] == "devShell" || attrPath[0] == "formatter")) + || (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) logger->cout(fmt("%s " ANSI_WARNING "omitted" ANSI_NORMAL " (use '--all-systems' to show)", headerPrefix)); 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 { 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()) showDerivation(); else recurse(); } - else if (attrPath.size() > 0 && attrPathS[0] == "legacyPackages") { + else if (attrPath.size() > 0 && attrPath[0] == "legacyPackages") { if (attrPath.size() == 1) recurse(); else if (!showLegacy){ if (!json) logger->cout(fmt("%s " ANSI_WARNING "omitted" ANSI_NORMAL " (use '--legacy' to show)", headerPrefix)); 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) logger->cout(fmt("%s " ANSI_WARNING "omitted" ANSI_NORMAL " (use '--all-systems' to show)", headerPrefix)); 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 { if (visitor.isDerivation()) @@ -1369,8 +1363,8 @@ struct CmdFlakeShow : FlakeCommand, MixJSON } else if ( - (attrPath.size() == 2 && attrPathS[0] == "defaultApp") || - (attrPath.size() == 3 && attrPathS[0] == "apps")) + (attrPath.size() == 2 && attrPath[0] == "defaultApp") || + (attrPath.size() == 3 && attrPath[0] == "apps")) { auto aType = visitor.maybeGetAttr("type"); if (!aType || aType->getString() != "app") @@ -1383,8 +1377,8 @@ struct CmdFlakeShow : FlakeCommand, MixJSON } else if ( - (attrPath.size() == 1 && attrPathS[0] == "defaultTemplate") || - (attrPath.size() == 2 && attrPathS[0] == "templates")) + (attrPath.size() == 1 && attrPath[0] == "defaultTemplate") || + (attrPath.size() == 2 && attrPath[0] == "templates")) { auto description = visitor.getAttr("description")->getString(); if (json) { @@ -1397,11 +1391,11 @@ struct CmdFlakeShow : FlakeCommand, MixJSON else { auto [type, description] = - (attrPath.size() == 1 && attrPathS[0] == "overlay") - || (attrPath.size() == 2 && attrPathS[0] == "overlays") ? std::make_pair("nixpkgs-overlay", "Nixpkgs overlay") : - attrPath.size() == 2 && attrPathS[0] == "nixosConfigurations" ? std::make_pair("nixos-configuration", "NixOS configuration") : - (attrPath.size() == 1 && attrPathS[0] == "nixosModule") - || (attrPath.size() == 2 && attrPathS[0] == "nixosModules") ? std::make_pair("nixos-module", "NixOS module") : + (attrPath.size() == 1 && attrPath[0] == "overlay") + || (attrPath.size() == 2 && attrPath[0] == "overlays") ? std::make_pair("nixpkgs-overlay", "Nixpkgs overlay") : + attrPath.size() == 2 && attrPath[0] == "nixosConfigurations" ? std::make_pair("nixos-configuration", "NixOS configuration") : + (attrPath.size() == 1 && attrPath[0] == "nixosModule") + || (attrPath.size() == 2 && attrPath[0] == "nixosModules") ? std::make_pair("nixos-module", "NixOS module") : std::make_pair("unknown", "unknown"); if (json) { j.emplace("type", type); @@ -1410,7 +1404,7 @@ struct CmdFlakeShow : FlakeCommand, MixJSON } } } catch (EvalError & e) { - if (!(attrPath.size() > 0 && attrPathS[0] == "legacyPackages")) + if (!(attrPath.size() > 0 && attrPath[0] == "legacyPackages")) throw; } diff --git a/lix/nix/search.cc b/lix/nix/search.cc index a6bafa383..b9845df7a 100644 --- a/lix/nix/search.cc +++ b/lix/nix/search.cc @@ -91,33 +91,31 @@ struct CmdSearch : InstallableCommand, MixJSON uint64_t results = 0; - std::function & attrPath, bool initialRecurse)> visit; + std::function & attrPath, bool initialRecurse)> visit; - visit = [&](eval_cache::AttrCursor & cursor, const std::vector & attrPath, bool initialRecurse) + visit = [&](eval_cache::AttrCursor & cursor, const std::vector & attrPath, bool initialRecurse) { - auto attrPathS = state->symbols.resolve(attrPath); - Activity act(*logger, lvlInfo, actUnknown, - fmt("evaluating '%s'", concatStringsSep(".", attrPathS))); + fmt("evaluating '%s'", concatStringsSep(".", attrPath))); try { auto recurse = [&]() { for (const auto & attr : cursor.getAttrs()) { - auto cursor2 = cursor.getAttr(state->symbols[attr]); + auto cursor2 = cursor.getAttr(attr); auto attrPath2(attrPath); - attrPath2.push_back(attr); + attrPath2.emplace_back(attr); visit(*cursor2, attrPath2, false); } }; 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 aDescription = aMeta ? aMeta->maybeGetAttr(state->s.description) : nullptr; + auto aMeta = cursor.maybeGetAttr("meta"); + auto aDescription = aMeta ? aMeta->maybeGetAttr("description") : nullptr; auto description = aDescription ? aDescription->getString() : ""; std::replace(description.begin(), description.end(), '\n', ' '); - auto attrPath2 = concatStringsSep(".", attrPathS); + auto attrPath2 = concatStringsSep(".", attrPath); std::vector attrPathMatches; std::vector descriptionMatches; @@ -175,21 +173,21 @@ struct CmdSearch : InstallableCommand, MixJSON else if ( attrPath.size() == 0 - || (attrPathS[0] == "legacyPackages" && attrPath.size() <= 2) - || (attrPathS[0] == "packages" && attrPath.size() <= 2)) + || (attrPath[0] == "legacyPackages" && attrPath.size() <= 2) + || (attrPath[0] == "packages" && attrPath.size() <= 2)) recurse(); else if (initialRecurse) recurse(); - else if (attrPathS[0] == "legacyPackages" && attrPath.size() > 2) { - auto attr = cursor.maybeGetAttr(state->s.recurseForDerivations); + else if (attrPath[0] == "legacyPackages" && attrPath.size() > 2) { + auto attr = cursor.maybeGetAttr("recurseForDerivations"); if (attr && attr->getBool()) recurse(); } } catch (EvalError & e) { - if (!(attrPath.size() > 0 && attrPathS[0] == "legacyPackages")) + if (!(attrPath.size() > 0 && attrPath[0] == "legacyPackages")) throw; } };