From 6d7efcfaeb715b04986ef5a6b1d8f57de4ba5509 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 28 May 2019 12:58:28 +0200 Subject: [PATCH 01/10] Store SourceInfo in Flake and NonFlake This deduplicates some shared fields. Factoring out the commonality is useful in places like makeFlakeValue(). --- src/libexpr/primops/flake.cc | 21 +++++++++++---------- src/libexpr/primops/flake.hh | 14 +++++--------- src/nix/flake.cc | 24 ++++++++++++------------ src/nix/installables.cc | 2 +- 4 files changed, 29 insertions(+), 32 deletions(-) diff --git a/src/libexpr/primops/flake.cc b/src/libexpr/primops/flake.cc index d82c2389d..a8e3e0859 100644 --- a/src/libexpr/primops/flake.cc +++ b/src/libexpr/primops/flake.cc @@ -368,19 +368,19 @@ Flake getFlake(EvalState & state, const FlakeRef & flakeRef, bool impureIsAllowe // Get the `NonFlake` corresponding to a `FlakeRef`. NonFlake getNonFlake(EvalState & state, const FlakeRef & flakeRef, FlakeAlias alias, bool impureIsAllowed = false) { - SourceInfo sourceInfo = fetchFlake(state, flakeRef, impureIsAllowed); + auto sourceInfo = fetchFlake(state, flakeRef, impureIsAllowed); debug("got non-flake source '%s' with flakeref %s", sourceInfo.storePath, sourceInfo.resolvedRef.to_string()); FlakeRef resolvedRef = sourceInfo.resolvedRef; NonFlake nonFlake(flakeRef, sourceInfo); - state.store->assertStorePath(nonFlake.storePath); + state.store->assertStorePath(nonFlake.sourceInfo.storePath); if (state.allowedPaths) - state.allowedPaths->insert(nonFlake.storePath); + state.allowedPaths->insert(nonFlake.sourceInfo.storePath); - nonFlake.hash = state.store->queryPathInfo(sourceInfo.storePath)->narHash; + nonFlake.hash = state.store->queryPathInfo(nonFlake.sourceInfo.storePath)->narHash; nonFlake.alias = alias; @@ -480,7 +480,7 @@ ResolvedFlake resolveFlake(EvalState & state, const FlakeRef & topRef, HandleLoc if (!recreateLockFile (handleLockFile)) { // If recreateLockFile, start with an empty lockfile - oldLockFile = readLockFile(flake.storePath + "/flake.lock"); // FIXME: symlink attack + oldLockFile = readLockFile(flake.sourceInfo.storePath + "/flake.lock"); // FIXME: symlink attack } LockFile lockFile(oldLockFile); @@ -527,15 +527,16 @@ void callFlake(EvalState & state, const ResolvedFlake & resFlake, Value & v) auto vNonFlake = state.allocAttr(v, nonFlake.alias); state.mkAttrs(*vNonFlake, 4); - state.store->isValidPath(nonFlake.storePath); - mkString(*state.allocAttr(*vNonFlake, state.sOutPath), nonFlake.storePath, {nonFlake.storePath}); + state.store->isValidPath(nonFlake.sourceInfo.storePath); + mkString(*state.allocAttr(*vNonFlake, state.sOutPath), + nonFlake.sourceInfo.storePath, {nonFlake.sourceInfo.storePath}); // FIXME: add rev, shortRev, revCount, ... } mkString(*state.allocAttr(v, state.sDescription), resFlake.flake.description); - auto & path = resFlake.flake.storePath; + auto & path = resFlake.flake.sourceInfo.storePath; state.store->isValidPath(path); mkString(*state.allocAttr(v, state.sOutPath), path, {path}); @@ -546,8 +547,8 @@ void callFlake(EvalState & state, const ResolvedFlake & resFlake, Value & v) resFlake.flake.resolvedRef.rev->gitShortRev()); } - if (resFlake.flake.revCount) - mkInt(*state.allocAttr(v, state.symbols.create("revCount")), *resFlake.flake.revCount); + if (resFlake.flake.sourceInfo.revCount) + mkInt(*state.allocAttr(v, state.symbols.create("revCount")), *resFlake.flake.sourceInfo.revCount); auto vProvides = state.allocAttr(v, state.symbols.create("provides")); mkApp(*vProvides, *resFlake.flake.vProvides, v); diff --git a/src/libexpr/primops/flake.hh b/src/libexpr/primops/flake.hh index f85e62e7f..46489c085 100644 --- a/src/libexpr/primops/flake.hh +++ b/src/libexpr/primops/flake.hh @@ -94,17 +94,15 @@ struct Flake FlakeRef originalRef; FlakeRef resolvedRef; std::string description; - std::optional revCount; - Path storePath; + SourceInfo sourceInfo; Hash hash; // content hash std::vector requires; std::map nonFlakeRequires; Value * vProvides; // FIXME: gc - // date unsigned int epoch; Flake(const FlakeRef & origRef, const SourceInfo & sourceInfo) : originalRef(origRef), - resolvedRef(sourceInfo.resolvedRef), revCount(sourceInfo.revCount), storePath(sourceInfo.storePath) {}; + resolvedRef(sourceInfo.resolvedRef), sourceInfo(sourceInfo) {}; }; struct NonFlake @@ -112,12 +110,10 @@ struct NonFlake FlakeAlias alias; FlakeRef originalRef; FlakeRef resolvedRef; - std::optional revCount; + SourceInfo sourceInfo; Hash hash; - Path storePath; - // date - NonFlake(const FlakeRef & origRef, const SourceInfo & sourceInfo) : originalRef(origRef), - resolvedRef(sourceInfo.resolvedRef), revCount(sourceInfo.revCount), storePath(sourceInfo.storePath) {}; + NonFlake(const FlakeRef & origRef, const SourceInfo & sourceInfo) : + originalRef(origRef), resolvedRef(sourceInfo.resolvedRef), sourceInfo(sourceInfo) {}; }; Flake getFlake(EvalState &, const FlakeRef &, bool impureIsAllowed); diff --git a/src/nix/flake.cc b/src/nix/flake.cc index 912b154c1..71a6c16d9 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -80,9 +80,9 @@ void printFlakeInfo(const Flake & flake, bool json) { j["branch"] = *flake.resolvedRef.ref; if (flake.resolvedRef.rev) j["revision"] = flake.resolvedRef.rev->to_string(Base16, false); - if (flake.revCount) - j["revCount"] = *flake.revCount; - j["path"] = flake.storePath; + if (flake.sourceInfo.revCount) + j["revCount"] = *flake.sourceInfo.revCount; + j["path"] = flake.sourceInfo.storePath; j["epoch"] = flake.epoch; std::cout << j.dump(4) << std::endl; } else { @@ -93,9 +93,9 @@ void printFlakeInfo(const Flake & flake, bool json) { std::cout << "Branch: " << *flake.resolvedRef.ref << "\n"; if (flake.resolvedRef.rev) std::cout << "Revision: " << flake.resolvedRef.rev->to_string(Base16, false) << "\n"; - if (flake.revCount) - std::cout << "Revcount: " << *flake.revCount << "\n"; - std::cout << "Path: " << flake.storePath << "\n"; + if (flake.sourceInfo.revCount) + std::cout << "Revcount: " << *flake.sourceInfo.revCount << "\n"; + std::cout << "Path: " << flake.sourceInfo.storePath << "\n"; std::cout << "Epoch: " << flake.epoch << "\n"; } } @@ -109,9 +109,9 @@ void printNonFlakeInfo(const NonFlake & nonFlake, bool json) { j["branch"] = *nonFlake.resolvedRef.ref; if (nonFlake.resolvedRef.rev) j["revision"] = nonFlake.resolvedRef.rev->to_string(Base16, false); - if (nonFlake.revCount) - j["revCount"] = *nonFlake.revCount; - j["path"] = nonFlake.storePath; + if (nonFlake.sourceInfo.revCount) + j["revCount"] = *nonFlake.sourceInfo.revCount; + j["path"] = nonFlake.sourceInfo.storePath; std::cout << j.dump(4) << std::endl; } else { std::cout << "ID: " << nonFlake.alias << "\n"; @@ -120,9 +120,9 @@ void printNonFlakeInfo(const NonFlake & nonFlake, bool json) { std::cout << "Branch: " << *nonFlake.resolvedRef.ref; if (nonFlake.resolvedRef.rev) std::cout << "Revision: " << nonFlake.resolvedRef.rev->to_string(Base16, false) << "\n"; - if (nonFlake.revCount) - std::cout << "Revcount: " << *nonFlake.revCount << "\n"; - std::cout << "Path: " << nonFlake.storePath << "\n"; + if (nonFlake.sourceInfo.revCount) + std::cout << "Revcount: " << *nonFlake.sourceInfo.revCount << "\n"; + std::cout << "Path: " << nonFlake.sourceInfo.storePath << "\n"; } } diff --git a/src/nix/installables.cc b/src/nix/installables.cc index 6cab06240..ce09a43d0 100644 --- a/src/nix/installables.cc +++ b/src/nix/installables.cc @@ -177,7 +177,7 @@ void makeFlakeClosureGCRoot(Store & store, const FlakeRef & origFlakeRef, const const ResolvedFlake & flake = queue.front(); queue.pop(); if (!std::get_if(&flake.flake.resolvedRef.data)) - closure.insert(flake.flake.storePath); + closure.insert(flake.flake.sourceInfo.storePath); for (const auto & dep : flake.flakeDeps) queue.push(dep.second); } From 894e0074453d58eb3e1902c3de3d483538e2a026 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 28 May 2019 13:07:15 +0200 Subject: [PATCH 02/10] Move hash into SourceInfo and rename to narHash to avoid ambiguity --- src/libexpr/primops/flake.cc | 14 +++++++------- src/libexpr/primops/flake.hh | 4 +--- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/libexpr/primops/flake.cc b/src/libexpr/primops/flake.cc index a8e3e0859..ff3cd8184 100644 --- a/src/libexpr/primops/flake.cc +++ b/src/libexpr/primops/flake.cc @@ -263,6 +263,7 @@ static SourceInfo fetchFlake(EvalState & state, const FlakeRef & flakeRef, bool ref.rev = Hash(std::string(*result.etag, 1, result.etag->size() - 2), htSHA1); SourceInfo info(ref); info.storePath = result.storePath; + info.narHash = state.store->queryPathInfo(info.storePath)->narHash; return info; } @@ -276,6 +277,7 @@ static SourceInfo fetchFlake(EvalState & state, const FlakeRef & flakeRef, bool SourceInfo info(ref); info.storePath = gitInfo.storePath; info.revCount = gitInfo.revCount; + info.narHash = state.store->queryPathInfo(info.storePath)->narHash; return info; } @@ -289,6 +291,7 @@ static SourceInfo fetchFlake(EvalState & state, const FlakeRef & flakeRef, bool SourceInfo info(ref); info.storePath = gitInfo.storePath; info.revCount = gitInfo.revCount; + info.narHash = state.store->queryPathInfo(info.storePath)->narHash; return info; } @@ -315,7 +318,6 @@ Flake getFlake(EvalState & state, const FlakeRef & flakeRef, bool impureIsAllowe throw Error("'flake.nix' file of flake '%s' escapes from '%s'", resolvedRef, sourceInfo.storePath); Flake flake(flakeRef, sourceInfo); - flake.hash = state.store->queryPathInfo(sourceInfo.storePath)->narHash; if (!pathExists(realFlakeFile)) throw Error("source tree referenced by '%s' does not contain a '%s/flake.nix' file", resolvedRef, resolvedRef.subdir); @@ -380,8 +382,6 @@ NonFlake getNonFlake(EvalState & state, const FlakeRef & flakeRef, FlakeAlias al if (state.allowedPaths) state.allowedPaths->insert(nonFlake.sourceInfo.storePath); - nonFlake.hash = state.store->queryPathInfo(nonFlake.sourceInfo.storePath)->narHash; - nonFlake.alias = alias; return nonFlake; @@ -397,13 +397,13 @@ LockFile entryToLockFile(const LockFile::FlakeEntry & entry) LockFile::FlakeEntry dependenciesToFlakeEntry(const ResolvedFlake & resolvedFlake) { - LockFile::FlakeEntry entry(resolvedFlake.flake.resolvedRef, resolvedFlake.flake.hash); + LockFile::FlakeEntry entry(resolvedFlake.flake.resolvedRef, resolvedFlake.flake.sourceInfo.narHash); for (auto & info : resolvedFlake.flakeDeps) entry.flakeEntries.insert_or_assign(info.first.to_string(), dependenciesToFlakeEntry(info.second)); for (auto & nonFlake : resolvedFlake.nonFlakeDeps) { - LockFile::NonFlakeEntry nonEntry(nonFlake.resolvedRef, nonFlake.hash); + LockFile::NonFlakeEntry nonEntry(nonFlake.resolvedRef, nonFlake.sourceInfo.narHash); entry.nonFlakeEntries.insert_or_assign(nonFlake.alias, nonEntry); } @@ -443,7 +443,7 @@ ResolvedFlake resolveFlakeFromLockFile(EvalState & state, const FlakeRef & flake auto i = lockFile.nonFlakeEntries.find(nonFlakeInfo.first); if (i != lockFile.nonFlakeEntries.end()) { NonFlake nonFlake = getNonFlake(state, i->second.ref, nonFlakeInfo.first); - if (nonFlake.hash != i->second.contentHash) + if (nonFlake.sourceInfo.narHash != i->second.contentHash) throw Error("the content hash of flakeref '%s' doesn't match", i->second.ref.to_string()); deps.nonFlakeDeps.push_back(nonFlake); } else { @@ -457,7 +457,7 @@ ResolvedFlake resolveFlakeFromLockFile(EvalState & state, const FlakeRef & flake auto i = lockFile.flakeEntries.find(newFlakeRef); if (i != lockFile.flakeEntries.end()) { // Propagate lockFile downwards if possible ResolvedFlake newResFlake = resolveFlakeFromLockFile(state, i->second.ref, handleLockFile, entryToLockFile(i->second)); - if (newResFlake.flake.hash != i->second.contentHash) + if (newResFlake.flake.sourceInfo.narHash != i->second.contentHash) throw Error("the content hash of flakeref '%s' doesn't match", i->second.ref.to_string()); deps.flakeDeps.insert_or_assign(newFlakeRef, newResFlake); } else { diff --git a/src/libexpr/primops/flake.hh b/src/libexpr/primops/flake.hh index 46489c085..760d66057 100644 --- a/src/libexpr/primops/flake.hh +++ b/src/libexpr/primops/flake.hh @@ -84,7 +84,7 @@ struct SourceInfo FlakeRef resolvedRef; Path storePath; std::optional revCount; - // date + Hash narHash; // store path hash SourceInfo(const FlakeRef & resolvRef) : resolvedRef(resolvRef) {}; }; @@ -95,7 +95,6 @@ struct Flake FlakeRef resolvedRef; std::string description; SourceInfo sourceInfo; - Hash hash; // content hash std::vector requires; std::map nonFlakeRequires; Value * vProvides; // FIXME: gc @@ -111,7 +110,6 @@ struct NonFlake FlakeRef originalRef; FlakeRef resolvedRef; SourceInfo sourceInfo; - Hash hash; NonFlake(const FlakeRef & origRef, const SourceInfo & sourceInfo) : originalRef(origRef), resolvedRef(sourceInfo.resolvedRef), sourceInfo(sourceInfo) {}; }; From 48463045415d6099b01e360d27f3cdd1053c9ed0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 28 May 2019 13:08:40 +0200 Subject: [PATCH 03/10] Rename contentHash -> narHash for consistency --- src/libexpr/primops/flake.cc | 10 +++++----- src/libexpr/primops/flake.hh | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/libexpr/primops/flake.cc b/src/libexpr/primops/flake.cc index ff3cd8184..d04f665a8 100644 --- a/src/libexpr/primops/flake.cc +++ b/src/libexpr/primops/flake.cc @@ -105,10 +105,10 @@ nlohmann::json flakeEntryToJson(const LockFile::FlakeEntry & entry) { nlohmann::json json; json["uri"] = entry.ref.to_string(); - json["contentHash"] = entry.contentHash.to_string(SRI); + json["contentHash"] = entry.narHash.to_string(SRI); for (auto & x : entry.nonFlakeEntries) { json["nonFlakeRequires"][x.first]["uri"] = x.second.ref.to_string(); - json["nonFlakeRequires"][x.first]["contentHash"] = x.second.contentHash.to_string(SRI); + json["nonFlakeRequires"][x.first]["contentHash"] = x.second.narHash.to_string(SRI); } for (auto & x : entry.flakeEntries) json["requires"][x.first.to_string()] = flakeEntryToJson(x.second); @@ -122,7 +122,7 @@ void writeLockFile(const LockFile & lockFile, const Path & path) json["nonFlakeRequires"] = nlohmann::json::object(); for (auto & x : lockFile.nonFlakeEntries) { json["nonFlakeRequires"][x.first]["uri"] = x.second.ref.to_string(); - json["nonFlakeRequires"][x.first]["contentHash"] = x.second.contentHash.to_string(SRI); + json["nonFlakeRequires"][x.first]["contentHash"] = x.second.narHash.to_string(SRI); } json["requires"] = nlohmann::json::object(); for (auto & x : lockFile.flakeEntries) @@ -443,7 +443,7 @@ ResolvedFlake resolveFlakeFromLockFile(EvalState & state, const FlakeRef & flake auto i = lockFile.nonFlakeEntries.find(nonFlakeInfo.first); if (i != lockFile.nonFlakeEntries.end()) { NonFlake nonFlake = getNonFlake(state, i->second.ref, nonFlakeInfo.first); - if (nonFlake.sourceInfo.narHash != i->second.contentHash) + if (nonFlake.sourceInfo.narHash != i->second.narHash) throw Error("the content hash of flakeref '%s' doesn't match", i->second.ref.to_string()); deps.nonFlakeDeps.push_back(nonFlake); } else { @@ -457,7 +457,7 @@ ResolvedFlake resolveFlakeFromLockFile(EvalState & state, const FlakeRef & flake auto i = lockFile.flakeEntries.find(newFlakeRef); if (i != lockFile.flakeEntries.end()) { // Propagate lockFile downwards if possible ResolvedFlake newResFlake = resolveFlakeFromLockFile(state, i->second.ref, handleLockFile, entryToLockFile(i->second)); - if (newResFlake.flake.sourceInfo.narHash != i->second.contentHash) + if (newResFlake.flake.sourceInfo.narHash != i->second.narHash) throw Error("the content hash of flakeref '%s' doesn't match", i->second.ref.to_string()); deps.flakeDeps.insert_or_assign(newFlakeRef, newResFlake); } else { diff --git a/src/libexpr/primops/flake.hh b/src/libexpr/primops/flake.hh index 760d66057..d90404ae6 100644 --- a/src/libexpr/primops/flake.hh +++ b/src/libexpr/primops/flake.hh @@ -22,28 +22,28 @@ struct LockFile struct NonFlakeEntry { FlakeRef ref; - Hash contentHash; - NonFlakeEntry(const FlakeRef & flakeRef, const Hash & hash) : ref(flakeRef), contentHash(hash) {}; + Hash narHash; + NonFlakeEntry(const FlakeRef & flakeRef, const Hash & hash) : ref(flakeRef), narHash(hash) {}; bool operator ==(const NonFlakeEntry & other) const { - return ref == other.ref && contentHash == other.contentHash; + return ref == other.ref && narHash == other.narHash; } }; struct FlakeEntry { FlakeRef ref; - Hash contentHash; + Hash narHash; std::map flakeEntries; std::map nonFlakeEntries; - FlakeEntry(const FlakeRef & flakeRef, const Hash & hash) : ref(flakeRef), contentHash(hash) {}; + FlakeEntry(const FlakeRef & flakeRef, const Hash & hash) : ref(flakeRef), narHash(hash) {}; bool operator ==(const FlakeEntry & other) const { return ref == other.ref - && contentHash == other.contentHash + && narHash == other.narHash && flakeEntries == other.flakeEntries && nonFlakeEntries == other.nonFlakeEntries; } From dda4f7167b9a421f1bb85ee5eed79a1bf03a13e4 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 28 May 2019 13:12:43 +0200 Subject: [PATCH 04/10] Remove redundant resolvedRef fields since they're already in SourceInfo --- src/libexpr/primops/flake.cc | 14 ++++++++---- src/libexpr/primops/flake.hh | 10 ++++---- src/nix/flake.cc | 44 ++++++++++++++++++------------------ src/nix/installables.cc | 2 +- 4 files changed, 36 insertions(+), 34 deletions(-) diff --git a/src/libexpr/primops/flake.cc b/src/libexpr/primops/flake.cc index d04f665a8..4de742862 100644 --- a/src/libexpr/primops/flake.cc +++ b/src/libexpr/primops/flake.cc @@ -397,13 +397,17 @@ LockFile entryToLockFile(const LockFile::FlakeEntry & entry) LockFile::FlakeEntry dependenciesToFlakeEntry(const ResolvedFlake & resolvedFlake) { - LockFile::FlakeEntry entry(resolvedFlake.flake.resolvedRef, resolvedFlake.flake.sourceInfo.narHash); + LockFile::FlakeEntry entry( + resolvedFlake.flake.sourceInfo.resolvedRef, + resolvedFlake.flake.sourceInfo.narHash); for (auto & info : resolvedFlake.flakeDeps) entry.flakeEntries.insert_or_assign(info.first.to_string(), dependenciesToFlakeEntry(info.second)); for (auto & nonFlake : resolvedFlake.nonFlakeDeps) { - LockFile::NonFlakeEntry nonEntry(nonFlake.resolvedRef, nonFlake.sourceInfo.narHash); + LockFile::NonFlakeEntry nonEntry( + nonFlake.sourceInfo.resolvedRef, + nonFlake.sourceInfo.narHash); entry.nonFlakeEntries.insert_or_assign(nonFlake.alias, nonEntry); } @@ -540,11 +544,11 @@ void callFlake(EvalState & state, const ResolvedFlake & resFlake, Value & v) state.store->isValidPath(path); mkString(*state.allocAttr(v, state.sOutPath), path, {path}); - if (resFlake.flake.resolvedRef.rev) { + if (resFlake.flake.sourceInfo.resolvedRef.rev) { mkString(*state.allocAttr(v, state.symbols.create("rev")), - resFlake.flake.resolvedRef.rev->gitRev()); + resFlake.flake.sourceInfo.resolvedRef.rev->gitRev()); mkString(*state.allocAttr(v, state.symbols.create("shortRev")), - resFlake.flake.resolvedRef.rev->gitShortRev()); + resFlake.flake.sourceInfo.resolvedRef.rev->gitShortRev()); } if (resFlake.flake.sourceInfo.revCount) diff --git a/src/libexpr/primops/flake.hh b/src/libexpr/primops/flake.hh index d90404ae6..a26103736 100644 --- a/src/libexpr/primops/flake.hh +++ b/src/libexpr/primops/flake.hh @@ -92,7 +92,6 @@ struct Flake { FlakeId id; FlakeRef originalRef; - FlakeRef resolvedRef; std::string description; SourceInfo sourceInfo; std::vector requires; @@ -100,18 +99,17 @@ struct Flake Value * vProvides; // FIXME: gc unsigned int epoch; - Flake(const FlakeRef & origRef, const SourceInfo & sourceInfo) : originalRef(origRef), - resolvedRef(sourceInfo.resolvedRef), sourceInfo(sourceInfo) {}; + Flake(const FlakeRef & origRef, const SourceInfo & sourceInfo) + : originalRef(origRef), sourceInfo(sourceInfo) {}; }; struct NonFlake { FlakeAlias alias; FlakeRef originalRef; - FlakeRef resolvedRef; SourceInfo sourceInfo; - NonFlake(const FlakeRef & origRef, const SourceInfo & sourceInfo) : - originalRef(origRef), resolvedRef(sourceInfo.resolvedRef), sourceInfo(sourceInfo) {}; + NonFlake(const FlakeRef & origRef, const SourceInfo & sourceInfo) + : originalRef(origRef), sourceInfo(sourceInfo) {}; }; Flake getFlake(EvalState &, const FlakeRef &, bool impureIsAllowed); diff --git a/src/nix/flake.cc b/src/nix/flake.cc index 71a6c16d9..ce5ce8742 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -74,12 +74,12 @@ void printFlakeInfo(const Flake & flake, bool json) { if (json) { nlohmann::json j; j["id"] = flake.id; - j["uri"] = flake.resolvedRef.to_string(); + j["uri"] = flake.sourceInfo.resolvedRef.to_string(); j["description"] = flake.description; - if (flake.resolvedRef.ref) - j["branch"] = *flake.resolvedRef.ref; - if (flake.resolvedRef.rev) - j["revision"] = flake.resolvedRef.rev->to_string(Base16, false); + if (flake.sourceInfo.resolvedRef.ref) + j["branch"] = *flake.sourceInfo.resolvedRef.ref; + if (flake.sourceInfo.resolvedRef.rev) + j["revision"] = flake.sourceInfo.resolvedRef.rev->to_string(Base16, false); if (flake.sourceInfo.revCount) j["revCount"] = *flake.sourceInfo.revCount; j["path"] = flake.sourceInfo.storePath; @@ -87,12 +87,12 @@ void printFlakeInfo(const Flake & flake, bool json) { std::cout << j.dump(4) << std::endl; } else { std::cout << "ID: " << flake.id << "\n"; - std::cout << "URI: " << flake.resolvedRef.to_string() << "\n"; + std::cout << "URI: " << flake.sourceInfo.resolvedRef.to_string() << "\n"; std::cout << "Description: " << flake.description << "\n"; - if (flake.resolvedRef.ref) - std::cout << "Branch: " << *flake.resolvedRef.ref << "\n"; - if (flake.resolvedRef.rev) - std::cout << "Revision: " << flake.resolvedRef.rev->to_string(Base16, false) << "\n"; + if (flake.sourceInfo.resolvedRef.ref) + std::cout << "Branch: " << *flake.sourceInfo.resolvedRef.ref << "\n"; + if (flake.sourceInfo.resolvedRef.rev) + std::cout << "Revision: " << flake.sourceInfo.resolvedRef.rev->to_string(Base16, false) << "\n"; if (flake.sourceInfo.revCount) std::cout << "Revcount: " << *flake.sourceInfo.revCount << "\n"; std::cout << "Path: " << flake.sourceInfo.storePath << "\n"; @@ -104,22 +104,22 @@ void printNonFlakeInfo(const NonFlake & nonFlake, bool json) { if (json) { nlohmann::json j; j["id"] = nonFlake.alias; - j["uri"] = nonFlake.resolvedRef.to_string(); - if (nonFlake.resolvedRef.ref) - j["branch"] = *nonFlake.resolvedRef.ref; - if (nonFlake.resolvedRef.rev) - j["revision"] = nonFlake.resolvedRef.rev->to_string(Base16, false); + j["uri"] = nonFlake.sourceInfo.resolvedRef.to_string(); + if (nonFlake.sourceInfo.resolvedRef.ref) + j["branch"] = *nonFlake.sourceInfo.resolvedRef.ref; + if (nonFlake.sourceInfo.resolvedRef.rev) + j["revision"] = nonFlake.sourceInfo.resolvedRef.rev->to_string(Base16, false); if (nonFlake.sourceInfo.revCount) j["revCount"] = *nonFlake.sourceInfo.revCount; j["path"] = nonFlake.sourceInfo.storePath; std::cout << j.dump(4) << std::endl; } else { std::cout << "ID: " << nonFlake.alias << "\n"; - std::cout << "URI: " << nonFlake.resolvedRef.to_string() << "\n"; - if (nonFlake.resolvedRef.ref) - std::cout << "Branch: " << *nonFlake.resolvedRef.ref; - if (nonFlake.resolvedRef.rev) - std::cout << "Revision: " << nonFlake.resolvedRef.rev->to_string(Base16, false) << "\n"; + std::cout << "URI: " << nonFlake.sourceInfo.resolvedRef.to_string() << "\n"; + if (nonFlake.sourceInfo.resolvedRef.ref) + std::cout << "Branch: " << *nonFlake.sourceInfo.resolvedRef.ref; + if (nonFlake.sourceInfo.resolvedRef.rev) + std::cout << "Revision: " << nonFlake.sourceInfo.resolvedRef.rev->to_string(Base16, false) << "\n"; if (nonFlake.sourceInfo.revCount) std::cout << "Revcount: " << *nonFlake.sourceInfo.revCount << "\n"; std::cout << "Path: " << nonFlake.sourceInfo.storePath << "\n"; @@ -295,13 +295,13 @@ struct CmdFlakePin : virtual Args, EvalCommand FlakeRegistry userRegistry = *readRegistry(userRegistryPath); auto it = userRegistry.entries.find(FlakeRef(alias)); if (it != userRegistry.entries.end()) { - it->second = getFlake(*evalState, it->second, true).resolvedRef; + it->second = getFlake(*evalState, it->second, true).sourceInfo.resolvedRef; writeRegistry(userRegistry, userRegistryPath); } else { std::shared_ptr globalReg = evalState->getGlobalFlakeRegistry(); it = globalReg->entries.find(FlakeRef(alias)); if (it != globalReg->entries.end()) { - FlakeRef newRef = getFlake(*evalState, it->second, true).resolvedRef; + auto newRef = getFlake(*evalState, it->second, true).sourceInfo.resolvedRef; userRegistry.entries.insert_or_assign(alias, newRef); writeRegistry(userRegistry, userRegistryPath); } else diff --git a/src/nix/installables.cc b/src/nix/installables.cc index ce09a43d0..4f9161666 100644 --- a/src/nix/installables.cc +++ b/src/nix/installables.cc @@ -176,7 +176,7 @@ void makeFlakeClosureGCRoot(Store & store, const FlakeRef & origFlakeRef, const while (!queue.empty()) { const ResolvedFlake & flake = queue.front(); queue.pop(); - if (!std::get_if(&flake.flake.resolvedRef.data)) + if (!std::get_if(&flake.flake.sourceInfo.resolvedRef.data)) closure.insert(flake.flake.sourceInfo.storePath); for (const auto & dep : flake.flakeDeps) queue.push(dep.second); From 25e497bf9c3a848afbd7463f132c9229d8a44284 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 28 May 2019 13:14:27 +0200 Subject: [PATCH 05/10] nix flake info/deps: Stop progress bar before printing output --- src/nix/flake.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/nix/flake.cc b/src/nix/flake.cc index ce5ce8742..66fa11e47 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -147,6 +147,8 @@ struct CmdFlakeDeps : FlakeCommand, MixJSON std::queue todo; todo.push(resolveFlake()); + stopProgressBar(); + while (!todo.empty()) { auto resFlake = std::move(todo.front()); todo.pop(); @@ -204,6 +206,7 @@ struct CmdFlakeInfo : FlakeCommand, MixJSON void run(nix::ref store) override { auto flake = getFlake(); + stopProgressBar(); printFlakeInfo(flake, json); } }; From fdf06ce72f9695f57f6215683e4b2e1c6ec463cf Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 28 May 2019 13:21:06 +0200 Subject: [PATCH 06/10] printFlakeInfo/printNonFlakeInfo: Factor out commonality --- src/nix/flake.cc | 66 +++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/src/nix/flake.cc b/src/nix/flake.cc index 66fa11e47..da19caa5a 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -70,59 +70,57 @@ struct CmdFlakeList : EvalCommand } }; -void printFlakeInfo(const Flake & flake, bool json) { +static void printSourceInfo(const SourceInfo & sourceInfo) +{ + std::cout << "URI: " << sourceInfo.resolvedRef.to_string() << "\n"; + if (sourceInfo.resolvedRef.ref) + std::cout << "Branch: " << *sourceInfo.resolvedRef.ref; + if (sourceInfo.resolvedRef.rev) + std::cout << "Revision: " << sourceInfo.resolvedRef.rev->to_string(Base16, false) << "\n"; + if (sourceInfo.revCount) + std::cout << "Revcount: " << *sourceInfo.revCount << "\n"; + std::cout << "Path: " << sourceInfo.storePath << "\n"; +} + +static void sourceInfoToJson(const SourceInfo & sourceInfo, nlohmann::json & j) +{ + j["uri"] = sourceInfo.resolvedRef.to_string(); + if (sourceInfo.resolvedRef.ref) + j["branch"] = *sourceInfo.resolvedRef.ref; + if (sourceInfo.resolvedRef.rev) + j["revision"] = sourceInfo.resolvedRef.rev->to_string(Base16, false); + if (sourceInfo.revCount) + j["revCount"] = *sourceInfo.revCount; + j["path"] = sourceInfo.storePath; +} + +static void printFlakeInfo(const Flake & flake, bool json) +{ if (json) { nlohmann::json j; j["id"] = flake.id; - j["uri"] = flake.sourceInfo.resolvedRef.to_string(); j["description"] = flake.description; - if (flake.sourceInfo.resolvedRef.ref) - j["branch"] = *flake.sourceInfo.resolvedRef.ref; - if (flake.sourceInfo.resolvedRef.rev) - j["revision"] = flake.sourceInfo.resolvedRef.rev->to_string(Base16, false); - if (flake.sourceInfo.revCount) - j["revCount"] = *flake.sourceInfo.revCount; - j["path"] = flake.sourceInfo.storePath; j["epoch"] = flake.epoch; + sourceInfoToJson(flake.sourceInfo, j); std::cout << j.dump(4) << std::endl; } else { std::cout << "ID: " << flake.id << "\n"; - std::cout << "URI: " << flake.sourceInfo.resolvedRef.to_string() << "\n"; std::cout << "Description: " << flake.description << "\n"; - if (flake.sourceInfo.resolvedRef.ref) - std::cout << "Branch: " << *flake.sourceInfo.resolvedRef.ref << "\n"; - if (flake.sourceInfo.resolvedRef.rev) - std::cout << "Revision: " << flake.sourceInfo.resolvedRef.rev->to_string(Base16, false) << "\n"; - if (flake.sourceInfo.revCount) - std::cout << "Revcount: " << *flake.sourceInfo.revCount << "\n"; - std::cout << "Path: " << flake.sourceInfo.storePath << "\n"; std::cout << "Epoch: " << flake.epoch << "\n"; + printSourceInfo(flake.sourceInfo); } } -void printNonFlakeInfo(const NonFlake & nonFlake, bool json) { +static void printNonFlakeInfo(const NonFlake & nonFlake, bool json) +{ if (json) { nlohmann::json j; j["id"] = nonFlake.alias; - j["uri"] = nonFlake.sourceInfo.resolvedRef.to_string(); - if (nonFlake.sourceInfo.resolvedRef.ref) - j["branch"] = *nonFlake.sourceInfo.resolvedRef.ref; - if (nonFlake.sourceInfo.resolvedRef.rev) - j["revision"] = nonFlake.sourceInfo.resolvedRef.rev->to_string(Base16, false); - if (nonFlake.sourceInfo.revCount) - j["revCount"] = *nonFlake.sourceInfo.revCount; - j["path"] = nonFlake.sourceInfo.storePath; + printSourceInfo(nonFlake.sourceInfo); std::cout << j.dump(4) << std::endl; } else { std::cout << "ID: " << nonFlake.alias << "\n"; - std::cout << "URI: " << nonFlake.sourceInfo.resolvedRef.to_string() << "\n"; - if (nonFlake.sourceInfo.resolvedRef.ref) - std::cout << "Branch: " << *nonFlake.sourceInfo.resolvedRef.ref; - if (nonFlake.sourceInfo.resolvedRef.rev) - std::cout << "Revision: " << nonFlake.sourceInfo.resolvedRef.rev->to_string(Base16, false) << "\n"; - if (nonFlake.sourceInfo.revCount) - std::cout << "Revcount: " << *nonFlake.sourceInfo.revCount << "\n"; - std::cout << "Path: " << nonFlake.sourceInfo.storePath << "\n"; + printSourceInfo(nonFlake.sourceInfo); } } From e7e7a03baf446bad34939c106aee4b69f5619fd0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 28 May 2019 13:22:11 +0200 Subject: [PATCH 07/10] nix flake deps: Remove --json flag for now It doesn't produce valid JSON at the moment (but a concatenation of JSON objects). Anyway we probably should merge this command info 'nix flake info'. --- src/nix/flake.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/nix/flake.cc b/src/nix/flake.cc index da19caa5a..810529613 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -125,7 +125,7 @@ static void printNonFlakeInfo(const NonFlake & nonFlake, bool json) } // FIXME: merge info CmdFlakeInfo? -struct CmdFlakeDeps : FlakeCommand, MixJSON +struct CmdFlakeDeps : FlakeCommand { std::string name() override { @@ -152,10 +152,10 @@ struct CmdFlakeDeps : FlakeCommand, MixJSON todo.pop(); for (auto & nonFlake : resFlake.nonFlakeDeps) - printNonFlakeInfo(nonFlake, json); + printNonFlakeInfo(nonFlake, false); for (auto & info : resFlake.flakeDeps) { - printFlakeInfo(info.second.flake, json); + printFlakeInfo(info.second.flake, false); todo.push(info.second); } } From ecee759b80a5a4cefbf15c3670f28bdebb58c404 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 28 May 2019 14:01:08 +0200 Subject: [PATCH 08/10] callFlake(): Emit source info attributes for non-flake dependencies --- src/libexpr/primops/flake.cc | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/libexpr/primops/flake.cc b/src/libexpr/primops/flake.cc index 4de742862..162e5c915 100644 --- a/src/libexpr/primops/flake.cc +++ b/src/libexpr/primops/flake.cc @@ -514,6 +514,23 @@ void updateLockFile(EvalState & state, const FlakeRef & flakeRef, bool recreateL resolveFlake(state, flakeRef, recreateLockFile ? RecreateLockFile : UpdateLockFile); } +static void emitSourceInfoAttrs(EvalState & state, const SourceInfo & sourceInfo, Value & vAttrs) +{ + auto & path = sourceInfo.storePath; + state.store->isValidPath(path); + mkString(*state.allocAttr(vAttrs, state.sOutPath), path, {path}); + + if (sourceInfo.resolvedRef.rev) { + mkString(*state.allocAttr(vAttrs, state.symbols.create("rev")), + sourceInfo.resolvedRef.rev->gitRev()); + mkString(*state.allocAttr(vAttrs, state.symbols.create("shortRev")), + sourceInfo.resolvedRef.rev->gitShortRev()); + } + + if (sourceInfo.revCount) + mkInt(*state.allocAttr(vAttrs, state.symbols.create("revCount")), *sourceInfo.revCount); +} + void callFlake(EvalState & state, const ResolvedFlake & resFlake, Value & v) { // Construct the resulting attrset '{description, provides, @@ -529,30 +546,18 @@ void callFlake(EvalState & state, const ResolvedFlake & resFlake, Value & v) for (const NonFlake nonFlake : resFlake.nonFlakeDeps) { auto vNonFlake = state.allocAttr(v, nonFlake.alias); - state.mkAttrs(*vNonFlake, 4); + state.mkAttrs(*vNonFlake, 8); state.store->isValidPath(nonFlake.sourceInfo.storePath); mkString(*state.allocAttr(*vNonFlake, state.sOutPath), nonFlake.sourceInfo.storePath, {nonFlake.sourceInfo.storePath}); - // FIXME: add rev, shortRev, revCount, ... + emitSourceInfoAttrs(state, nonFlake.sourceInfo, *vNonFlake); } mkString(*state.allocAttr(v, state.sDescription), resFlake.flake.description); - auto & path = resFlake.flake.sourceInfo.storePath; - state.store->isValidPath(path); - mkString(*state.allocAttr(v, state.sOutPath), path, {path}); - - if (resFlake.flake.sourceInfo.resolvedRef.rev) { - mkString(*state.allocAttr(v, state.symbols.create("rev")), - resFlake.flake.sourceInfo.resolvedRef.rev->gitRev()); - mkString(*state.allocAttr(v, state.symbols.create("shortRev")), - resFlake.flake.sourceInfo.resolvedRef.rev->gitShortRev()); - } - - if (resFlake.flake.sourceInfo.revCount) - mkInt(*state.allocAttr(v, state.symbols.create("revCount")), *resFlake.flake.sourceInfo.revCount); + emitSourceInfoAttrs(state, resFlake.flake.sourceInfo, v); auto vProvides = state.allocAttr(v, state.symbols.create("provides")); mkApp(*vProvides, *resFlake.flake.vProvides, v); From 46294d60cd46564ea6b40cf9c32759021f9d1fc9 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 28 May 2019 14:01:57 +0200 Subject: [PATCH 09/10] printFlakeInfo: Separate JSON output --- src/nix/flake.cc | 59 ++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/src/nix/flake.cc b/src/nix/flake.cc index 810529613..0fea1993c 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -94,34 +94,36 @@ static void sourceInfoToJson(const SourceInfo & sourceInfo, nlohmann::json & j) j["path"] = sourceInfo.storePath; } -static void printFlakeInfo(const Flake & flake, bool json) +static void printFlakeInfo(const Flake & flake) { - if (json) { - nlohmann::json j; - j["id"] = flake.id; - j["description"] = flake.description; - j["epoch"] = flake.epoch; - sourceInfoToJson(flake.sourceInfo, j); - std::cout << j.dump(4) << std::endl; - } else { - std::cout << "ID: " << flake.id << "\n"; - std::cout << "Description: " << flake.description << "\n"; - std::cout << "Epoch: " << flake.epoch << "\n"; - printSourceInfo(flake.sourceInfo); - } + std::cout << "ID: " << flake.id << "\n"; + std::cout << "Description: " << flake.description << "\n"; + std::cout << "Epoch: " << flake.epoch << "\n"; + printSourceInfo(flake.sourceInfo); } -static void printNonFlakeInfo(const NonFlake & nonFlake, bool json) +static nlohmann::json flakeToJson(const Flake & flake) { - if (json) { - nlohmann::json j; - j["id"] = nonFlake.alias; - printSourceInfo(nonFlake.sourceInfo); - std::cout << j.dump(4) << std::endl; - } else { - std::cout << "ID: " << nonFlake.alias << "\n"; - printSourceInfo(nonFlake.sourceInfo); - } + nlohmann::json j; + j["id"] = flake.id; + j["description"] = flake.description; + j["epoch"] = flake.epoch; + sourceInfoToJson(flake.sourceInfo, j); + return j; +} + +static void printNonFlakeInfo(const NonFlake & nonFlake) +{ + std::cout << "ID: " << nonFlake.alias << "\n"; + printSourceInfo(nonFlake.sourceInfo); +} + +static nlohmann::json nonFlakeToJson(const NonFlake & nonFlake) +{ + nlohmann::json j; + j["id"] = nonFlake.alias; + sourceInfoToJson(nonFlake.sourceInfo, j); + return j; } // FIXME: merge info CmdFlakeInfo? @@ -152,10 +154,10 @@ struct CmdFlakeDeps : FlakeCommand todo.pop(); for (auto & nonFlake : resFlake.nonFlakeDeps) - printNonFlakeInfo(nonFlake, false); + printNonFlakeInfo(nonFlake); for (auto & info : resFlake.flakeDeps) { - printFlakeInfo(info.second.flake, false); + printFlakeInfo(info.second.flake); todo.push(info.second); } } @@ -205,7 +207,10 @@ struct CmdFlakeInfo : FlakeCommand, MixJSON { auto flake = getFlake(); stopProgressBar(); - printFlakeInfo(flake, json); + if (json) + std::cout << flakeToJson(flake).dump() << std::endl; + else + printFlakeInfo(flake); } }; From 444786e6d39209d3f0c222af0fbc80846ac7337d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 28 May 2019 14:11:19 +0200 Subject: [PATCH 10/10] nix flake info: Add missing newline --- src/nix/flake.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/nix/flake.cc b/src/nix/flake.cc index 0fea1993c..d8c422d3d 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -72,14 +72,14 @@ struct CmdFlakeList : EvalCommand static void printSourceInfo(const SourceInfo & sourceInfo) { - std::cout << "URI: " << sourceInfo.resolvedRef.to_string() << "\n"; + std::cout << fmt("URI: %s\n", sourceInfo.resolvedRef.to_string()); if (sourceInfo.resolvedRef.ref) - std::cout << "Branch: " << *sourceInfo.resolvedRef.ref; + std::cout << fmt("Branch: %s\n",*sourceInfo.resolvedRef.ref); if (sourceInfo.resolvedRef.rev) - std::cout << "Revision: " << sourceInfo.resolvedRef.rev->to_string(Base16, false) << "\n"; + std::cout << fmt("Revision: %s\n", sourceInfo.resolvedRef.rev->to_string(Base16, false)); if (sourceInfo.revCount) - std::cout << "Revcount: " << *sourceInfo.revCount << "\n"; - std::cout << "Path: " << sourceInfo.storePath << "\n"; + std::cout << fmt("Revcount: %s\n", *sourceInfo.revCount); + std::cout << fmt("Path: %s\n", sourceInfo.storePath); } static void sourceInfoToJson(const SourceInfo & sourceInfo, nlohmann::json & j) @@ -96,9 +96,9 @@ static void sourceInfoToJson(const SourceInfo & sourceInfo, nlohmann::json & j) static void printFlakeInfo(const Flake & flake) { - std::cout << "ID: " << flake.id << "\n"; - std::cout << "Description: " << flake.description << "\n"; - std::cout << "Epoch: " << flake.epoch << "\n"; + std::cout << fmt("ID: %s\n", flake.id); + std::cout << fmt("Description: %s\n", flake.description); + std::cout << fmt("Epoch: %s\n", flake.epoch); printSourceInfo(flake.sourceInfo); } @@ -114,7 +114,7 @@ static nlohmann::json flakeToJson(const Flake & flake) static void printNonFlakeInfo(const NonFlake & nonFlake) { - std::cout << "ID: " << nonFlake.alias << "\n"; + std::cout << fmt("ID: %s\n", nonFlake.alias); printSourceInfo(nonFlake.sourceInfo); }