mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-24 14:56:15 +02:00
GitInputScheme::lazyFetch(): Return rev/revCount/ref/lastModified
This commit is contained in:
parent
ad4b7669db
commit
e6cf987201
3 changed files with 62 additions and 31 deletions
|
@ -303,6 +303,8 @@ struct GitInputScheme : InputScheme
|
||||||
warn("Git tree '%s' is dirty", url);
|
warn("Git tree '%s' is dirty", url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string gitDir = getGitDir();
|
||||||
};
|
};
|
||||||
|
|
||||||
RepoInfo getRepoInfo(const Input & input)
|
RepoInfo getRepoInfo(const Input & input)
|
||||||
|
@ -411,6 +413,34 @@ struct GitInputScheme : InputScheme
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateRev(Input & input, const RepoInfo & repoInfo, const std::string & ref)
|
||||||
|
{
|
||||||
|
if (!input.getRev())
|
||||||
|
input.attrs.insert_or_assign("rev",
|
||||||
|
Hash::parseAny(chomp(runProgram("git", true, { "-C", repoInfo.url, "--git-dir", repoInfo.gitDir, "rev-parse", ref })), htSHA1).gitRev());
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t getLastModified(const RepoInfo & repoInfo, const std::string & repoDir, const std::string & ref)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
repoInfo.hasHead
|
||||||
|
? std::stoull(
|
||||||
|
runProgram("git", true,
|
||||||
|
{ "-C", repoDir, "--git-dir", repoInfo.gitDir, "log", "-1", "--format=%ct", "--no-show-signature", ref }))
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t getRevCount(const RepoInfo & repoInfo, const std::string & repoDir, const Hash & rev)
|
||||||
|
{
|
||||||
|
// FIXME: cache this.
|
||||||
|
return
|
||||||
|
repoInfo.hasHead
|
||||||
|
? std::stoull(
|
||||||
|
runProgram("git", true,
|
||||||
|
{ "-C", repoDir, "--git-dir", repoInfo.gitDir, "rev-list", "--count", rev.gitRev() }))
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
std::string getDefaultRef(const RepoInfo & repoInfo)
|
std::string getDefaultRef(const RepoInfo & repoInfo)
|
||||||
{
|
{
|
||||||
auto head = repoInfo.isLocal
|
auto head = repoInfo.isLocal
|
||||||
|
@ -426,7 +456,6 @@ struct GitInputScheme : InputScheme
|
||||||
std::pair<StorePath, Input> fetch(ref<Store> store, const Input & _input) override
|
std::pair<StorePath, Input> fetch(ref<Store> store, const Input & _input) override
|
||||||
{
|
{
|
||||||
Input input(_input);
|
Input input(_input);
|
||||||
auto gitDir = getGitDir(); // FIXME: move into RepoInfo
|
|
||||||
|
|
||||||
auto repoInfo = getRepoInfo(input);
|
auto repoInfo = getRepoInfo(input);
|
||||||
|
|
||||||
|
@ -474,13 +503,8 @@ struct GitInputScheme : InputScheme
|
||||||
Path repoDir;
|
Path repoDir;
|
||||||
|
|
||||||
if (repoInfo.isLocal) {
|
if (repoInfo.isLocal) {
|
||||||
|
updateRev(input, repoInfo, ref);
|
||||||
if (!input.getRev())
|
|
||||||
input.attrs.insert_or_assign("rev",
|
|
||||||
Hash::parseAny(chomp(runProgram("git", true, { "-C", repoInfo.url, "--git-dir", getGitDir(), "rev-parse", ref })), htSHA1).gitRev());
|
|
||||||
|
|
||||||
repoDir = repoInfo.url;
|
repoDir = repoInfo.url;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (auto res = getCache()->lookup(store, unlockedAttrs)) {
|
if (auto res = getCache()->lookup(store, unlockedAttrs)) {
|
||||||
auto rev2 = Hash::parseAny(getStrAttr(res->first, "rev"), htSHA1);
|
auto rev2 = Hash::parseAny(getStrAttr(res->first, "rev"), htSHA1);
|
||||||
|
@ -492,7 +516,7 @@ struct GitInputScheme : InputScheme
|
||||||
|
|
||||||
Path cacheDir = getCachePath(repoInfo.url);
|
Path cacheDir = getCachePath(repoInfo.url);
|
||||||
repoDir = cacheDir;
|
repoDir = cacheDir;
|
||||||
gitDir = ".";
|
repoInfo.gitDir = ".";
|
||||||
|
|
||||||
createDirs(dirOf(cacheDir));
|
createDirs(dirOf(cacheDir));
|
||||||
PathLocks cacheDirLock({cacheDir + ".lock"});
|
PathLocks cacheDirLock({cacheDir + ".lock"});
|
||||||
|
@ -513,7 +537,7 @@ struct GitInputScheme : InputScheme
|
||||||
repo. */
|
repo. */
|
||||||
if (input.getRev()) {
|
if (input.getRev()) {
|
||||||
try {
|
try {
|
||||||
runProgram("git", true, { "-C", repoDir, "--git-dir", gitDir, "cat-file", "-e", input.getRev()->gitRev() });
|
runProgram("git", true, { "-C", repoDir, "--git-dir", repoInfo.gitDir, "cat-file", "-e", input.getRev()->gitRev() });
|
||||||
doFetch = false;
|
doFetch = false;
|
||||||
} catch (ExecError & e) {
|
} catch (ExecError & e) {
|
||||||
if (WIFEXITED(e.status)) {
|
if (WIFEXITED(e.status)) {
|
||||||
|
@ -549,7 +573,7 @@ struct GitInputScheme : InputScheme
|
||||||
: "refs/heads/" + ref;
|
: "refs/heads/" + ref;
|
||||||
runProgram("git", true,
|
runProgram("git", true,
|
||||||
{ "-C", repoDir,
|
{ "-C", repoDir,
|
||||||
"--git-dir", gitDir,
|
"--git-dir", repoInfo.gitDir,
|
||||||
"fetch",
|
"fetch",
|
||||||
"--quiet",
|
"--quiet",
|
||||||
"--force",
|
"--force",
|
||||||
|
@ -574,7 +598,7 @@ struct GitInputScheme : InputScheme
|
||||||
// cache dir lock is removed at scope end; we will only use read-only operations on specific revisions in the remainder
|
// cache dir lock is removed at scope end; we will only use read-only operations on specific revisions in the remainder
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isShallow = chomp(runProgram("git", true, { "-C", repoDir, "--git-dir", gitDir, "rev-parse", "--is-shallow-repository" })) == "true";
|
bool isShallow = chomp(runProgram("git", true, { "-C", repoDir, "--git-dir", repoInfo.gitDir, "rev-parse", "--is-shallow-repository" })) == "true";
|
||||||
|
|
||||||
if (isShallow && !repoInfo.shallow)
|
if (isShallow && !repoInfo.shallow)
|
||||||
throw Error("'%s' is a shallow Git repository, but a non-shallow repository is needed", repoInfo.url);
|
throw Error("'%s' is a shallow Git repository, but a non-shallow repository is needed", repoInfo.url);
|
||||||
|
@ -594,7 +618,7 @@ struct GitInputScheme : InputScheme
|
||||||
|
|
||||||
auto result = runProgram(RunOptions {
|
auto result = runProgram(RunOptions {
|
||||||
.program = "git",
|
.program = "git",
|
||||||
.args = { "-C", repoDir, "--git-dir", gitDir, "cat-file", "commit", input.getRev()->gitRev() },
|
.args = { "-C", repoDir, "--git-dir", repoInfo.gitDir, "cat-file", "commit", input.getRev()->gitRev() },
|
||||||
.mergeStderrToStdout = true
|
.mergeStderrToStdout = true
|
||||||
});
|
});
|
||||||
if (WEXITSTATUS(result.first) == 128
|
if (WEXITSTATUS(result.first) == 128
|
||||||
|
@ -633,7 +657,7 @@ struct GitInputScheme : InputScheme
|
||||||
auto source = sinkToSource([&](Sink & sink) {
|
auto source = sinkToSource([&](Sink & sink) {
|
||||||
runProgram2({
|
runProgram2({
|
||||||
.program = "git",
|
.program = "git",
|
||||||
.args = { "-C", repoDir, "--git-dir", gitDir, "archive", input.getRev()->gitRev() },
|
.args = { "-C", repoDir, "--git-dir", repoInfo.gitDir, "archive", input.getRev()->gitRev() },
|
||||||
.standardOut = &sink
|
.standardOut = &sink
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -643,16 +667,16 @@ struct GitInputScheme : InputScheme
|
||||||
|
|
||||||
auto storePath = store->addToStore(name, tmpDir, FileIngestionMethod::Recursive, htSHA256, filter);
|
auto storePath = store->addToStore(name, tmpDir, FileIngestionMethod::Recursive, htSHA256, filter);
|
||||||
|
|
||||||
auto lastModified = std::stoull(runProgram("git", true, { "-C", repoDir, "--git-dir", gitDir, "log", "-1", "--format=%ct", "--no-show-signature", input.getRev()->gitRev() }));
|
auto rev = *input.getRev();
|
||||||
|
|
||||||
Attrs infoAttrs({
|
Attrs infoAttrs({
|
||||||
{"rev", input.getRev()->gitRev()},
|
{"rev", rev.gitRev()},
|
||||||
{"lastModified", lastModified},
|
{"lastModified", getLastModified(repoInfo, repoDir, rev.gitRev())},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!repoInfo.shallow)
|
if (!repoInfo.shallow)
|
||||||
infoAttrs.insert_or_assign("revCount",
|
infoAttrs.insert_or_assign("revCount",
|
||||||
std::stoull(runProgram("git", true, { "-C", repoDir, "--git-dir", gitDir, "rev-list", "--count", input.getRev()->gitRev() })));
|
getRevCount(repoInfo, repoDir, rev));
|
||||||
|
|
||||||
if (!_input.getRev())
|
if (!_input.getRev())
|
||||||
getCache()->add(
|
getCache()->add(
|
||||||
|
@ -695,15 +719,15 @@ struct GitInputScheme : InputScheme
|
||||||
// modified dirty file?
|
// modified dirty file?
|
||||||
input.attrs.insert_or_assign(
|
input.attrs.insert_or_assign(
|
||||||
"lastModified",
|
"lastModified",
|
||||||
repoInfo.hasHead
|
getLastModified(repoInfo, repoInfo.url, "HEAD"));
|
||||||
? std::stoull(runProgram("git", true, { "-C", repoInfo.url, "log", "-1", "--format=%ct", "--no-show-signature", "HEAD" }))
|
|
||||||
: 0);
|
|
||||||
|
|
||||||
return {std::move(storePath), input};
|
return {std::move(storePath), input};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<ref<InputAccessor>, Input> lazyFetch(ref<Store> store, const Input & input) override
|
std::pair<ref<InputAccessor>, Input> lazyFetch(ref<Store> store, const Input & _input) override
|
||||||
{
|
{
|
||||||
|
Input input(_input);
|
||||||
|
|
||||||
auto repoInfo = getRepoInfo(input);
|
auto repoInfo = getRepoInfo(input);
|
||||||
|
|
||||||
/* Unless we're using the working tree, copy the tree into the
|
/* Unless we're using the working tree, copy the tree into the
|
||||||
|
@ -714,7 +738,22 @@ struct GitInputScheme : InputScheme
|
||||||
|
|
||||||
repoInfo.checkDirty();
|
repoInfo.checkDirty();
|
||||||
|
|
||||||
// FIXME: return updated input.
|
auto ref = getDefaultRef(repoInfo);
|
||||||
|
input.attrs.insert_or_assign("ref", ref);
|
||||||
|
|
||||||
|
if (!repoInfo.isDirty) {
|
||||||
|
updateRev(input, repoInfo, ref);
|
||||||
|
|
||||||
|
input.attrs.insert_or_assign(
|
||||||
|
"revCount",
|
||||||
|
getRevCount(repoInfo, repoInfo.url, *input.getRev()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: maybe we should use the timestamp of the last
|
||||||
|
// modified dirty file?
|
||||||
|
input.attrs.insert_or_assign(
|
||||||
|
"lastModified",
|
||||||
|
getLastModified(repoInfo, repoInfo.url, ref));
|
||||||
|
|
||||||
auto makeNotAllowedError = [url{repoInfo.url}](const CanonPath & path) -> RestrictedPathError
|
auto makeNotAllowedError = [url{repoInfo.url}](const CanonPath & path) -> RestrictedPathError
|
||||||
{
|
{
|
||||||
|
|
|
@ -182,9 +182,6 @@ struct CmdFlakeMetadata : FlakeCommand, MixJSON
|
||||||
j["revCount"] = *revCount;
|
j["revCount"] = *revCount;
|
||||||
if (auto lastModified = flake.lockedRef.input.getLastModified())
|
if (auto lastModified = flake.lockedRef.input.getLastModified())
|
||||||
j["lastModified"] = *lastModified;
|
j["lastModified"] = *lastModified;
|
||||||
#if 0
|
|
||||||
j["path"] = store->printStorePath(flake.sourceInfo->storePath);
|
|
||||||
#endif
|
|
||||||
j["locks"] = lockedFlake.lockFile.toJSON();
|
j["locks"] = lockedFlake.lockFile.toJSON();
|
||||||
logger->cout("%s", j.dump());
|
logger->cout("%s", j.dump());
|
||||||
} else {
|
} else {
|
||||||
|
@ -198,11 +195,6 @@ struct CmdFlakeMetadata : FlakeCommand, MixJSON
|
||||||
logger->cout(
|
logger->cout(
|
||||||
ANSI_BOLD "Description:" ANSI_NORMAL " %s",
|
ANSI_BOLD "Description:" ANSI_NORMAL " %s",
|
||||||
*flake.description);
|
*flake.description);
|
||||||
#if 0
|
|
||||||
logger->cout(
|
|
||||||
ANSI_BOLD "Path:" ANSI_NORMAL " %s",
|
|
||||||
store->printStorePath(flake.sourceInfo->storePath));
|
|
||||||
#endif
|
|
||||||
if (auto rev = flake.lockedRef.input.getRev())
|
if (auto rev = flake.lockedRef.input.getRev())
|
||||||
logger->cout(
|
logger->cout(
|
||||||
ANSI_BOLD "Revision:" ANSI_NORMAL " %s",
|
ANSI_BOLD "Revision:" ANSI_NORMAL " %s",
|
||||||
|
|
|
@ -124,7 +124,7 @@ nix flake metadata $flake1Dir | grep -q 'URL:.*flake1.*'
|
||||||
# Test 'nix flake metadata --json'.
|
# Test 'nix flake metadata --json'.
|
||||||
json=$(nix flake metadata flake1 --json | jq .)
|
json=$(nix flake metadata flake1 --json | jq .)
|
||||||
[[ $(echo "$json" | jq -r .description) = 'Bla bla' ]]
|
[[ $(echo "$json" | jq -r .description) = 'Bla bla' ]]
|
||||||
[[ -d $(echo "$json" | jq -r .path) ]]
|
#[[ -d $(echo "$json" | jq -r .path) ]]
|
||||||
[[ $(echo "$json" | jq -r .lastModified) = $(git -C $flake1Dir log -n1 --format=%ct) ]]
|
[[ $(echo "$json" | jq -r .lastModified) = $(git -C $flake1Dir log -n1 --format=%ct) ]]
|
||||||
hash1=$(echo "$json" | jq -r .revision)
|
hash1=$(echo "$json" | jq -r .revision)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue