aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2020-04-27 16:29:26 +0200
committerEelco Dolstra <edolstra@gmail.com>2020-04-27 16:29:26 +0200
commitb4e23dcd9e0a52644517f8a7777e3c2e6b92481a (patch)
treed42f9b5cb7034d70d9475e11b9e10e5a5ed742b8 /src
parent0469795978599d84bc47226f373e178332fc0aaa (diff)
nix search: Search legacyPackages recursively
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/eval-cache.cc82
-rw-r--r--src/libexpr/eval-cache.hh5
-rw-r--r--src/libexpr/eval.cc1
-rw-r--r--src/libexpr/eval.hh2
-rw-r--r--src/libexpr/get-drvs.cc2
-rw-r--r--src/nix/search.cc6
6 files changed, 76 insertions, 22 deletions
diff --git a/src/libexpr/eval-cache.cc b/src/libexpr/eval-cache.cc
index e17dbde84..b503d8f04 100644
--- a/src/libexpr/eval-cache.cc
+++ b/src/libexpr/eval-cache.cc
@@ -106,6 +106,21 @@ struct AttrDb
return state->db.getLastInsertedRowId();
}
+ AttrId setBool(
+ AttrKey key,
+ bool b)
+ {
+ auto state(_state->lock());
+
+ state->insertAttribute.use()
+ (key.first)
+ (key.second)
+ (AttrType::Bool)
+ (b ? 1 : 0).exec();
+
+ return state->db.getLastInsertedRowId();
+ }
+
AttrId setPlaceholder(AttrKey key)
{
auto state(_state->lock());
@@ -170,25 +185,30 @@ struct AttrDb
auto rowId = (AttrType) queryAttribute.getInt(0);
auto type = (AttrType) queryAttribute.getInt(1);
- if (type == AttrType::Placeholder)
- return {{rowId, placeholder_t()}};
- else if (type == AttrType::FullAttrs) {
- // FIXME: expensive, should separate this out.
- std::vector<Symbol> attrs;
- auto queryAttributes(state->queryAttributes.use()(rowId));
- while (queryAttributes.next())
- attrs.push_back(symbols.create(queryAttributes.getStr(0)));
- return {{rowId, attrs}};
- } else if (type == AttrType::String) {
- return {{rowId, queryAttribute.getStr(2)}};
- } else if (type == AttrType::Missing) {
- return {{rowId, missing_t()}};
- } else if (type == AttrType::Misc) {
- return {{rowId, misc_t()}};
- } else if (type == AttrType::Failed) {
- return {{rowId, failed_t()}};
- } else
- throw Error("unexpected type in evaluation cache");
+ switch (type) {
+ case AttrType::Placeholder:
+ return {{rowId, placeholder_t()}};
+ case AttrType::FullAttrs: {
+ // FIXME: expensive, should separate this out.
+ std::vector<Symbol> attrs;
+ auto queryAttributes(state->queryAttributes.use()(rowId));
+ while (queryAttributes.next())
+ attrs.push_back(symbols.create(queryAttributes.getStr(0)));
+ return {{rowId, attrs}};
+ }
+ case AttrType::String:
+ return {{rowId, queryAttribute.getStr(2)}};
+ case AttrType::Bool:
+ return {{rowId, queryAttribute.getInt(2) != 0}};
+ case AttrType::Missing:
+ return {{rowId, missing_t()}};
+ case AttrType::Misc:
+ return {{rowId, misc_t()}};
+ case AttrType::Failed:
+ return {{rowId, failed_t()}};
+ default:
+ throw Error("unexpected type in evaluation cache");
+ }
}
};
@@ -301,6 +321,8 @@ Value & AttrCursor::forceValue()
if (root->db && (!cachedValue || std::get_if<placeholder_t>(&cachedValue->second))) {
if (v.type == tString)
cachedValue = {root->db->setString(getKey(), v.string.s), v.string.s};
+ else if (v.type == tBool)
+ cachedValue = {root->db->setBool(getKey(), v.boolean), v.boolean};
else if (v.type == tAttrs)
; // FIXME: do something?
else
@@ -419,6 +441,28 @@ std::string AttrCursor::getString()
return v.string.s;
}
+bool AttrCursor::getBool()
+{
+ if (root->db) {
+ if (!cachedValue)
+ cachedValue = root->db->getAttr(getKey(), root->state.symbols);
+ if (cachedValue && !std::get_if<placeholder_t>(&cachedValue->second)) {
+ if (auto b = std::get_if<bool>(&cachedValue->second)) {
+ debug("using cached Boolean attribute '%s'", getAttrPathStr());
+ return *b;
+ } else
+ throw TypeError("'%s' is not a Boolean", getAttrPathStr());
+ }
+ }
+
+ auto & v = forceValue();
+
+ if (v.type != tBool)
+ throw TypeError("'%s' is not a Boolean", getAttrPathStr());
+
+ return v.boolean;
+}
+
std::vector<Symbol> AttrCursor::getAttrs()
{
if (root->db) {
diff --git a/src/libexpr/eval-cache.hh b/src/libexpr/eval-cache.hh
index a2c21b6ea..9c47da315 100644
--- a/src/libexpr/eval-cache.hh
+++ b/src/libexpr/eval-cache.hh
@@ -41,6 +41,7 @@ enum AttrType {
Missing = 3,
Misc = 4,
Failed = 5,
+ Bool = 6,
};
struct placeholder_t {};
@@ -49,7 +50,7 @@ struct misc_t {};
struct failed_t {};
typedef uint64_t AttrId;
typedef std::pair<AttrId, Symbol> AttrKey;
-typedef std::variant<std::vector<Symbol>, std::string, placeholder_t, missing_t, misc_t, failed_t> AttrValue;
+typedef std::variant<std::vector<Symbol>, std::string, placeholder_t, missing_t, misc_t, failed_t, bool> AttrValue;
class AttrCursor : public std::enable_shared_from_this<AttrCursor>
{
@@ -93,6 +94,8 @@ public:
std::string getString();
+ bool getBool();
+
std::vector<Symbol> getAttrs();
bool isDerivation();
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 95f52dc93..dd2c44c6d 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -352,6 +352,7 @@ EvalState::EvalState(const Strings & _searchPath, ref<Store> store)
, sDescription(symbols.create("description"))
, sSelf(symbols.create("self"))
, sEpsilon(symbols.create(""))
+ , sRecurseForDerivations(symbols.create("recurseForDerivations"))
, repair(NoRepair)
, store(store)
, baseEnv(allocEnv(128))
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 994954e44..9cf0030f9 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -75,7 +75,7 @@ public:
sFile, sLine, sColumn, sFunctor, sToString,
sRight, sWrong, sStructuredAttrs, sBuilder, sArgs,
sOutputHash, sOutputHashAlgo, sOutputHashMode,
- sDescription, sSelf, sEpsilon;
+ sDescription, sSelf, sEpsilon, sRecurseForDerivations;
Symbol sDerivationNix;
/* If set, force copying files to the Nix store even if they
diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc
index ca9c547fa..a4937e722 100644
--- a/src/libexpr/get-drvs.cc
+++ b/src/libexpr/get-drvs.cc
@@ -348,7 +348,7 @@ static void getDerivations(EvalState & state, Value & vIn,
should we recurse into it? => Only if it has a
`recurseForDerivations = true' attribute. */
if (i->value->type == tAttrs) {
- Bindings::iterator j = i->value->attrs->find(state.symbols.create("recurseForDerivations"));
+ Bindings::iterator j = i->value->attrs->find(state.sRecurseForDerivations);
if (j != i->value->attrs->end() && state.forceBool(*j->value, *j->pos))
getDerivations(state, *i->value, pathPrefix2, autoArgs, drvs, done, ignoreAssertionFailures);
}
diff --git a/src/nix/search.cc b/src/nix/search.cc
index 586bff5e5..fca49350a 100644
--- a/src/nix/search.cc
+++ b/src/nix/search.cc
@@ -165,6 +165,12 @@ struct CmdSearch : InstallableCommand, MixJSON
|| (attrPath[0] == "packages" && attrPath.size() <= 2))
recurse();
+ else if (attrPath[0] == "legacyPackages" && attrPath.size() > 2) {
+ auto attr = cursor.maybeGetAttr(state->sRecurseForDerivations);
+ if (attr && attr->getBool())
+ recurse();
+ }
+
} catch (EvalError & e) {
if (!(attrPath.size() > 0 && attrPath[0] == "legacyPackages"))
throw;