1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-30 07:33:16 +02:00

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 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 (auto prevNarHash = getNarHash()) {
if (input.getNarHash() != prevNarHash) if (input.getNarHash() != prevNarHash)
throw Error((unsigned int) 102, "NAR hash mismatch in input '%s', expected '%s'", throw Error((unsigned int) 102, "NAR hash mismatch in input '%s', expected '%s'",

View file

@ -27,6 +27,8 @@ struct PathInputScheme : InputScheme
else else
throw Error("path URL '%s' has invalid parameter '%s'", url.to_string(), name); 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 else
throw Error("path URL '%s' has unsupported parameter '%s'", url.to_string(), name); 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 {}; if (maybeGetStrAttr(attrs, "type") != "path") return {};
getStrAttr(attrs, "path"); getStrAttr(attrs, "path");
maybeGetBoolAttr(attrs, "lock");
for (auto & [name, value] : attrs) for (auto & [name, value] : attrs)
/* Allow the user to pass in "fake" tree info /* 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 FIXME: remove this hack once we have a prepopulated
flake input cache mechanism. flake input cache mechanism.
*/ */
if (name == "type" || name == "rev" || name == "revCount" || name == "lastModified" || name == "narHash" || name == "path") if (name == "type" || name == "rev" || name == "revCount" || name == "lastModified" || name == "narHash" || name == "path" || name == "lock")
// checked in Input::fromAttrs // checked elsewhere
; ;
else else
throw Error("unsupported path input attribute '%s'", name); throw Error("unsupported path input attribute '%s'", name);
@ -58,6 +61,11 @@ struct PathInputScheme : InputScheme
return input; return input;
} }
bool getLockAttr(const Input & input) const
{
return maybeGetBoolAttr(input.attrs, "lock").value_or(false);
}
ParsedURL toURL(const Input & input) const override ParsedURL toURL(const Input & input) const override
{ {
auto query = attrsToQuery(input.attrs); auto query = attrsToQuery(input.attrs);
@ -112,8 +120,32 @@ struct PathInputScheme : InputScheme
auto absPath = getAbsPath(input); auto absPath = getAbsPath(input);
auto input2(input); auto input2(input);
input2.attrs.emplace("path", (std::string) absPath.abs()); input2.attrs.emplace("path", (std::string) absPath.abs());
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)}; return {makeFSInputAccessor(absPath), std::move(input2)};
} }
}
std::optional<std::string> getFingerprint(ref<Store> store, const Input & input) const override 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; url = git+file://$nonFlakeDir;
flake = false; flake = false;
}; };
# FIXME: we can't lock path:// inputs at the moment. nonFlakeFile = {
#nonFlakeFile = { url = path://$nonFlakeDir/README.md?lock=1;
# url = path://$nonFlakeDir/README.md; flake = false;
# flake = false; };
#};
#nonFlakeFile2 = { #nonFlakeFile2 = {
# url = "$nonFlakeDir/README.md"; # url = "$nonFlakeDir/README.md";
# flake = false; # 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"); 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
[[ \$(cat \${inputs.nonFlake}/README.md) = \$(cat \${inputs.nonFlakeFile}) ]]
''; '';
# [[ \$(cat \${inputs.nonFlake}/README.md) = \$(cat \${inputs.nonFlakeFile}) ]]
# [[ \${inputs.nonFlakeFile} = \${inputs.nonFlakeFile2} ]] # [[ \${inputs.nonFlakeFile} = \${inputs.nonFlakeFile2} ]]
}; };
}; };

View file

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