diff options
author | Vincent Ambo <tazjin@google.com> | 2020-05-17T15·31+0100 |
---|---|---|
committer | Vincent Ambo <tazjin@google.com> | 2020-05-17T15·31+0100 |
commit | 0f2cf531f705d370321843e5ba9135b2ebdb5d19 (patch) | |
tree | 256feb13963a849ed96e89228fa05454c2a22363 /third_party/nix/src/nix/search.cc | |
parent | 65a1aae98ce5a237c9643e639e550c8b0c0be7f1 (diff) |
style(3p/nix): Reformat project in Google C++ style r/740
Reformatted with: fd . -e hh -e cc | xargs clang-format -i
Diffstat (limited to 'third_party/nix/src/nix/search.cc')
-rw-r--r-- | third_party/nix/src/nix/search.cc | 446 |
1 files changed, 214 insertions, 232 deletions
diff --git a/third_party/nix/src/nix/search.cc b/third_party/nix/src/nix/search.cc index eb75493e4759..fab8bba6283a 100644 --- a/third_party/nix/src/nix/search.cc +++ b/third_party/nix/src/nix/search.cc @@ -1,280 +1,262 @@ +#include <fstream> +#include <regex> #include "command.hh" -#include "globals.hh" -#include "eval.hh" +#include "common-args.hh" #include "eval-inline.hh" -#include "names.hh" +#include "eval.hh" #include "get-drvs.hh" -#include "common-args.hh" -#include "json.hh" +#include "globals.hh" #include "json-to-value.hh" +#include "json.hh" +#include "names.hh" #include "shared.hh" -#include <regex> -#include <fstream> - using namespace nix; -std::string wrap(std::string prefix, std::string s) -{ - return prefix + s + ANSI_NORMAL; +std::string wrap(std::string prefix, std::string s) { + return prefix + s + ANSI_NORMAL; } -std::string hilite(const std::string & s, const std::smatch & m, std::string postfix) -{ - return - m.empty() - ? s - : std::string(m.prefix()) - + ANSI_RED + std::string(m.str()) + postfix - + std::string(m.suffix()); +std::string hilite(const std::string& s, const std::smatch& m, + std::string postfix) { + return m.empty() ? s + : std::string(m.prefix()) + ANSI_RED + std::string(m.str()) + + postfix + std::string(m.suffix()); } -struct CmdSearch : SourceExprCommand, MixJSON -{ - std::vector<std::string> res; +struct CmdSearch : SourceExprCommand, MixJSON { + std::vector<std::string> res; + + bool writeCache = true; + bool useCache = true; + + CmdSearch() { + expectArgs("regex", &res); + + mkFlag() + .longName("update-cache") + .shortName('u') + .description("update the package search cache") + .handler([&]() { + writeCache = true; + useCache = false; + }); + + mkFlag() + .longName("no-cache") + .description("do not use or update the package search cache") + .handler([&]() { + writeCache = false; + useCache = false; + }); + } + + std::string name() override { return "search"; } + + std::string description() override { return "query available packages"; } + + Examples examples() override { + return {Example{"To show all available packages:", "nix search"}, + Example{"To show any packages containing 'blender' in its name or " + "description:", + "nix search blender"}, + Example{"To search for Firefox or Chromium:", + "nix search 'firefox|chromium'"}, + Example{"To search for git and frontend or gui:", + "nix search git 'frontend|gui'"}}; + } + + void run(ref<Store> store) override { + settings.readOnlyMode = true; + + // Empty search string should match all packages + // Use "^" here instead of ".*" due to differences in resulting highlighting + // (see #1893 -- libc++ claims empty search string is not in POSIX grammar) + if (res.empty()) { + res.push_back("^"); + } - bool writeCache = true; - bool useCache = true; + std::vector<std::regex> regexes; + regexes.reserve(res.size()); - CmdSearch() - { - expectArgs("regex", &res); + for (auto& re : res) { + regexes.push_back( + std::regex(re, std::regex::extended | std::regex::icase)); + } - mkFlag() - .longName("update-cache") - .shortName('u') - .description("update the package search cache") - .handler([&]() { writeCache = true; useCache = false; }); + auto state = getEvalState(); - mkFlag() - .longName("no-cache") - .description("do not use or update the package search cache") - .handler([&]() { writeCache = false; useCache = false; }); - } + auto jsonOut = json ? std::make_unique<JSONObject>(std::cout) : nullptr; - std::string name() override - { - return "search"; - } + auto sToplevel = state->symbols.create("_toplevel"); + auto sRecurse = state->symbols.create("recurseForDerivations"); - std::string description() override - { - return "query available packages"; - } + bool fromCache = false; - Examples examples() override - { - return { - Example{ - "To show all available packages:", - "nix search" - }, - Example{ - "To show any packages containing 'blender' in its name or description:", - "nix search blender" - }, - Example{ - "To search for Firefox or Chromium:", - "nix search 'firefox|chromium'" - }, - Example{ - "To search for git and frontend or gui:", - "nix search git 'frontend|gui'" - } - }; - } + std::map<std::string, std::string> results; - void run(ref<Store> store) override - { - settings.readOnlyMode = true; + std::function<void(Value*, std::string, bool, JSONObject*)> doExpr; - // Empty search string should match all packages - // Use "^" here instead of ".*" due to differences in resulting highlighting - // (see #1893 -- libc++ claims empty search string is not in POSIX grammar) - if (res.empty()) { - res.push_back("^"); - } + doExpr = [&](Value* v, std::string attrPath, bool toplevel, + JSONObject* cache) { + debug("at attribute '%s'", attrPath); + + try { + uint found = 0; - std::vector<std::regex> regexes; - regexes.reserve(res.size()); + state->forceValue(*v); - for (auto &re : res) { - regexes.push_back(std::regex(re, std::regex::extended | std::regex::icase)); + if (v->type == tLambda && toplevel) { + Value* v2 = state->allocValue(); + state->autoCallFunction(*state->allocBindings(1), *v, *v2); + v = v2; + state->forceValue(*v); } - auto state = getEvalState(); + if (state->isDerivation(*v)) { + DrvInfo drv(*state, attrPath, v->attrs); + std::string description; + std::smatch attrPathMatch; + std::smatch descriptionMatch; + std::smatch nameMatch; + std::string name; - auto jsonOut = json ? std::make_unique<JSONObject>(std::cout) : nullptr; - - auto sToplevel = state->symbols.create("_toplevel"); - auto sRecurse = state->symbols.create("recurseForDerivations"); - - bool fromCache = false; - - std::map<std::string, std::string> results; - - std::function<void(Value *, std::string, bool, JSONObject *)> doExpr; - - doExpr = [&](Value * v, std::string attrPath, bool toplevel, JSONObject * cache) { - debug("at attribute '%s'", attrPath); - - try { - uint found = 0; - - state->forceValue(*v); - - if (v->type == tLambda && toplevel) { - Value * v2 = state->allocValue(); - state->autoCallFunction(*state->allocBindings(1), *v, *v2); - v = v2; - state->forceValue(*v); - } - - if (state->isDerivation(*v)) { - - DrvInfo drv(*state, attrPath, v->attrs); - std::string description; - std::smatch attrPathMatch; - std::smatch descriptionMatch; - std::smatch nameMatch; - std::string name; - - DrvName parsed(drv.queryName()); - - for (auto ®ex : regexes) { - std::regex_search(attrPath, attrPathMatch, regex); - - name = parsed.name; - std::regex_search(name, nameMatch, regex); - - description = drv.queryMetaString("description"); - std::replace(description.begin(), description.end(), '\n', ' '); - std::regex_search(description, descriptionMatch, regex); - - if (!attrPathMatch.empty() - || !nameMatch.empty() - || !descriptionMatch.empty()) - { - found++; - } - } - - if (found == res.size()) { - if (json) { - - auto jsonElem = jsonOut->object(attrPath); - - jsonElem.attr("pkgName", parsed.name); - jsonElem.attr("version", parsed.version); - jsonElem.attr("description", description); - - } else { - auto name = hilite(parsed.name, nameMatch, "\e[0;2m") - + std::string(parsed.fullName, parsed.name.length()); - results[attrPath] = fmt( - "* %s (%s)\n %s\n", - wrap("\e[0;1m", hilite(attrPath, attrPathMatch, "\e[0;1m")), - wrap("\e[0;2m", hilite(name, nameMatch, "\e[0;2m")), - hilite(description, descriptionMatch, ANSI_NORMAL)); - } - } - - if (cache) { - cache->attr("type", "derivation"); - cache->attr("name", drv.queryName()); - cache->attr("system", drv.querySystem()); - if (description != "") { - auto meta(cache->object("meta")); - meta.attr("description", description); - } - } - } - - else if (v->type == tAttrs) { - - if (!toplevel) { - auto attrs = v->attrs; - Bindings::iterator j = attrs->find(sRecurse); - if (j == attrs->end() || !state->forceBool(*j->value, *j->pos)) { - debug("skip attribute '%s'", attrPath); - return; - } - } - - bool toplevel2 = false; - if (!fromCache) { - Bindings::iterator j = v->attrs->find(sToplevel); - toplevel2 = j != v->attrs->end() && state->forceBool(*j->value, *j->pos); - } - - for (auto & i : *v->attrs) { - auto cache2 = - cache ? std::make_unique<JSONObject>(cache->object(i.name)) : nullptr; - doExpr(i.value, - attrPath == "" ? (std::string) i.name : attrPath + "." + (std::string) i.name, - toplevel2 || fromCache, cache2 ? cache2.get() : nullptr); - } - } - - } catch (AssertionError & e) { - } catch (Error & e) { - if (!toplevel) { - e.addPrefix(fmt("While evaluating the attribute '%s':\n", attrPath)); - throw; - } - } - }; + DrvName parsed(drv.queryName()); - Path jsonCacheFileName = getCacheDir() + "/nix/package-search.json"; + for (auto& regex : regexes) { + std::regex_search(attrPath, attrPathMatch, regex); - if (useCache && pathExists(jsonCacheFileName)) { + name = parsed.name; + std::regex_search(name, nameMatch, regex); - warn("using cached results; pass '-u' to update the cache"); + description = drv.queryMetaString("description"); + std::replace(description.begin(), description.end(), '\n', ' '); + std::regex_search(description, descriptionMatch, regex); - Value vRoot; - parseJSON(*state, readFile(jsonCacheFileName), vRoot); + if (!attrPathMatch.empty() || !nameMatch.empty() || + !descriptionMatch.empty()) { + found++; + } + } + + if (found == res.size()) { + if (json) { + auto jsonElem = jsonOut->object(attrPath); + + jsonElem.attr("pkgName", parsed.name); + jsonElem.attr("version", parsed.version); + jsonElem.attr("description", description); + + } else { + auto name = hilite(parsed.name, nameMatch, "\e[0;2m") + + std::string(parsed.fullName, parsed.name.length()); + results[attrPath] = fmt( + "* %s (%s)\n %s\n", + wrap("\e[0;1m", hilite(attrPath, attrPathMatch, "\e[0;1m")), + wrap("\e[0;2m", hilite(name, nameMatch, "\e[0;2m")), + hilite(description, descriptionMatch, ANSI_NORMAL)); + } + } + + if (cache) { + cache->attr("type", "derivation"); + cache->attr("name", drv.queryName()); + cache->attr("system", drv.querySystem()); + if (description != "") { + auto meta(cache->object("meta")); + meta.attr("description", description); + } + } + } - fromCache = true; + else if (v->type == tAttrs) { + if (!toplevel) { + auto attrs = v->attrs; + Bindings::iterator j = attrs->find(sRecurse); + if (j == attrs->end() || !state->forceBool(*j->value, *j->pos)) { + debug("skip attribute '%s'", attrPath); + return; + } + } + + bool toplevel2 = false; + if (!fromCache) { + Bindings::iterator j = v->attrs->find(sToplevel); + toplevel2 = + j != v->attrs->end() && state->forceBool(*j->value, *j->pos); + } + + for (auto& i : *v->attrs) { + auto cache2 = + cache ? std::make_unique<JSONObject>(cache->object(i.name)) + : nullptr; + doExpr(i.value, + attrPath == "" ? (std::string)i.name + : attrPath + "." + (std::string)i.name, + toplevel2 || fromCache, cache2 ? cache2.get() : nullptr); + } + } - doExpr(&vRoot, "", true, nullptr); + } catch (AssertionError& e) { + } catch (Error& e) { + if (!toplevel) { + e.addPrefix(fmt("While evaluating the attribute '%s':\n", attrPath)); + throw; } + } + }; - else { - createDirs(dirOf(jsonCacheFileName)); + Path jsonCacheFileName = getCacheDir() + "/nix/package-search.json"; - Path tmpFile = fmt("%s.tmp.%d", jsonCacheFileName, getpid()); + if (useCache && pathExists(jsonCacheFileName)) { + warn("using cached results; pass '-u' to update the cache"); - std::ofstream jsonCacheFile; + Value vRoot; + parseJSON(*state, readFile(jsonCacheFileName), vRoot); - try { - // iostream considered harmful - jsonCacheFile.exceptions(std::ofstream::failbit); - jsonCacheFile.open(tmpFile); + fromCache = true; - auto cache = writeCache ? std::make_unique<JSONObject>(jsonCacheFile, false) : nullptr; + doExpr(&vRoot, "", true, nullptr); + } - doExpr(getSourceExpr(*state), "", true, cache.get()); + else { + createDirs(dirOf(jsonCacheFileName)); - } catch (std::exception &) { - /* Fun fact: catching std::ios::failure does not work - due to C++11 ABI shenanigans. - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66145 */ - if (!jsonCacheFile) - throw Error("error writing to %s", tmpFile); - throw; - } + Path tmpFile = fmt("%s.tmp.%d", jsonCacheFileName, getpid()); - if (writeCache && rename(tmpFile.c_str(), jsonCacheFileName.c_str()) == -1) - throw SysError("cannot rename '%s' to '%s'", tmpFile, jsonCacheFileName); - } + std::ofstream jsonCacheFile; - if (results.size() == 0) - throw Error("no results for the given search term(s)!"); + try { + // iostream considered harmful + jsonCacheFile.exceptions(std::ofstream::failbit); + jsonCacheFile.open(tmpFile); - RunPager pager; - for (auto el : results) std::cout << el.second << "\n"; + auto cache = writeCache + ? std::make_unique<JSONObject>(jsonCacheFile, false) + : nullptr; + doExpr(getSourceExpr(*state), "", true, cache.get()); + + } catch (std::exception&) { + /* Fun fact: catching std::ios::failure does not work + due to C++11 ABI shenanigans. + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66145 */ + if (!jsonCacheFile) throw Error("error writing to %s", tmpFile); + throw; + } + + if (writeCache && + rename(tmpFile.c_str(), jsonCacheFileName.c_str()) == -1) + throw SysError("cannot rename '%s' to '%s'", tmpFile, + jsonCacheFileName); } + + if (results.size() == 0) + throw Error("no results for the given search term(s)!"); + + RunPager pager; + for (auto el : results) std::cout << el.second << "\n"; + } }; static RegisterCommand r1(make_ref<CmdSearch>()); |