diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc index be14c9af3..099cf4c58 100644 --- a/src/libexpr/flake/flake.cc +++ b/src/libexpr/flake/flake.cc @@ -478,7 +478,7 @@ LockedFlake lockFlake( lockFlags.useRegistries, flakeCache); newLocks.inputs.insert_or_assign(id, - LockedInput(inputFlake.resolvedRef, inputFlake.originalRef, inputFlake.sourceInfo->narHash)); + LockedInput(inputFlake.resolvedRef, inputFlake.originalRef, inputFlake.sourceInfo->info.narHash)); /* Recursively process the inputs of this flake. Also, unless we already have this @@ -497,7 +497,7 @@ LockedFlake lockFlake( auto [sourceInfo, resolvedRef] = getNonFlake(state, input.ref, lockFlags.useRegistries, flakeCache); newLocks.inputs.insert_or_assign(id, - LockedInput(resolvedRef, input.ref, sourceInfo.narHash)); + LockedInput(resolvedRef, input.ref, sourceInfo.info.narHash)); } } } @@ -573,19 +573,19 @@ static void emitSourceInfoAttrs(EvalState & state, const fetchers::Tree & source auto pathS = state.store->printStorePath(sourceInfo.storePath); mkString(*state.allocAttr(vAttrs, state.sOutPath), pathS, {pathS}); - if (sourceInfo.rev) { + if (sourceInfo.info.rev) { mkString(*state.allocAttr(vAttrs, state.symbols.create("rev")), - sourceInfo.rev->gitRev()); + sourceInfo.info.rev->gitRev()); mkString(*state.allocAttr(vAttrs, state.symbols.create("shortRev")), - sourceInfo.rev->gitShortRev()); + sourceInfo.info.rev->gitShortRev()); } - if (sourceInfo.revCount) - mkInt(*state.allocAttr(vAttrs, state.symbols.create("revCount")), *sourceInfo.revCount); + if (sourceInfo.info.revCount) + mkInt(*state.allocAttr(vAttrs, state.symbols.create("revCount")), *sourceInfo.info.revCount); - if (sourceInfo.lastModified) + if (sourceInfo.info.lastModified) mkString(*state.allocAttr(vAttrs, state.symbols.create("lastModified")), - fmt("%s", std::put_time(std::gmtime(&*sourceInfo.lastModified), "%Y%m%d%H%M%S"))); + fmt("%s", std::put_time(std::gmtime(&*sourceInfo.info.lastModified), "%Y%m%d%H%M%S"))); } struct LazyInput @@ -604,7 +604,7 @@ static void prim_callFlake(EvalState & state, const Pos & pos, Value * * args, V if (lazyInput->isFlake) { auto flake = getFlake(state, lazyInput->lockedInput.ref, false); - if (flake.sourceInfo->narHash != lazyInput->lockedInput.narHash) + if (flake.sourceInfo->info.narHash != lazyInput->lockedInput.narHash) throw Error("the content hash of flake '%s' doesn't match the hash recorded in the referring lockfile", lazyInput->lockedInput.ref); @@ -615,7 +615,7 @@ static void prim_callFlake(EvalState & state, const Pos & pos, Value * * args, V FlakeCache flakeCache; auto [sourceInfo, resolvedRef] = getNonFlake(state, lazyInput->lockedInput.ref, false, flakeCache); - if (sourceInfo.narHash != lazyInput->lockedInput.narHash) + if (sourceInfo.info.narHash != lazyInput->lockedInput.narHash) throw Error("the content hash of repository '%s' doesn't match the hash recorded in the referring lockfile", lazyInput->lockedInput.ref); @@ -718,8 +718,8 @@ Fingerprint LockedFlake::getFingerprint() const return hashString(htSHA256, fmt("%s;%d;%d;%s", flake.sourceInfo->storePath.to_string(), - flake.sourceInfo->revCount.value_or(0), - flake.sourceInfo->lastModified.value_or(0), + flake.sourceInfo->info.revCount.value_or(0), + flake.sourceInfo->info.lastModified.value_or(0), lockFile)); } diff --git a/src/libexpr/primops/fetchGit.cc b/src/libexpr/primops/fetchGit.cc index 448beaa1f..2e24a79f7 100644 --- a/src/libexpr/primops/fetchGit.cc +++ b/src/libexpr/primops/fetchGit.cc @@ -64,11 +64,11 @@ static void prim_fetchGit(EvalState & state, const Pos & pos, Value * * args, Va mkString(*state.allocAttr(v, state.sOutPath), storePath, PathSet({storePath})); // Backward compatibility: set 'rev' to // 0000000000000000000000000000000000000000 for a dirty tree. - auto rev2 = tree.rev.value_or(Hash(htSHA1)); + auto rev2 = tree.info.rev.value_or(Hash(htSHA1)); mkString(*state.allocAttr(v, state.symbols.create("rev")), rev2.gitRev()); mkString(*state.allocAttr(v, state.symbols.create("shortRev")), rev2.gitShortRev()); - assert(tree.revCount); - mkInt(*state.allocAttr(v, state.symbols.create("revCount")), *tree.revCount); + assert(tree.info.revCount); + mkInt(*state.allocAttr(v, state.symbols.create("revCount")), *tree.info.revCount); v.attrs->sort(); if (state.allowedPaths) diff --git a/src/libexpr/primops/fetchMercurial.cc b/src/libexpr/primops/fetchMercurial.cc index 8a22963ef..fea46e7c5 100644 --- a/src/libexpr/primops/fetchMercurial.cc +++ b/src/libexpr/primops/fetchMercurial.cc @@ -73,11 +73,11 @@ static void prim_fetchMercurial(EvalState & state, const Pos & pos, Value * * ar mkString(*state.allocAttr(v, state.symbols.create("branch")), *input2->getRef()); // Backward compatibility: set 'rev' to // 0000000000000000000000000000000000000000 for a dirty tree. - auto rev2 = tree.rev.value_or(Hash(htSHA1)); + auto rev2 = tree.info.rev.value_or(Hash(htSHA1)); mkString(*state.allocAttr(v, state.symbols.create("rev")), rev2.gitRev()); mkString(*state.allocAttr(v, state.symbols.create("shortRev")), std::string(rev2.gitRev(), 0, 12)); - if (tree.revCount) - mkInt(*state.allocAttr(v, state.symbols.create("revCount")), *tree.revCount); + if (tree.info.revCount) + mkInt(*state.allocAttr(v, state.symbols.create("revCount")), *tree.info.revCount); v.attrs->sort(); if (state.allowedPaths) diff --git a/src/libstore/fetchers/fetchers.cc b/src/libstore/fetchers/fetchers.cc index 16f674401..256ef66f2 100644 --- a/src/libstore/fetchers/fetchers.cc +++ b/src/libstore/fetchers/fetchers.cc @@ -83,11 +83,11 @@ std::pair> Input::fetchTree(ref store) if (tree.actualPath == "") tree.actualPath = store->toRealPath(store->printStorePath(tree.storePath)); - if (!tree.narHash) - tree.narHash = store->queryPathInfo(tree.storePath)->narHash; + if (!tree.info.narHash) + tree.info.narHash = store->queryPathInfo(tree.storePath)->narHash; if (input->narHash) - assert(input->narHash == tree.narHash); + assert(input->narHash == tree.info.narHash); if (narHash && narHash != input->narHash) throw Error("NAR hash mismatch in input '%s', expected '%s', got '%s'", diff --git a/src/libstore/fetchers/fetchers.hh b/src/libstore/fetchers/fetchers.hh index 39e004240..7a7ce7d37 100644 --- a/src/libstore/fetchers/fetchers.hh +++ b/src/libstore/fetchers/fetchers.hh @@ -3,6 +3,7 @@ #include "types.hh" #include "hash.hh" #include "path.hh" +#include "tree-info.hh" #include #include @@ -19,10 +20,7 @@ struct Tree { Path actualPath; StorePath storePath; - Hash narHash; - std::optional rev; - std::optional revCount; - std::optional lastModified; + TreeInfo info; }; struct Input : std::enable_shared_from_this diff --git a/src/libstore/fetchers/git.cc b/src/libstore/fetchers/git.cc index 5d0448777..4ad0f6f34 100644 --- a/src/libstore/fetchers/git.cc +++ b/src/libstore/fetchers/git.cc @@ -28,11 +28,11 @@ static void cacheGitInfo(Store & store, const std::string & name, const Tree & t nlohmann::json json; json["storePath"] = store.printStorePath(tree.storePath); json["name"] = name; - json["rev"] = tree.rev->gitRev(); - json["revCount"] = *tree.revCount; - json["lastModified"] = *tree.lastModified; + json["rev"] = tree.info.rev->gitRev(); + json["revCount"] = *tree.info.revCount; + json["lastModified"] = *tree.info.lastModified; - auto cacheInfoPath = getCacheInfoPathFor(name, *tree.rev); + auto cacheInfoPath = getCacheInfoPathFor(name, *tree.info.rev); createDirs(dirOf(cacheInfoPath)); writeFile(cacheInfoPath, json.dump()); } @@ -53,9 +53,11 @@ static std::optional lookupGitInfo( Tree tree{ .actualPath = store->toRealPath(store->printStorePath(storePath)), .storePath = std::move(storePath), - .rev = rev, - .revCount = json["revCount"], - .lastModified = json["lastModified"], + .info = TreeInfo { + .rev = rev, + .revCount = json["revCount"], + .lastModified = json["lastModified"], + } }; return tree; } @@ -237,10 +239,12 @@ struct GitInput : Input auto tree = Tree { .actualPath = store->printStorePath(storePath), .storePath = std::move(storePath), - .revCount = haveCommits ? std::stoull(runProgram("git", true, { "-C", actualUrl, "rev-list", "--count", "HEAD" })) : 0, - // FIXME: maybe we should use the timestamp of the last - // modified dirty file? - .lastModified = haveCommits ? std::stoull(runProgram("git", true, { "-C", actualUrl, "log", "-1", "--format=%ct", "HEAD" })) : 0, + .info = TreeInfo { + .revCount = haveCommits ? std::stoull(runProgram("git", true, { "-C", actualUrl, "rev-list", "--count", "HEAD" })) : 0, + // FIXME: maybe we should use the timestamp of the last + // modified dirty file? + .lastModified = haveCommits ? std::stoull(runProgram("git", true, { "-C", actualUrl, "log", "-1", "--format=%ct", "HEAD" })) : 0, + } }; return {std::move(tree), input}; @@ -349,9 +353,11 @@ struct GitInput : Input auto tree = Tree { .actualPath = store->toRealPath(store->printStorePath(storePath)), .storePath = std::move(storePath), - .rev = input->rev, - .revCount = revCount, - .lastModified = lastModified, + .info = TreeInfo { + .rev = input->rev, + .revCount = revCount, + .lastModified = lastModified + } }; cacheGitInfo(*store, name, tree); diff --git a/src/libstore/fetchers/github.cc b/src/libstore/fetchers/github.cc index c8746b723..a4d39d17d 100644 --- a/src/libstore/fetchers/github.cc +++ b/src/libstore/fetchers/github.cc @@ -113,8 +113,10 @@ struct GitHubInput : Input Tree result{ .actualPath = dresult.path, .storePath = store->parseStorePath(dresult.storePath), - .rev = *rev, - .lastModified = *dresult.lastModified + .info = TreeInfo { + .rev = *rev, + .lastModified = *dresult.lastModified, + }, }; #if 0 diff --git a/src/libstore/fetchers/mercurial.cc b/src/libstore/fetchers/mercurial.cc index 1bdab1dbf..b415b7944 100644 --- a/src/libstore/fetchers/mercurial.cc +++ b/src/libstore/fetchers/mercurial.cc @@ -215,12 +215,17 @@ struct MercurialInput : Input if (store->isValidPath(storePath)) { printTalkative("using cached Mercurial store path '%s'", store->printStorePath(storePath)); - return {Tree { - .actualPath = store->printStorePath(storePath), - .storePath = std::move(storePath), - .rev = input->rev, - .revCount = revCount, - }, input}; + return { + Tree { + .actualPath = store->printStorePath(storePath), + .storePath = std::move(storePath), + .info = TreeInfo { + .rev = input->rev, + .revCount = revCount, + }, + }, + input + }; } } catch (SysError & e) { @@ -246,12 +251,17 @@ struct MercurialInput : Input writeFile(storeLink, json.dump()); - return {Tree { - .actualPath = store->printStorePath(storePath), - .storePath = std::move(storePath), - .rev = input->rev, - .revCount = revCount, - }, input}; + return { + Tree { + .actualPath = store->printStorePath(storePath), + .storePath = std::move(storePath), + .info = TreeInfo { + .rev = input->rev, + .revCount = revCount + } + }, + input + }; } }; diff --git a/src/libstore/fetchers/tarball.cc b/src/libstore/fetchers/tarball.cc index 1302299b3..fc4d7542b 100644 --- a/src/libstore/fetchers/tarball.cc +++ b/src/libstore/fetchers/tarball.cc @@ -72,7 +72,9 @@ struct TarballInput : Input Tree { .actualPath = res.path, .storePath = std::move(storePath), - .lastModified = *res.lastModified + .info = TreeInfo { + .lastModified = *res.lastModified, + }, }, input }; diff --git a/src/libstore/fetchers/tree-info.hh b/src/libstore/fetchers/tree-info.hh new file mode 100644 index 000000000..30d4f3d6b --- /dev/null +++ b/src/libstore/fetchers/tree-info.hh @@ -0,0 +1,13 @@ +#pragma once + +namespace nix { + +struct TreeInfo +{ + Hash narHash; + std::optional rev; + std::optional revCount; + std::optional lastModified; +}; + +} diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc index b379306f6..fa5c84a27 100644 --- a/src/libutil/logging.cc +++ b/src/libutil/logging.cc @@ -21,7 +21,7 @@ Logger * logger = makeDefaultLogger(); void Logger::warn(const std::string & msg) { - log(lvlWarn, ANSI_RED "warning:" ANSI_NORMAL " " + msg); + log(lvlWarn, ANSI_YELLOW "warning:" ANSI_NORMAL " " + msg); } class SimpleLogger : public Logger diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 0aee67008..9a6268346 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -455,6 +455,7 @@ void ignoreException(); #define ANSI_FAINT "\e[2m" #define ANSI_RED "\e[31;1m" #define ANSI_GREEN "\e[32;1m" +#define ANSI_YELLOW "\e[33;1m" #define ANSI_BLUE "\e[34;1m" diff --git a/src/nix/flake.cc b/src/nix/flake.cc index dc576c82d..d3c03e214 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -84,13 +84,13 @@ static void printFlakeInfo(const Store & store, const Flake & flake) if (flake.description) std::cout << fmt("Description: %s\n", *flake.description); std::cout << fmt("Path: %s\n", store.printStorePath(flake.sourceInfo->storePath)); - if (flake.sourceInfo->rev) - std::cout << fmt("Revision: %s\n", flake.sourceInfo->rev->to_string(Base16, false)); - if (flake.sourceInfo->revCount) - std::cout << fmt("Revisions: %s\n", *flake.sourceInfo->revCount); - if (flake.sourceInfo->lastModified) + if (flake.sourceInfo->info.rev) + std::cout << fmt("Revision: %s\n", flake.sourceInfo->info.rev->to_string(Base16, false)); + if (flake.sourceInfo->info.revCount) + std::cout << fmt("Revisions: %s\n", *flake.sourceInfo->info.revCount); + if (flake.sourceInfo->info.lastModified) std::cout << fmt("Last modified: %s\n", - std::put_time(std::localtime(&*flake.sourceInfo->lastModified), "%F %T")); + std::put_time(std::localtime(&*flake.sourceInfo->info.lastModified), "%F %T")); } static nlohmann::json flakeToJson(const Store & store, const Flake & flake) @@ -100,12 +100,12 @@ static nlohmann::json flakeToJson(const Store & store, const Flake & flake) j["description"] = *flake.description; j["edition"] = flake.edition; j["url"] = flake.resolvedRef.input->to_string(); - if (flake.sourceInfo->rev) - j["revision"] = flake.sourceInfo->rev->to_string(Base16, false); - if (flake.sourceInfo->revCount) - j["revCount"] = *flake.sourceInfo->revCount; - if (flake.sourceInfo->lastModified) - j["lastModified"] = *flake.sourceInfo->lastModified; + if (flake.sourceInfo->info.rev) + j["revision"] = flake.sourceInfo->info.rev->to_string(Base16, false); + if (flake.sourceInfo->info.revCount) + j["revCount"] = *flake.sourceInfo->info.revCount; + if (flake.sourceInfo->info.lastModified) + j["lastModified"] = *flake.sourceInfo->info.lastModified; j["path"] = store.printStorePath(flake.sourceInfo->storePath); return j; }