forked from lix-project/lix
Merge pull request #5347 from edolstra/allow-context
Make addPath() work on paths with a context
This commit is contained in:
commit
7b5fc4a984
|
@ -56,13 +56,9 @@ void EvalState::realiseContext(const PathSet & context)
|
||||||
"cannot build '%1%' during evaluation because the option 'allow-import-from-derivation' is disabled",
|
"cannot build '%1%' during evaluation because the option 'allow-import-from-derivation' is disabled",
|
||||||
store->printStorePath(drvs.begin()->drvPath));
|
store->printStorePath(drvs.begin()->drvPath));
|
||||||
|
|
||||||
/* For performance, prefetch all substitute info. */
|
/* Build/substitute the context. */
|
||||||
StorePathSet willBuild, willSubstitute, unknown;
|
|
||||||
uint64_t downloadSize, narSize;
|
|
||||||
std::vector<DerivedPath> buildReqs;
|
std::vector<DerivedPath> buildReqs;
|
||||||
for (auto & d : drvs) buildReqs.emplace_back(DerivedPath { d });
|
for (auto & d : drvs) buildReqs.emplace_back(DerivedPath { d });
|
||||||
store->queryMissing(buildReqs, willBuild, willSubstitute, unknown, downloadSize, narSize);
|
|
||||||
|
|
||||||
store->buildPaths(buildReqs);
|
store->buildPaths(buildReqs);
|
||||||
|
|
||||||
/* Add the output of this derivations to the allowed
|
/* Add the output of this derivations to the allowed
|
||||||
|
@ -1847,12 +1843,34 @@ static RegisterPrimOp primop_toFile({
|
||||||
.fun = prim_toFile,
|
.fun = prim_toFile,
|
||||||
});
|
});
|
||||||
|
|
||||||
static void addPath(EvalState & state, const Pos & pos, const string & name, const Path & path_,
|
static void addPath(
|
||||||
Value * filterFun, FileIngestionMethod method, const std::optional<Hash> expectedHash, Value & v)
|
EvalState & state,
|
||||||
|
const Pos & pos,
|
||||||
|
const string & name,
|
||||||
|
Path path,
|
||||||
|
Value * filterFun,
|
||||||
|
FileIngestionMethod method,
|
||||||
|
const std::optional<Hash> expectedHash,
|
||||||
|
Value & v,
|
||||||
|
const PathSet & context)
|
||||||
{
|
{
|
||||||
const auto path = evalSettings.pureEval && expectedHash ?
|
try {
|
||||||
path_ :
|
// FIXME: handle CA derivation outputs (where path needs to
|
||||||
state.checkSourcePath(path_);
|
// be rewritten to the actual output).
|
||||||
|
state.realiseContext(context);
|
||||||
|
|
||||||
|
path = evalSettings.pureEval && expectedHash
|
||||||
|
? path
|
||||||
|
: state.checkSourcePath(path);
|
||||||
|
|
||||||
|
if (state.store->isInStore(path)) {
|
||||||
|
auto storePath = state.store->toStorePath(path).first;
|
||||||
|
auto info = state.store->queryPathInfo(storePath);
|
||||||
|
if (!info->references.empty())
|
||||||
|
throw EvalError("store path '%s' is not allowed to have references",
|
||||||
|
state.store->printStorePath(storePath));
|
||||||
|
}
|
||||||
|
|
||||||
PathFilter filter = filterFun ? ([&](const Path & path) {
|
PathFilter filter = filterFun ? ([&](const Path & path) {
|
||||||
auto st = lstat(path);
|
auto st = lstat(path);
|
||||||
|
|
||||||
|
@ -1880,6 +1898,7 @@ static void addPath(EvalState & state, const Pos & pos, const string & name, con
|
||||||
std::optional<StorePath> expectedStorePath;
|
std::optional<StorePath> expectedStorePath;
|
||||||
if (expectedHash)
|
if (expectedHash)
|
||||||
expectedStorePath = state.store->makeFixedOutputPath(method, *expectedHash, name);
|
expectedStorePath = state.store->makeFixedOutputPath(method, *expectedHash, name);
|
||||||
|
|
||||||
Path dstPath;
|
Path dstPath;
|
||||||
if (!expectedHash || !state.store->isValidPath(*expectedStorePath)) {
|
if (!expectedHash || !state.store->isValidPath(*expectedStorePath)) {
|
||||||
dstPath = state.store->printStorePath(settings.readOnlyMode
|
dstPath = state.store->printStorePath(settings.readOnlyMode
|
||||||
|
@ -1893,6 +1912,11 @@ static void addPath(EvalState & state, const Pos & pos, const string & name, con
|
||||||
mkString(v, dstPath, {dstPath});
|
mkString(v, dstPath, {dstPath});
|
||||||
|
|
||||||
state.allowPath(v.string.s);
|
state.allowPath(v.string.s);
|
||||||
|
|
||||||
|
} catch (Error & e) {
|
||||||
|
e.addTrace(pos, "while adding path '%s'", path);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1900,11 +1924,6 @@ static void prim_filterSource(EvalState & state, const Pos & pos, Value * * args
|
||||||
{
|
{
|
||||||
PathSet context;
|
PathSet context;
|
||||||
Path path = state.coerceToPath(pos, *args[1], context);
|
Path path = state.coerceToPath(pos, *args[1], context);
|
||||||
if (!context.empty())
|
|
||||||
throw EvalError({
|
|
||||||
.msg = hintfmt("string '%1%' cannot refer to other paths", path),
|
|
||||||
.errPos = pos
|
|
||||||
});
|
|
||||||
|
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
if (args[0]->type() != nFunction)
|
if (args[0]->type() != nFunction)
|
||||||
|
@ -1915,7 +1934,7 @@ static void prim_filterSource(EvalState & state, const Pos & pos, Value * * args
|
||||||
.errPos = pos
|
.errPos = pos
|
||||||
});
|
});
|
||||||
|
|
||||||
addPath(state, pos, std::string(baseNameOf(path)), path, args[0], FileIngestionMethod::Recursive, std::nullopt, v);
|
addPath(state, pos, std::string(baseNameOf(path)), path, args[0], FileIngestionMethod::Recursive, std::nullopt, v, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPrimOp primop_filterSource({
|
static RegisterPrimOp primop_filterSource({
|
||||||
|
@ -1981,18 +2000,13 @@ static void prim_path(EvalState & state, const Pos & pos, Value * * args, Value
|
||||||
Value * filterFun = nullptr;
|
Value * filterFun = nullptr;
|
||||||
auto method = FileIngestionMethod::Recursive;
|
auto method = FileIngestionMethod::Recursive;
|
||||||
std::optional<Hash> expectedHash;
|
std::optional<Hash> expectedHash;
|
||||||
|
PathSet context;
|
||||||
|
|
||||||
for (auto & attr : *args[0]->attrs) {
|
for (auto & attr : *args[0]->attrs) {
|
||||||
const string & n(attr.name);
|
const string & n(attr.name);
|
||||||
if (n == "path") {
|
if (n == "path")
|
||||||
PathSet context;
|
|
||||||
path = state.coerceToPath(*attr.pos, *attr.value, context);
|
path = state.coerceToPath(*attr.pos, *attr.value, context);
|
||||||
if (!context.empty())
|
else if (attr.name == state.sName)
|
||||||
throw EvalError({
|
|
||||||
.msg = hintfmt("string '%1%' cannot refer to other paths", path),
|
|
||||||
.errPos = *attr.pos
|
|
||||||
});
|
|
||||||
} else if (attr.name == state.sName)
|
|
||||||
name = state.forceStringNoCtx(*attr.value, *attr.pos);
|
name = state.forceStringNoCtx(*attr.value, *attr.pos);
|
||||||
else if (n == "filter") {
|
else if (n == "filter") {
|
||||||
state.forceValue(*attr.value, pos);
|
state.forceValue(*attr.value, pos);
|
||||||
|
@ -2015,7 +2029,7 @@ static void prim_path(EvalState & state, const Pos & pos, Value * * args, Value
|
||||||
if (name.empty())
|
if (name.empty())
|
||||||
name = baseNameOf(path);
|
name = baseNameOf(path);
|
||||||
|
|
||||||
addPath(state, pos, name, path, filterFun, method, expectedHash, v);
|
addPath(state, pos, name, path, filterFun, method, expectedHash, v, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPrimOp primop_path({
|
static RegisterPrimOp primop_path({
|
||||||
|
|
|
@ -239,7 +239,7 @@ void Worker::run(const Goals & _topGoals)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call queryMissing() efficiently query substitutes. */
|
/* Call queryMissing() to efficiently query substitutes. */
|
||||||
StorePathSet willBuild, willSubstitute, unknown;
|
StorePathSet willBuild, willSubstitute, unknown;
|
||||||
uint64_t downloadSize, narSize;
|
uint64_t downloadSize, narSize;
|
||||||
store.queryMissing(topPaths, willBuild, willSubstitute, unknown, downloadSize, narSize);
|
store.queryMissing(topPaths, willBuild, willSubstitute, unknown, downloadSize, narSize);
|
||||||
|
|
|
@ -262,6 +262,7 @@ cat > $flake3Dir/flake.nix <<EOF
|
||||||
inherit system;
|
inherit system;
|
||||||
name = "fnord";
|
name = "fnord";
|
||||||
dummy = builtins.readFile (builtins.path { name = "source"; path = ./.; filter = path: type: baseNameOf path == "config.nix"; } + "/config.nix");
|
dummy = builtins.readFile (builtins.path { name = "source"; path = ./.; filter = path: type: baseNameOf path == "config.nix"; } + "/config.nix");
|
||||||
|
dummy2 = builtins.readFile (builtins.path { name = "source"; path = inputs.flake1; filter = path: type: baseNameOf path == "simple.nix"; } + "/simple.nix");
|
||||||
buildCommand = ''
|
buildCommand = ''
|
||||||
cat \${inputs.nonFlake}/README.md > \$out
|
cat \${inputs.nonFlake}/README.md > \$out
|
||||||
'';
|
'';
|
||||||
|
|
Loading…
Reference in a new issue