aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2019-10-21 23:14:29 +0200
committerEelco Dolstra <edolstra@gmail.com>2019-10-21 23:14:29 +0200
commit1e23b82a5303fa9f22f8943c0c3f3a65bc5eb9a9 (patch)
tree20d9c2f53328d282ad69e060c6be04dedcc8098f /src/libexpr
parent45b740c18b196d0326a94df23d08fa3d68e0863f (diff)
exportGitHub(): Don't rely on the ETag from GitHub
We relied on it being the Git revision, but that stopped being the case.
Diffstat (limited to 'src/libexpr')
-rw-r--r--src/libexpr/primops/fetchGit.cc22
1 files changed, 13 insertions, 9 deletions
diff --git a/src/libexpr/primops/fetchGit.cc b/src/libexpr/primops/fetchGit.cc
index 50277672c..e8d87ffa4 100644
--- a/src/libexpr/primops/fetchGit.cc
+++ b/src/libexpr/primops/fetchGit.cc
@@ -286,11 +286,21 @@ GitInfo exportGitHub(
return *gitInfo;
}
+ if (!rev) {
+ auto url = fmt("https://api.github.com/repos/%s/%s/commits/%s",
+ owner, repo, ref ? *ref : "master");
+ CachedDownloadRequest request(url);
+ request.ttl = rev ? 1000000000 : settings.tarballTtl;
+ auto result = getDownloader()->downloadCached(store, request);
+ auto json = nlohmann::json::parse(readFile(result.path));
+ rev = Hash(json["sha"], htSHA1);
+ }
+
// FIXME: use regular /archive URLs instead? api.github.com
// might have stricter rate limits.
auto url = fmt("https://api.github.com/repos/%s/%s/tarball/%s",
- owner, repo, rev ? rev->to_string(Base16, false) : ref ? *ref : "master");
+ owner, repo, rev->to_string(Base16, false));
std::string accessToken = settings.githubAccessToken.get();
if (accessToken != "")
@@ -299,21 +309,15 @@ GitInfo exportGitHub(
CachedDownloadRequest request(url);
request.unpack = true;
request.name = "source";
- request.ttl = rev ? 1000000000 : settings.tarballTtl;
+ request.ttl = 1000000000;
request.getLastModified = true;
auto result = getDownloader()->downloadCached(store, request);
- if (!result.etag)
- throw Error("did not receive an ETag header from '%s'", url);
-
- if (result.etag->size() != 42 || (*result.etag)[0] != '"' || (*result.etag)[41] != '"')
- throw Error("ETag header '%s' from '%s' is not a Git revision", *result.etag, url);
-
assert(result.lastModified);
GitInfo gitInfo;
gitInfo.storePath = result.storePath;
- gitInfo.rev = Hash(std::string(*result.etag, 1, result.etag->size() - 2), htSHA1);
+ gitInfo.rev = *rev;
gitInfo.lastModified = *result.lastModified;
// FIXME: this can overwrite a cache file that contains a revCount.