Check meta values and warn about bad ones

This commit is contained in:
Eelco Dolstra 2013-11-19 14:29:39 +01:00
parent 0f24400d90
commit 30b986908e
4 changed files with 54 additions and 26 deletions

View file

@ -91,12 +91,30 @@ StringSet DrvInfo::queryMetaNames()
} }
bool DrvInfo::checkMeta(Value & v)
{
state->forceValue(v);
if (v.type == tList) {
for (unsigned int n = 0; n < v.list.length; ++n)
if (!checkMeta(*v.list.elems[n])) return false;
return true;
}
else if (v.type == tAttrs) {
Bindings::iterator i = v.attrs->find(state->sOutPath);
if (i != v.attrs->end()) return false;
foreach (Bindings::iterator, i, *v.attrs)
if (!checkMeta(*i->value)) return false;
return true;
}
else return v.type == tInt || v.type == tBool || v.type == tString;
}
Value * DrvInfo::queryMeta(const string & name) Value * DrvInfo::queryMeta(const string & name)
{ {
if (!getMeta()) return 0; if (!getMeta()) return 0;
Bindings::iterator a = meta->find(state->symbols.create(name)); Bindings::iterator a = meta->find(state->symbols.create(name));
if (a == meta->end()) return 0; if (a == meta->end() || !checkMeta(*a->value)) return 0;
state->forceValue(*a->value);
return a->value; return a->value;
} }

View file

@ -30,6 +30,8 @@ private:
Bindings * getMeta(); Bindings * getMeta();
bool checkMeta(Value & v);
public: public:
string name; string name;
string attrPath; /* path towards the derivation */ string attrPath; /* path towards the derivation */

View file

@ -873,11 +873,15 @@ static void queryJSON(Globals & globals, vector<DrvInfo> & elems)
foreach (StringSet::iterator, j, metaNames) { foreach (StringSet::iterator, j, metaNames) {
metaObj.attr(*j); metaObj.attr(*j);
Value * v = i->queryMeta(*j); Value * v = i->queryMeta(*j);
if (!v)
printMsg(lvlError, format("derivation `%1%' has invalid meta attribute `%2%'") % i->name % *j);
else {
PathSet context; PathSet context;
printValueAsJSON(globals.state, true, *v, cout, context); printValueAsJSON(globals.state, true, *v, cout, context);
} }
} }
} }
}
static void opQuery(Globals & globals, static void opQuery(Globals & globals,
@ -1112,31 +1116,35 @@ static void opQuery(Globals & globals,
foreach (StringSet::iterator, j, metaNames) { foreach (StringSet::iterator, j, metaNames) {
XMLAttrs attrs2; XMLAttrs attrs2;
attrs2["name"] = *j; attrs2["name"] = *j;
Value & v(*i->queryMeta(*j)); Value * v = i->queryMeta(*j);
if (v.type == tString) { if (!v)
printMsg(lvlError, format("derivation `%1%' has invalid meta attribute `%2%'") % i->name % *j);
else {
if (v->type == tString) {
attrs2["type"] = "string"; attrs2["type"] = "string";
attrs2["value"] = v.string.s; attrs2["value"] = v->string.s;
xml.writeEmptyElement("meta", attrs2); xml.writeEmptyElement("meta", attrs2);
} else if (v.type == tInt) { } else if (v->type == tInt) {
attrs2["type"] = "int"; attrs2["type"] = "int";
attrs2["value"] = (format("%1%") % v.integer).str(); attrs2["value"] = (format("%1%") % v->integer).str();
xml.writeEmptyElement("meta", attrs2); xml.writeEmptyElement("meta", attrs2);
} else if (v.type == tBool) { } else if (v->type == tBool) {
attrs2["type"] = "bool"; attrs2["type"] = "bool";
attrs2["value"] = v.boolean ? "true" : "false"; attrs2["value"] = v->boolean ? "true" : "false";
xml.writeEmptyElement("meta", attrs2); xml.writeEmptyElement("meta", attrs2);
} else if (v.type == tList) { } else if (v->type == tList) {
attrs2["type"] = "strings"; attrs2["type"] = "strings";
XMLOpenElement m(xml, "meta", attrs2); XMLOpenElement m(xml, "meta", attrs2);
for (unsigned int j = 0; j < v.list.length; ++j) { for (unsigned int j = 0; j < v->list.length; ++j) {
string s = globals.state.forceStringNoCtx(*v.list.elems[j]); if (v->list.elems[j]->type != tString) continue;
XMLAttrs attrs3; XMLAttrs attrs3;
attrs3["value"] = s; attrs3["value"] = v->list.elems[j]->string.s;
xml.writeEmptyElement("string", attrs3); xml.writeEmptyElement("string", attrs3);
} }
} }
} }
} }
}
} else } else
xml.writeEmptyElement("item", attrs); xml.writeEmptyElement("item", attrs);
} else } else

View file

@ -88,7 +88,7 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
StringSet metaNames = i->queryMetaNames(); StringSet metaNames = i->queryMetaNames();
foreach (StringSet::iterator, j, metaNames) { foreach (StringSet::iterator, j, metaNames) {
Value * v = i->queryMeta(*j); Value * v = i->queryMeta(*j);
state.strictForceValue(*v); // FIXME if (!v) continue;
vMeta.attrs->push_back(Attr(state.symbols.create(*j), v)); vMeta.attrs->push_back(Attr(state.symbols.create(*j), v));
} }
v.attrs->sort(); v.attrs->sort();