fetchers: don't consider a path locked if a rev is specified
It's possible to put a path into the store in pure mode by pretending
it's locked like this:
$ echo 'lalala' > testfile
$ nix eval --expr '(builtins.fetchTree { path = "/home/ma27/testfile"; rev = "0000000000000000000000000000000000000000"; type = "path"; })'
{ lastModified = 1723656303; lastModifiedDate = "20240814172503"; narHash = "sha256-hOMY06A0ohaaCLwnhpZIMoAqi/8kG2vk30NRiqi0dfc="; outPath = "/nix/store/lhfz259iipmv9ky995rml8018jvriynh-source"; rev = "0000000000000000000000000000000000000000"; shortRev = "0000000"; }
$ cat /nix/store/lhfz259iipmv9ky995rml8018jvriynh-source
lalala
There was a fix in CppNix[1], but Puck noted that it's breaking
backwards-compatibility because
> [...] a github fetch with a fully specified rev is no longer considered "locked"
> this is for "purity" reasons, but it breaks any existing flake.nix files
I tried a way smaller correctness fix here:
* Each scheme can denote whether a `rev` is enough to consider itself
locked.
* If a `rev` is given and the scheme is OK with just a `rev` to be
locked, the input is marked as locked.
For `path` this is not the case anymore, i.e. it requires a NAR hash to
be locked down.
[1] https://github.com/nixos/nix/commit/071dd2b3a4e6c0b2106f1b6f14ec26e153d97446
Change-Id: Ibbbf4733c82bcfa1c24dfe099a896d8aaecd81cc
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
---
|
||||
synopsis: Don't consider a path with a specified rev to be `locked`
|
||||
issues: []
|
||||
cls: [2064]
|
||||
category: Fixes
|
||||
credits: [ma27]
|
||||
---
|
||||
|
||||
Until now it was allowed to do e.g.
|
||||
|
||||
$ echo 'lalala' > testfile
|
||||
$ nix eval --expr '(builtins.fetchTree { path = "/home/ma27/testfile"; rev = "0000000000000000000000000000000000000000"; type = "path"; })'
|
||||
{ lastModified = 1723656303; lastModifiedDate = "20240814172503"; narHash = "sha256-hOMY06A0ohaaCLwnhpZIMoAqi/8kG2vk30NRiqi0dfc="; outPath = "/nix/store/lhfz259iipmv9ky995rml8018jvriynh-source"; rev = "0000000000000000000000000000000000000000"; shortRev = "0000000"; }
|
||||
$ cat /nix/store/lhfz259iipmv9ky995rml8018jvriynh-source
|
||||
lalala
|
||||
|
||||
because any kind of input with a `rev` specified is considered to be locked.
|
||||
|
||||
With this change, inputs of type `path`, `indirect` and `tarball` are no longer
|
||||
considered locked with a rev, but no hash specified.
|
||||
|
||||
This behavior was changed in
|
||||
[CppNix 2.21 as well](https://github.com/nixos/nix/commit/071dd2b3a4e6c0b2106f1b6f14ec26e153d97446) as well.
|
||||
@@ -39,7 +39,7 @@ static void fixupInput(Input & input)
|
||||
// Check common attributes.
|
||||
input.getType();
|
||||
input.getRef();
|
||||
if (input.getRev())
|
||||
if (input.scheme && input.scheme->isLockedByRev() && input.getRev())
|
||||
input.locked = true;
|
||||
input.getRevCount();
|
||||
input.getLastModified();
|
||||
|
||||
@@ -165,6 +165,13 @@ struct InputScheme
|
||||
virtual kj::Promise<Result<std::pair<StorePath, Input>>>
|
||||
fetch(ref<Store> store, const Input & input) = 0;
|
||||
|
||||
/*
|
||||
* By default, libfetchers considers inputs as locked if a `rev`
|
||||
* is specified. This however doesn't make any sense for `path` inputs,
|
||||
* so schemes can indicate that a `rev` on its own is not sufficient.
|
||||
*/
|
||||
virtual bool isLockedByRev() const { return true; }
|
||||
|
||||
protected:
|
||||
void emplaceURLQueryIntoAttrs(
|
||||
const ParsedURL & parsedURL,
|
||||
|
||||
@@ -86,6 +86,8 @@ struct IndirectInputScheme : InputScheme
|
||||
return url;
|
||||
}
|
||||
|
||||
bool isLockedByRev() const override { return false; }
|
||||
|
||||
bool hasAllInfo(const Input & input) const override
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -56,6 +56,8 @@ struct PathInputScheme : InputScheme
|
||||
return input;
|
||||
}
|
||||
|
||||
bool isLockedByRev() const override { return false; }
|
||||
|
||||
ParsedURL toURL(const Input & input) const override
|
||||
{
|
||||
auto query = attrsToQuery(input.attrs);
|
||||
|
||||
@@ -253,6 +253,8 @@ struct CurlInputScheme : InputScheme
|
||||
return url;
|
||||
}
|
||||
|
||||
bool isLockedByRev() const override { return false; }
|
||||
|
||||
bool hasAllInfo(const Input & input) const override
|
||||
{
|
||||
return true;
|
||||
|
||||
@@ -89,3 +89,8 @@ testFetchTreeError \
|
||||
testFetchTreeError \
|
||||
"{ type = \"hg\"; url = \"https://forge.tld/owner/repo\"; ref = \",\"; }" \
|
||||
"invalid Mercurial branch/tag name ','"
|
||||
|
||||
echo 'hello lix' > testfile
|
||||
output="$(nix eval --expr '(builtins.fetchTree { path = "'"$(pwd)"'/testfile"; rev = "0000000000000000000000000000000000000000"; type = "path"; })' 2>&1)" && status=0 || status=$?
|
||||
[ "$status" -eq 1 ]
|
||||
grepQuiet "error: in pure evaluation mode, 'fetchTree' requires a locked input" <<<"$output"
|
||||
|
||||
Reference in New Issue
Block a user