Support locking path inputs

This commit is contained in:
Eelco Dolstra 2022-08-16 16:05:43 +02:00
parent 4adb32f7d5
commit a218dd80d6
4 changed files with 43 additions and 21 deletions

View file

@ -134,11 +134,6 @@ std::pair<StorePath, Input> Input::fetchToStore(ref<Store> store) const
void Input::checkLocks(Input & input) const
{
#if 0
auto narHash = store.queryPathInfo(storePath)->narHash;
input.attrs.insert_or_assign("narHash", narHash.to_string(SRI, true));
#endif
if (auto prevNarHash = getNarHash()) {
if (input.getNarHash() != prevNarHash)
throw Error((unsigned int) 102, "NAR hash mismatch in input '%s', expected '%s'",

View file

@ -27,6 +27,8 @@ struct PathInputScheme : InputScheme
else
throw Error("path URL '%s' has invalid parameter '%s'", url.to_string(), name);
}
else if (name == "lock")
input.attrs.emplace(name, Explicit<bool> { value == "1" });
else
throw Error("path URL '%s' has unsupported parameter '%s'", url.to_string(), name);
@ -38,6 +40,7 @@ struct PathInputScheme : InputScheme
if (maybeGetStrAttr(attrs, "type") != "path") return {};
getStrAttr(attrs, "path");
maybeGetBoolAttr(attrs, "lock");
for (auto & [name, value] : attrs)
/* Allow the user to pass in "fake" tree info
@ -47,8 +50,8 @@ struct PathInputScheme : InputScheme
FIXME: remove this hack once we have a prepopulated
flake input cache mechanism.
*/
if (name == "type" || name == "rev" || name == "revCount" || name == "lastModified" || name == "narHash" || name == "path")
// checked in Input::fromAttrs
if (name == "type" || name == "rev" || name == "revCount" || name == "lastModified" || name == "narHash" || name == "path" || name == "lock")
// checked elsewhere
;
else
throw Error("unsupported path input attribute '%s'", name);
@ -58,6 +61,11 @@ struct PathInputScheme : InputScheme
return input;
}
bool getLockAttr(const Input & input) const
{
return maybeGetBoolAttr(input.attrs, "lock").value_or(false);
}
ParsedURL toURL(const Input & input) const override
{
auto query = attrsToQuery(input.attrs);
@ -112,7 +120,31 @@ struct PathInputScheme : InputScheme
auto absPath = getAbsPath(input);
auto input2(input);
input2.attrs.emplace("path", (std::string) absPath.abs());
return {makeFSInputAccessor(absPath), std::move(input2)};
if (getLockAttr(input2)) {
auto storePath = store->maybeParseStorePath(absPath.abs());
if (!storePath || storePath->name() != input.getName() || !store->isValidPath(*storePath)) {
Activity act(*logger, lvlChatty, actUnknown, fmt("copying '%s' to the store", absPath));
storePath = store->addToStore(input.getName(), absPath.abs());
auto narHash = store->queryPathInfo(*storePath)->narHash;
input2.attrs.insert_or_assign("narHash", narHash.to_string(SRI, true));
} else
input2.attrs.erase("narHash");
input2.attrs.erase("lastModified");
auto makeNotAllowedError = [absPath](const CanonPath & path) -> RestrictedPathError
{
return RestrictedPathError("path '%s' does not exist'", absPath + path);
};
return {makeStorePathAccessor(store, *storePath, std::move(makeNotAllowedError)), std::move(input2)};
} else {
return {makeFSInputAccessor(absPath), std::move(input2)};
}
}
std::optional<std::string> getFingerprint(ref<Store> store, const Input & input) const override

View file

@ -221,11 +221,10 @@ cat > $flake3Dir/flake.nix <<EOF
url = git+file://$nonFlakeDir;
flake = false;
};
# FIXME: we can't lock path:// inputs at the moment.
#nonFlakeFile = {
# url = path://$nonFlakeDir/README.md;
# flake = false;
#};
nonFlakeFile = {
url = path://$nonFlakeDir/README.md?lock=1;
flake = false;
};
#nonFlakeFile2 = {
# url = "$nonFlakeDir/README.md";
# flake = false;
@ -246,8 +245,8 @@ cat > $flake3Dir/flake.nix <<EOF
dummy2 = builtins.readFile (builtins.path { name = "source"; path = inputs.flake1; filter = path: type: baseNameOf path == "simple.nix"; } + "/simple.nix");
buildCommand = ''
cat \${inputs.nonFlake}/README.md > \$out
[[ \$(cat \${inputs.nonFlake}/README.md) = \$(cat \${inputs.nonFlakeFile}) ]]
'';
# [[ \$(cat \${inputs.nonFlake}/README.md) = \$(cat \${inputs.nonFlakeFile}) ]]
# [[ \${inputs.nonFlakeFile} = \${inputs.nonFlakeFile2} ]]
};
};

View file

@ -27,9 +27,7 @@ cat > $flakeFollowsA/flake.nix <<EOF
inputs.foobar.follows = "foobar";
};
# FIXME: currently absolute path: flakes cannot be locked.
#foobar.url = "path:$flakeFollowsA/flakeE";
foobar.url = "git+file://$flake1Dir";
foobar.url = "path:$flakeFollowsA/flakeE?lock=1";
};
outputs = { ... }: {};
}
@ -39,8 +37,7 @@ cat > $flakeFollowsB/flake.nix <<EOF
{
description = "Flake B";
inputs = {
#foobar.url = "path:$flakeFollowsA/flakeE";
foobar.url = "git+file://$flake1Dir";
foobar.url = "path:$flakeFollowsA/flakeE?lock=1";
goodoo.follows = "C/goodoo";
C = {
url = "path:./flakeC";
@ -55,8 +52,7 @@ cat > $flakeFollowsC/flake.nix <<EOF
{
description = "Flake C";
inputs = {
#foobar.url = "path:$flakeFollowsA/flakeE";
foobar.url = "git+file://$flake1Dir";
foobar.url = "path:$flakeFollowsA/flakeE?lock=1";
goodoo.follows = "foobar";
};
outputs = { ... }: {};