diff --git a/doc/manual/rl-next/locked-paths.md b/doc/manual/rl-next/locked-paths.md new file mode 100644 index 000000000..4e5b5a427 --- /dev/null +++ b/doc/manual/rl-next/locked-paths.md @@ -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. diff --git a/lix/libfetchers/fetchers.cc b/lix/libfetchers/fetchers.cc index 457a5abff..0dc9f5e0c 100644 --- a/lix/libfetchers/fetchers.cc +++ b/lix/libfetchers/fetchers.cc @@ -38,7 +38,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(); diff --git a/lix/libfetchers/fetchers.hh b/lix/libfetchers/fetchers.hh index 1e965b756..420256bd2 100644 --- a/lix/libfetchers/fetchers.hh +++ b/lix/libfetchers/fetchers.hh @@ -166,6 +166,13 @@ struct InputScheme virtual kj::Promise>> fetch(ref 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, diff --git a/lix/libfetchers/indirect.cc b/lix/libfetchers/indirect.cc index 9f7678834..1aec6c522 100644 --- a/lix/libfetchers/indirect.cc +++ b/lix/libfetchers/indirect.cc @@ -86,6 +86,8 @@ struct IndirectInputScheme : InputScheme return url; } + bool isLockedByRev() const override { return false; } + bool hasAllInfo(const Input & input) const override { return false; diff --git a/lix/libfetchers/path.cc b/lix/libfetchers/path.cc index 94938edce..dc45db021 100644 --- a/lix/libfetchers/path.cc +++ b/lix/libfetchers/path.cc @@ -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); diff --git a/lix/libfetchers/tarball.cc b/lix/libfetchers/tarball.cc index e87098f68..c6fc52161 100644 --- a/lix/libfetchers/tarball.cc +++ b/lix/libfetchers/tarball.cc @@ -292,6 +292,8 @@ struct CurlInputScheme : InputScheme return url; } + bool isLockedByRev() const override { return false; } + bool hasAllInfo(const Input & input) const override { return true; diff --git a/tests/functional/fetchers.sh b/tests/functional/fetchers.sh index 0f888dc33..d1d6d1b63 100644 --- a/tests/functional/fetchers.sh +++ b/tests/functional/fetchers.sh @@ -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"