mirror of
https://github.com/NixOS/nix
synced 2025-06-29 06:21:14 +02:00
Warn if the computed tree hash differs from the one reported by GitHub
Ideally this would be a fatal error, but tree hashes won't be correct for repos that use submodules. (But OTOH, the GitHub fetcher doesn't support submodules anyway...)
This commit is contained in:
parent
7b1cda9ca2
commit
00b746d099
1 changed files with 36 additions and 15 deletions
|
@ -199,7 +199,13 @@ struct GitArchiveInputScheme : InputScheme
|
||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Hash getRevFromRef(nix::ref<Store> store, const Input & input) const = 0;
|
struct RefInfo
|
||||||
|
{
|
||||||
|
Hash rev;
|
||||||
|
std::optional<Hash> treeHash;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual RefInfo getRevFromRef(nix::ref<Store> store, const Input & input) const = 0;
|
||||||
|
|
||||||
virtual DownloadUrl getDownloadUrl(const Input & input) const = 0;
|
virtual DownloadUrl getDownloadUrl(const Input & input) const = 0;
|
||||||
|
|
||||||
|
@ -207,8 +213,15 @@ struct GitArchiveInputScheme : InputScheme
|
||||||
{
|
{
|
||||||
if (!maybeGetStrAttr(input.attrs, "ref")) input.attrs.insert_or_assign("ref", "HEAD");
|
if (!maybeGetStrAttr(input.attrs, "ref")) input.attrs.insert_or_assign("ref", "HEAD");
|
||||||
|
|
||||||
|
std::optional<Hash> upstreamTreeHash;
|
||||||
|
|
||||||
auto rev = input.getRev();
|
auto rev = input.getRev();
|
||||||
if (!rev) rev = getRevFromRef(store, input);
|
if (!rev) {
|
||||||
|
auto refInfo = getRevFromRef(store, input);
|
||||||
|
rev = refInfo.rev;
|
||||||
|
upstreamTreeHash = refInfo.treeHash;
|
||||||
|
debug("HEAD revision for '%s' is %s", input.to_string(), refInfo.rev.gitRev());
|
||||||
|
}
|
||||||
|
|
||||||
input.attrs.erase("ref");
|
input.attrs.erase("ref");
|
||||||
input.attrs.insert_or_assign("rev", rev->gitRev());
|
input.attrs.insert_or_assign("rev", rev->gitRev());
|
||||||
|
@ -243,6 +256,13 @@ struct GitArchiveInputScheme : InputScheme
|
||||||
cache->upsertFact(treeHashKey, tarballInfo.treeHash.gitRev());
|
cache->upsertFact(treeHashKey, tarballInfo.treeHash.gitRev());
|
||||||
cache->upsertFact(lastModifiedKey, std::to_string(tarballInfo.lastModified));
|
cache->upsertFact(lastModifiedKey, std::to_string(tarballInfo.lastModified));
|
||||||
|
|
||||||
|
if (upstreamTreeHash != tarballInfo.treeHash)
|
||||||
|
warn(
|
||||||
|
"Git tree hash mismatch for revision '%s' of '%s': "
|
||||||
|
"expected '%s', got '%s'. "
|
||||||
|
"This can happen if the Git repository uses submodules.",
|
||||||
|
rev->gitRev(), input.to_string(), upstreamTreeHash->gitRev(), tarballInfo.treeHash.gitRev());
|
||||||
|
|
||||||
return {std::move(input), tarballInfo};
|
return {std::move(input), tarballInfo};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,7 +317,7 @@ struct GitHubInputScheme : GitArchiveInputScheme
|
||||||
}
|
}
|
||||||
|
|
||||||
/* .commit.tree.sha, .commit.committer.date */
|
/* .commit.tree.sha, .commit.committer.date */
|
||||||
Hash getRevFromRef(nix::ref<Store> store, const Input & input) const override
|
RefInfo getRevFromRef(nix::ref<Store> store, const Input & input) const override
|
||||||
{
|
{
|
||||||
auto host = getHost(input);
|
auto host = getHost(input);
|
||||||
auto url = fmt(
|
auto url = fmt(
|
||||||
|
@ -312,9 +332,10 @@ struct GitHubInputScheme : GitArchiveInputScheme
|
||||||
readFile(
|
readFile(
|
||||||
store->toRealPath(
|
store->toRealPath(
|
||||||
downloadFile(store, url, "source", false, headers).storePath)));
|
downloadFile(store, url, "source", false, headers).storePath)));
|
||||||
auto rev = Hash::parseAny(std::string { json["sha"] }, htSHA1);
|
return RefInfo {
|
||||||
debug("HEAD revision for '%s' is %s", url, rev.gitRev());
|
.rev = Hash::parseAny(std::string { json["sha"] }, htSHA1),
|
||||||
return rev;
|
.treeHash = Hash::parseAny(std::string { json["commit"]["tree"]["sha"] }, htSHA1)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
DownloadUrl getDownloadUrl(const Input & input) const override
|
DownloadUrl getDownloadUrl(const Input & input) const override
|
||||||
|
@ -371,7 +392,7 @@ struct GitLabInputScheme : GitArchiveInputScheme
|
||||||
return std::make_pair(token.substr(0,fldsplit), token.substr(fldsplit+1));
|
return std::make_pair(token.substr(0,fldsplit), token.substr(fldsplit+1));
|
||||||
}
|
}
|
||||||
|
|
||||||
Hash getRevFromRef(nix::ref<Store> store, const Input & input) const override
|
RefInfo getRevFromRef(nix::ref<Store> store, const Input & input) const override
|
||||||
{
|
{
|
||||||
auto host = maybeGetStrAttr(input.attrs, "host").value_or("gitlab.com");
|
auto host = maybeGetStrAttr(input.attrs, "host").value_or("gitlab.com");
|
||||||
// See rate limiting note below
|
// See rate limiting note below
|
||||||
|
@ -384,9 +405,9 @@ struct GitLabInputScheme : GitArchiveInputScheme
|
||||||
readFile(
|
readFile(
|
||||||
store->toRealPath(
|
store->toRealPath(
|
||||||
downloadFile(store, url, "source", false, headers).storePath)));
|
downloadFile(store, url, "source", false, headers).storePath)));
|
||||||
auto rev = Hash::parseAny(std::string(json[0]["id"]), htSHA1);
|
return RefInfo {
|
||||||
debug("HEAD revision for '%s' is %s", url, rev.gitRev());
|
.rev = Hash::parseAny(std::string(json[0]["id"]), htSHA1)
|
||||||
return rev;
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
DownloadUrl getDownloadUrl(const Input & input) const override
|
DownloadUrl getDownloadUrl(const Input & input) const override
|
||||||
|
@ -430,7 +451,7 @@ struct SourceHutInputScheme : GitArchiveInputScheme
|
||||||
// Once it is implemented, however, should work as expected.
|
// Once it is implemented, however, should work as expected.
|
||||||
}
|
}
|
||||||
|
|
||||||
Hash getRevFromRef(nix::ref<Store> store, const Input & input) const override
|
RefInfo getRevFromRef(nix::ref<Store> store, const Input & input) const override
|
||||||
{
|
{
|
||||||
// TODO: In the future, when the sourcehut graphql API is implemented for mercurial
|
// TODO: In the future, when the sourcehut graphql API is implemented for mercurial
|
||||||
// and with anonymous access, this method should use it instead.
|
// and with anonymous access, this method should use it instead.
|
||||||
|
@ -476,9 +497,9 @@ struct SourceHutInputScheme : GitArchiveInputScheme
|
||||||
if (!id)
|
if (!id)
|
||||||
throw BadURL("in '%d', couldn't find ref '%d'", input.to_string(), ref);
|
throw BadURL("in '%d', couldn't find ref '%d'", input.to_string(), ref);
|
||||||
|
|
||||||
auto rev = Hash::parseAny(*id, htSHA1);
|
return RefInfo {
|
||||||
debug("HEAD revision for '%s' is %s", fmt("%s/%s", base_url, ref), rev.gitRev());
|
.rev = Hash::parseAny(*id, htSHA1)
|
||||||
return rev;
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
DownloadUrl getDownloadUrl(const Input & input) const override
|
DownloadUrl getDownloadUrl(const Input & input) const override
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue