Merge pull request #11766 from NixOS/refactor-import

Refactor `import`
This commit is contained in:
Robert Hensing 2024-10-30 04:19:08 +01:00 committed by GitHub
commit 12e31ab77d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -178,34 +178,27 @@ static void mkOutputString(
o.second.path(*state.store, Derivation::nameFromPath(drvPath), o.first)); o.second.path(*state.store, Derivation::nameFromPath(drvPath), o.first));
} }
/* Load and evaluate an expression from path specified by the /**
argument. */ * `import` will parse a derivation when it imports a `.drv` file from the store.
static void import(EvalState & state, const PosIdx pos, Value & vPath, Value * vScope, Value & v) *
{ * @param state The evaluation state.
auto path = realisePath(state, pos, vPath, std::nullopt); * @param pos The position of the `import` call.
* @param path The path to the `.drv` to import.
* @param storePath The path to the `.drv` to import.
* @param v Return value
*/
void derivationToValue(EvalState & state, const PosIdx pos, const SourcePath & path, const StorePath & storePath, Value & v) {
auto path2 = path.path.abs(); auto path2 = path.path.abs();
Derivation drv = state.store->readDerivation(storePath);
// FIXME
auto isValidDerivationInStore = [&]() -> std::optional<StorePath> {
if (!state.store->isStorePath(path2))
return std::nullopt;
auto storePath = state.store->parseStorePath(path2);
if (!(state.store->isValidPath(storePath) && isDerivation(path2)))
return std::nullopt;
return storePath;
};
if (auto storePath = isValidDerivationInStore()) {
Derivation drv = state.store->readDerivation(*storePath);
auto attrs = state.buildBindings(3 + drv.outputs.size()); auto attrs = state.buildBindings(3 + drv.outputs.size());
attrs.alloc(state.sDrvPath).mkString(path2, { attrs.alloc(state.sDrvPath).mkString(path2, {
NixStringContextElem::DrvDeep { .drvPath = *storePath }, NixStringContextElem::DrvDeep { .drvPath = storePath },
}); });
attrs.alloc(state.sName).mkString(drv.env["name"]); attrs.alloc(state.sName).mkString(drv.env["name"]);
auto list = state.buildList(drv.outputs.size()); auto list = state.buildList(drv.outputs.size());
for (const auto & [i, o] : enumerate(drv.outputs)) { for (const auto & [i, o] : enumerate(drv.outputs)) {
mkOutputString(state, attrs, *storePath, o); mkOutputString(state, attrs, storePath, o);
(list[i] = state.allocValue())->mkString(o.first); (list[i] = state.allocValue())->mkString(o.first);
} }
attrs.alloc(state.sOutputs).mkList(list); attrs.alloc(state.sOutputs).mkList(list);
@ -223,12 +216,18 @@ static void import(EvalState & state, const PosIdx pos, Value & vPath, Value * v
state.forceFunction(**state.vImportedDrvToDerivation, pos, "while evaluating imported-drv-to-derivation.nix.gen.hh"); state.forceFunction(**state.vImportedDrvToDerivation, pos, "while evaluating imported-drv-to-derivation.nix.gen.hh");
v.mkApp(*state.vImportedDrvToDerivation, w); v.mkApp(*state.vImportedDrvToDerivation, w);
state.forceAttrs(v, pos, "while calling imported-drv-to-derivation.nix.gen.hh"); state.forceAttrs(v, pos, "while calling imported-drv-to-derivation.nix.gen.hh");
} }
else { /**
if (!vScope) * Import a Nix file with an alternate base scope, as `builtins.scopedImport` does.
state.evalFile(path, v); *
else { * @param state The evaluation state.
* @param pos The position of the import call.
* @param path The path to the file to import.
* @param vScope The base scope to use for the import.
* @param v Return value
*/
static void scopedImport(EvalState & state, const PosIdx pos, SourcePath & path, Value * vScope, Value & v) {
state.forceAttrs(*vScope, pos, "while evaluating the first argument passed to builtins.scopedImport"); state.forceAttrs(*vScope, pos, "while evaluating the first argument passed to builtins.scopedImport");
Env * env = &state.allocEnv(vScope->attrs()->size()); Env * env = &state.allocEnv(vScope->attrs()->size());
@ -249,7 +248,33 @@ static void import(EvalState & state, const PosIdx pos, Value & vPath, Value * v
Expr * e = state.parseExprFromFile(resolveExprPath(path), staticEnv); Expr * e = state.parseExprFromFile(resolveExprPath(path), staticEnv);
e->eval(state, *env, v); e->eval(state, *env, v);
}
/* Load and evaluate an expression from path specified by the
argument. */
static void import(EvalState & state, const PosIdx pos, Value & vPath, Value * vScope, Value & v)
{
auto path = realisePath(state, pos, vPath, std::nullopt);
auto path2 = path.path.abs();
// FIXME
auto isValidDerivationInStore = [&]() -> std::optional<StorePath> {
if (!state.store->isStorePath(path2))
return std::nullopt;
auto storePath = state.store->parseStorePath(path2);
if (!(state.store->isValidPath(storePath) && isDerivation(path2)))
return std::nullopt;
return storePath;
};
if (auto storePath = isValidDerivationInStore()) {
derivationToValue(state, pos, path, *storePath, v);
} }
else if (vScope) {
scopedImport(state, pos, path, vScope, v);
}
else {
state.evalFile(path, v);
} }
} }