forked from lix-project/lix
nix search: Search legacyPackages recursively
This commit is contained in:
parent
0469795978
commit
b4e23dcd9e
|
@ -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,26 +185,31 @@ struct AttrDb
|
|||
auto rowId = (AttrType) queryAttribute.getInt(0);
|
||||
auto type = (AttrType) queryAttribute.getInt(1);
|
||||
|
||||
if (type == AttrType::Placeholder)
|
||||
switch (type) {
|
||||
case AttrType::Placeholder:
|
||||
return {{rowId, placeholder_t()}};
|
||||
else if (type == AttrType::FullAttrs) {
|
||||
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}};
|
||||
} else if (type == AttrType::String) {
|
||||
}
|
||||
case AttrType::String:
|
||||
return {{rowId, queryAttribute.getStr(2)}};
|
||||
} else if (type == AttrType::Missing) {
|
||||
case AttrType::Bool:
|
||||
return {{rowId, queryAttribute.getInt(2) != 0}};
|
||||
case AttrType::Missing:
|
||||
return {{rowId, missing_t()}};
|
||||
} else if (type == AttrType::Misc) {
|
||||
case AttrType::Misc:
|
||||
return {{rowId, misc_t()}};
|
||||
} else if (type == AttrType::Failed) {
|
||||
case AttrType::Failed:
|
||||
return {{rowId, failed_t()}};
|
||||
} else
|
||||
default:
|
||||
throw Error("unexpected type in evaluation cache");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
EvalCache::EvalCache(
|
||||
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue