fix: Consider fetchGit locked when narHash is present
`fetchGit` has been modified a long time ago to use fetchTree, however, we don't care about `lastModified` because we are not in a flake context, this hack introduces a `git-locked` type of input that only cares about `narHash` being present. This is needed to avoid fetching the remote repo each time `fetchGit` is evaluated whith the result present in the store. Change-Id: I521c6fcccf8cf12945594f205d7fd4c8c2cf89e9
This commit is contained in:
@@ -48,6 +48,10 @@ attribute with the following attributes (all except `url` optional):
|
||||
With this argument being true, it's possible to load a `rev` from *any* `ref`
|
||||
(by default only `rev`s from the specified `ref` are supported).
|
||||
|
||||
- `narHash`
|
||||
|
||||
If given, the source is first looked-up in the Nix store and the [substituters](@docroot@/command-ref/conf-file.md#conf-substituters), and only fetched if not available.
|
||||
|
||||
The return value is an attrset containing the following keys:
|
||||
|
||||
- `lastModified` (`integer`)
|
||||
|
||||
@@ -169,6 +169,13 @@ static void fetchTree(
|
||||
"attribute 'name' isn’t supported in call to 'fetchTree'"
|
||||
).atPos(pos).debugThrow();
|
||||
|
||||
// HACK: When using `fetchGit`, locking with only the hash should happen
|
||||
// as we don't care about flake shenanigans about `lastModified`
|
||||
if (type == "git" && attrs.contains("narHash")) {
|
||||
using namespace std::literals::string_literals;
|
||||
attrs["type"] = "\0git-locked"s;
|
||||
}
|
||||
|
||||
input = fetchers::Input::fromAttrs(std::move(attrs));
|
||||
} else {
|
||||
auto url = state.coerceToString(pos, *args[0], context,
|
||||
|
||||
@@ -10,6 +10,7 @@ std::unique_ptr<InputScheme> makePathInputScheme();
|
||||
std::unique_ptr<InputScheme> makeFileInputScheme();
|
||||
std::unique_ptr<InputScheme> makeTarballInputScheme();
|
||||
std::unique_ptr<InputScheme> makeGitInputScheme();
|
||||
std::unique_ptr<InputScheme> makeGitLockedInputScheme();
|
||||
std::unique_ptr<InputScheme> makeMercurialInputScheme();
|
||||
std::unique_ptr<InputScheme> makeGitHubInputScheme();
|
||||
std::unique_ptr<InputScheme> makeGitLabInputScheme();
|
||||
|
||||
@@ -22,6 +22,7 @@ void initLibFetchers()
|
||||
registerInputScheme(makeTarballInputScheme());
|
||||
registerInputScheme(makeFileInputScheme());
|
||||
registerInputScheme(makeGitInputScheme());
|
||||
registerInputScheme(makeGitLockedInputScheme());
|
||||
registerInputScheme(makeMercurialInputScheme());
|
||||
registerInputScheme(makeGitHubInputScheme());
|
||||
registerInputScheme(makeGitLabInputScheme());
|
||||
|
||||
@@ -823,4 +823,22 @@ std::unique_ptr<InputScheme> makeGitInputScheme()
|
||||
return std::make_unique<GitInputScheme>();
|
||||
}
|
||||
|
||||
struct GitLockedInputScheme : GitInputScheme {
|
||||
|
||||
std::string schemeType() const override {
|
||||
using namespace std::literals::string_literals;
|
||||
return "\0git-locked"s;
|
||||
}
|
||||
|
||||
bool hasAllInfo(const Input & input) const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
std::unique_ptr<InputScheme> makeGitLockedInputScheme()
|
||||
{
|
||||
return std::make_unique<GitLockedInputScheme>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
source common.sh
|
||||
|
||||
requireGit
|
||||
|
||||
clearStore
|
||||
|
||||
# Intentionally not in a canonical form
|
||||
# See https://github.com/NixOS/nix/issues/6195
|
||||
repo=$TEST_ROOT/./git
|
||||
|
||||
export _NIX_FORCE_HTTP=1
|
||||
|
||||
rm -rf "$repo" "$TEST_HOME/.cache/nix"
|
||||
|
||||
mkdir "$repo" && pushd "$repo"
|
||||
|
||||
git init --initial-branch=main
|
||||
git config user.email "foobar@example.com"
|
||||
git config user.name "Foobar"
|
||||
|
||||
echo utrecht >hello
|
||||
touch .gitignore
|
||||
git add hello .gitignore
|
||||
git commit -m 'Bla1'
|
||||
rev1=$(git rev-parse HEAD)
|
||||
git tag -a tag1 -m tag1
|
||||
|
||||
# Compute the hash of the output
|
||||
path=$(nix eval --impure --raw --expr "(builtins.fetchGit \"file://$repo\").outPath")
|
||||
hash=$(nix-hash --type sha256 --base32 "$path")
|
||||
narHash=$(nix-hash --to-sri --type sha256 "$hash")
|
||||
|
||||
# Remove the repo, and the local cache
|
||||
popd && rm -rf "$repo" "$TEST_HOME/.cache/nix"
|
||||
|
||||
# The path is locked and can be fetched
|
||||
path2=$(nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$repo\"; ref = \"main\"; rev=\"$rev1\"; narHash = \"$narHash\"; })")
|
||||
[[ "$path" = "$path2" ]]
|
||||
|
||||
# When no narHash is present the fetching fails
|
||||
! nix eval --impure --raw --expr "(builtins.fetchGit { url = \"file://$repo\"; ref = \"main\"; rev=\"$rev1\"; })"
|
||||
@@ -76,6 +76,7 @@ functional_tests_scripts = [
|
||||
'tarball.sh',
|
||||
'fetchers.sh',
|
||||
'fetchGit.sh',
|
||||
'fetchGitLocked.sh',
|
||||
'fetchurl.sh',
|
||||
'fetchPath.sh',
|
||||
'fetchTree-file.sh',
|
||||
|
||||
Reference in New Issue
Block a user