Get last commit time of github flakes

This commit is contained in:
Eelco Dolstra 2019-05-28 22:35:41 +02:00
parent 0f840483c7
commit ae7b56cd9a
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
5 changed files with 37 additions and 8 deletions

View file

@ -265,6 +265,7 @@ static SourceInfo fetchFlake(EvalState & state, const FlakeRef & flakeRef, bool
request.unpack = true; request.unpack = true;
request.name = "source"; request.name = "source";
request.ttl = resolvedRef.rev ? 1000000000 : settings.tarballTtl; request.ttl = resolvedRef.rev ? 1000000000 : settings.tarballTtl;
request.getLastModified = true;
auto result = getDownloader()->downloadCached(state.store, request); auto result = getDownloader()->downloadCached(state.store, request);
if (!result.etag) if (!result.etag)
@ -278,6 +279,7 @@ static SourceInfo fetchFlake(EvalState & state, const FlakeRef & flakeRef, bool
SourceInfo info(ref); SourceInfo info(ref);
info.storePath = result.storePath; info.storePath = result.storePath;
info.narHash = state.store->queryPathInfo(info.storePath)->narHash; info.narHash = state.store->queryPathInfo(info.storePath)->narHash;
info.lastModified = result.lastModified;
return info; return info;
} }

View file

@ -808,6 +808,7 @@ CachedDownloadResult Downloader::downloadCached(
CachedDownloadResult result; CachedDownloadResult result;
result.storePath = expectedStorePath; result.storePath = expectedStorePath;
result.path = store->toRealPath(expectedStorePath); result.path = store->toRealPath(expectedStorePath);
assert(!request.getLastModified); // FIXME
return result; return result;
} }
} }
@ -892,16 +893,26 @@ CachedDownloadResult Downloader::downloadCached(
store->addTempRoot(unpackedStorePath); store->addTempRoot(unpackedStorePath);
if (!store->isValidPath(unpackedStorePath)) if (!store->isValidPath(unpackedStorePath))
unpackedStorePath = ""; unpackedStorePath = "";
else
result.lastModified = lstat(unpackedLink).st_mtime;
} }
if (unpackedStorePath.empty()) { if (unpackedStorePath.empty()) {
printInfo(format("unpacking '%1%'...") % url); printInfo(format("unpacking '%1%'...") % url);
Path tmpDir = createTempDir(); Path tmpDir = createTempDir();
AutoDelete autoDelete(tmpDir, true); AutoDelete autoDelete(tmpDir, true);
// FIXME: this requires GNU tar for decompression. // FIXME: this requires GNU tar for decompression.
runProgram("tar", true, {"xf", store->toRealPath(storePath), "-C", tmpDir, "--strip-components", "1"}); runProgram("tar", true, {"xf", store->toRealPath(storePath), "-C", tmpDir});
unpackedStorePath = store->addToStore(name, tmpDir, true, htSHA256, defaultPathFilter, NoRepair); auto members = readDirectory(tmpDir);
if (members.size() != 1)
throw nix::Error("tarball '%s' contains an unexpected number of top-level files", url);
auto topDir = tmpDir + "/" + members.begin()->name;
result.lastModified = lstat(topDir).st_mtime;
unpackedStorePath = store->addToStore(name, topDir, true, htSHA256, defaultPathFilter, NoRepair);
} }
replaceSymlink(unpackedStorePath, unpackedLink); // Store the last-modified date of the tarball in the symlink
// mtime. This saves us from having to store it somewhere
// else.
replaceSymlink(unpackedStorePath, unpackedLink, result.lastModified);
storePath = unpackedStorePath; storePath = unpackedStorePath;
} }

View file

@ -49,6 +49,7 @@ struct CachedDownloadRequest
Hash expectedHash; Hash expectedHash;
unsigned int ttl = settings.tarballTtl; unsigned int ttl = settings.tarballTtl;
bool gcRoot = false; bool gcRoot = false;
bool getLastModified = false;
CachedDownloadRequest(const std::string & uri) CachedDownloadRequest(const std::string & uri)
: uri(uri) { } : uri(uri) { }
@ -62,6 +63,7 @@ struct CachedDownloadResult
Path path; Path path;
std::optional<std::string> etag; std::optional<std::string> etag;
std::string effectiveUri; std::string effectiveUri;
std::optional<time_t> lastModified;
}; };
class Store; class Store;

View file

@ -22,6 +22,7 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/time.h>
#include <unistd.h> #include <unistd.h>
#ifdef __APPLE__ #ifdef __APPLE__
@ -552,20 +553,31 @@ Paths createDirs(const Path & path)
} }
void createSymlink(const Path & target, const Path & link) void createSymlink(const Path & target, const Path & link,
std::optional<time_t> mtime)
{ {
if (symlink(target.c_str(), link.c_str())) if (symlink(target.c_str(), link.c_str()))
throw SysError(format("creating symlink from '%1%' to '%2%'") % link % target); throw SysError(format("creating symlink from '%1%' to '%2%'") % link % target);
if (mtime) {
struct timeval times[2];
times[0].tv_sec = *mtime;
times[0].tv_usec = 0;
times[1].tv_sec = *mtime;
times[1].tv_usec = 0;
if (lutimes(link.c_str(), times))
throw SysError("setting time of symlink '%s'", link);
}
} }
void replaceSymlink(const Path & target, const Path & link) void replaceSymlink(const Path & target, const Path & link,
std::optional<time_t> mtime)
{ {
for (unsigned int n = 0; true; n++) { for (unsigned int n = 0; true; n++) {
Path tmp = canonPath(fmt("%s/.%d_%s", dirOf(link), n, baseNameOf(link))); Path tmp = canonPath(fmt("%s/.%d_%s", dirOf(link), n, baseNameOf(link)));
try { try {
createSymlink(target, tmp); createSymlink(target, tmp, mtime);
} catch (SysError & e) { } catch (SysError & e) {
if (e.errNo == EEXIST) continue; if (e.errNo == EEXIST) continue;
throw; throw;

View file

@ -142,10 +142,12 @@ Path getDataDir();
Paths createDirs(const Path & path); Paths createDirs(const Path & path);
/* Create a symlink. */ /* Create a symlink. */
void createSymlink(const Path & target, const Path & link); void createSymlink(const Path & target, const Path & link,
std::optional<time_t> mtime = {});
/* Atomically create or replace a symlink. */ /* Atomically create or replace a symlink. */
void replaceSymlink(const Path & target, const Path & link); void replaceSymlink(const Path & target, const Path & link,
std::optional<time_t> mtime = {});
/* Wrappers arount read()/write() that read/write exactly the /* Wrappers arount read()/write() that read/write exactly the