From d15c20efd5fa1744a4d6835365a0b4d3ceb3432c Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 11 Jun 2020 22:00:58 +0200 Subject: [PATCH] diffLockFiles(): Show 'follows' changes --- src/libexpr/flake/lockfile.cc | 40 +++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/src/libexpr/flake/lockfile.cc b/src/libexpr/flake/lockfile.cc index acde0ab7f..fd5a68825 100644 --- a/src/libexpr/flake/lockfile.cc +++ b/src/libexpr/flake/lockfile.cc @@ -242,25 +242,43 @@ static void flattenLockFile( std::shared_ptr node, const InputPath & prefix, std::unordered_set> & done, - std::map> & res) + std::map & res) { if (!done.insert(node).second) return; for (auto &[id, input] : node->inputs) { auto inputPath(prefix); inputPath.push_back(id); - if (auto child = std::get_if<0>(&input)) { - if (auto lockedInput = std::dynamic_pointer_cast(*child)) - res.emplace(inputPath, lockedInput); + res.emplace(inputPath, input); + if (auto child = std::get_if<0>(&input)) flattenLockFile(*child, inputPath, done, res); - } } } +std::ostream & operator <<(std::ostream & stream, const Node::Edge & edge) +{ + if (auto node = std::get_if<0>(&edge)) + stream << "'" << (*node)->lockedRef << "'"; + else if (auto follows = std::get_if<1>(&edge)) + stream << fmt("follows '%s'", printInputPath(*follows)); + return stream; +} + +static bool equals(const Node::Edge & e1, const Node::Edge & e2) +{ + if (auto n1 = std::get_if<0>(&e1)) + if (auto n2 = std::get_if<0>(&e2)) + return (*n1)->lockedRef == (*n2)->lockedRef; + if (auto f1 = std::get_if<1>(&e1)) + if (auto f2 = std::get_if<1>(&e2)) + return *f1 == *f2; + return false; +} + std::string diffLockFiles(const LockFile & oldLocks, const LockFile & newLocks) { std::unordered_set> done; - std::map> oldFlat, newFlat; + std::map oldFlat, newFlat; flattenLockFile(oldLocks.root, {}, done, oldFlat); done.clear(); flattenLockFile(newLocks.root, {}, done, newFlat); @@ -271,17 +289,17 @@ std::string diffLockFiles(const LockFile & oldLocks, const LockFile & newLocks) while (i != oldFlat.end() || j != newFlat.end()) { if (j != newFlat.end() && (i == oldFlat.end() || i->first > j->first)) { - res += fmt("* Added '%s': '%s'\n", printInputPath(j->first), j->second->lockedRef); + res += fmt("* Added '%s': %s\n", printInputPath(j->first), j->second); ++j; } else if (i != oldFlat.end() && (j == newFlat.end() || i->first < j->first)) { res += fmt("* Removed '%s'\n", printInputPath(i->first)); ++i; } else { - if (!(i->second->lockedRef == j->second->lockedRef)) { - res += fmt("* Updated '%s': '%s' -> '%s'\n", + if (!equals(i->second, j->second)) { + res += fmt("* Updated '%s': %s -> %s\n", printInputPath(i->first), - i->second->lockedRef, - j->second->lockedRef); + i->second, + j->second); } ++i; ++j;