forked from lix-project/lix
Share code between scopedImport and import
In addition to reducing duplication, this fixes both import from derivation and import of derivation for scopedImport
This commit is contained in:
parent
61c464f252
commit
a8fb575c98
|
@ -39,31 +39,34 @@ std::pair<string, string> decodeContext(const string & s)
|
||||||
|
|
||||||
/* Load and evaluate an expression from path specified by the
|
/* Load and evaluate an expression from path specified by the
|
||||||
argument. */
|
argument. */
|
||||||
static void prim_import(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
Path path = state.coerceToPath(pos, *args[0], context);
|
Path path = state.coerceToPath(pos, *args[1], context);
|
||||||
|
|
||||||
foreach (PathSet::iterator, i, context) {
|
PathSet drvs;
|
||||||
Path ctx = decodeContext(*i).first;
|
for (auto & i : context) {
|
||||||
|
std::pair<string, string> decoded = decodeContext(i);
|
||||||
|
Path ctx = decoded.first;
|
||||||
assert(isStorePath(ctx));
|
assert(isStorePath(ctx));
|
||||||
if (!store->isValidPath(ctx))
|
if (!store->isValidPath(ctx))
|
||||||
throw EvalError(format("cannot import `%1%', since path `%2%' is not valid, at %3%")
|
throw EvalError(format("cannot import `%1%', since path `%2%' is not valid, at %3%")
|
||||||
% path % ctx % pos);
|
% path % ctx % pos);
|
||||||
if (isDerivation(ctx))
|
if (isDerivation(ctx))
|
||||||
try {
|
drvs.insert(decoded.first + "!" + decoded.second);
|
||||||
/* For performance, prefetch all substitute info. */
|
}
|
||||||
PathSet willBuild, willSubstitute, unknown;
|
if (!drvs.empty()) {
|
||||||
unsigned long long downloadSize, narSize;
|
try {
|
||||||
queryMissing(*store, singleton<PathSet>(ctx),
|
/* For performance, prefetch all substitute info. */
|
||||||
willBuild, willSubstitute, unknown, downloadSize, narSize);
|
PathSet willBuild, willSubstitute, unknown;
|
||||||
|
unsigned long long downloadSize, narSize;
|
||||||
|
queryMissing(*store, drvs,
|
||||||
|
willBuild, willSubstitute, unknown, downloadSize, narSize);
|
||||||
|
|
||||||
/* !!! If using a substitute, we only need to fetch
|
store->buildPaths(drvs);
|
||||||
the selected output of this derivation. */
|
} catch (Error & e) {
|
||||||
store->buildPaths(singleton<PathSet>(ctx));
|
throw ImportError(e.msg());
|
||||||
} catch (Error & e) {
|
}
|
||||||
throw ImportError(e.msg());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isStorePath(path) && store->isValidPath(path) && isDerivation(path)) {
|
if (isStorePath(path) && store->isValidPath(path) && isDerivation(path)) {
|
||||||
|
@ -88,35 +91,30 @@ static void prim_import(EvalState & state, const Pos & pos, Value * * args, Valu
|
||||||
mkApp(v, fun, w);
|
mkApp(v, fun, w);
|
||||||
state.forceAttrs(v, pos);
|
state.forceAttrs(v, pos);
|
||||||
} else {
|
} else {
|
||||||
state.evalFile(path, v);
|
state.forceAttrs(*args[0]);
|
||||||
|
if (args[0]->attrs->empty())
|
||||||
|
state.evalFile(path, v);
|
||||||
|
else {
|
||||||
|
Env * env = &state.allocEnv(args[0]->attrs->size());
|
||||||
|
env->up = &state.baseEnv;
|
||||||
|
|
||||||
|
StaticEnv staticEnv(false, &state.staticBaseEnv);
|
||||||
|
|
||||||
|
unsigned int displ = 0;
|
||||||
|
for (auto & attr : *args[0]->attrs) {
|
||||||
|
staticEnv.vars[attr.name] = displ;
|
||||||
|
env->values[displ++] = attr.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
startNest(nest, lvlTalkative, format("evaluating file `%1%'") % path);
|
||||||
|
Expr * e = state.parseExprFromFile(resolveExprPath(path), staticEnv);
|
||||||
|
|
||||||
|
e->eval(state, *env, v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
|
||||||
{
|
|
||||||
PathSet context;
|
|
||||||
state.forceAttrs(*args[0]);
|
|
||||||
Path path = resolveExprPath(state.coerceToPath(pos, *args[1], context));
|
|
||||||
|
|
||||||
Env * env = &state.allocEnv(args[0]->attrs->size());
|
|
||||||
env->up = &state.baseEnv;
|
|
||||||
|
|
||||||
StaticEnv staticEnv(false, &state.staticBaseEnv);
|
|
||||||
|
|
||||||
unsigned int displ = 0;
|
|
||||||
for (auto & attr : *args[0]->attrs) {
|
|
||||||
staticEnv.vars[attr.name] = displ;
|
|
||||||
env->values[displ++] = attr.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
startNest(nest, lvlTalkative, format("evaluating file `%1%'") % path);
|
|
||||||
Expr * e = state.parseExprFromFile(path, staticEnv);
|
|
||||||
|
|
||||||
e->eval(state, *env, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Return a string representing the type of the expression. */
|
/* Return a string representing the type of the expression. */
|
||||||
static void prim_typeOf(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
static void prim_typeOf(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
@ -1301,8 +1299,12 @@ void EvalState::createBaseEnv()
|
||||||
addConstant("__langVersion", v);
|
addConstant("__langVersion", v);
|
||||||
|
|
||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
addPrimOp("import", 1, prim_import);
|
|
||||||
addPrimOp("scopedImport", 2, prim_scopedImport);
|
addPrimOp("scopedImport", 2, prim_scopedImport);
|
||||||
|
Value * v2 = allocValue();
|
||||||
|
mkAttrs(*v2, 0);
|
||||||
|
mkApp(v, *baseEnv.values[baseEnvDispl - 1], *v2);
|
||||||
|
forceValue(v);
|
||||||
|
addConstant("import", v);
|
||||||
addPrimOp("__typeOf", 1, prim_typeOf);
|
addPrimOp("__typeOf", 1, prim_typeOf);
|
||||||
addPrimOp("isNull", 1, prim_isNull);
|
addPrimOp("isNull", 1, prim_isNull);
|
||||||
addPrimOp("__isFunction", 1, prim_isFunction);
|
addPrimOp("__isFunction", 1, prim_isFunction);
|
||||||
|
@ -1388,7 +1390,7 @@ void EvalState::createBaseEnv()
|
||||||
mkList(v, searchPath.size());
|
mkList(v, searchPath.size());
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for (auto & i : searchPath) {
|
for (auto & i : searchPath) {
|
||||||
Value * v2 = v.list.elems[n++] = allocValue();
|
v2 = v.list.elems[n++] = allocValue();
|
||||||
mkAttrs(*v2, 2);
|
mkAttrs(*v2, 2);
|
||||||
mkString(*allocAttr(*v2, symbols.create("path")), i.second);
|
mkString(*allocAttr(*v2, symbols.create("path")), i.second);
|
||||||
mkString(*allocAttr(*v2, symbols.create("prefix")), i.first);
|
mkString(*allocAttr(*v2, symbols.create("prefix")), i.first);
|
||||||
|
|
Loading…
Reference in a new issue