diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2020-03-24 14:17:10 +0100 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2020-03-24 14:26:23 +0100 |
commit | 7a8de57d3e7e53a4f6d8060c7201f3fbbe6cd325 (patch) | |
tree | e418ac74ab2a2dd45e4ea4c8ecb7017d8b76e9b8 /src | |
parent | 4260a22a55d7afc931b22e8c41282fbd0ed18a77 (diff) |
Pretty-print 'nix why-depends' / 'nix-store -q --tree' output
Extracted from 678301072f05b650dc15c5edb4c25f08f0d6cace.
Diffstat (limited to 'src')
-rw-r--r-- | src/libutil/util.hh | 34 | ||||
-rw-r--r-- | src/nix-store/nix-store.cc | 15 | ||||
-rw-r--r-- | src/nix/why-depends.cc | 7 |
3 files changed, 40 insertions, 16 deletions
diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 8c2cef9e1..acef682cd 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -451,6 +451,13 @@ void ignoreException(); #define ANSI_BLUE "\e[34;1m" +/* Tree formatting. */ +constexpr char treeConn[] = "├───"; +constexpr char treeLast[] = "└───"; +constexpr char treeLine[] = "│ "; +constexpr char treeNull[] = " "; + + /* Truncate a string to 'width' printable characters. If 'filterAll' is true, all ANSI escape sequences are filtered out. Otherwise, some escape sequences (such as colour setting) are copied but not @@ -576,4 +583,31 @@ extern PathFilter defaultPathFilter; AutoCloseFD createUnixDomainSocket(const Path & path, mode_t mode); +// A Rust/Python-like enumerate() iterator adapter. +// Borrowed from http://reedbeta.com/blog/python-like-enumerate-in-cpp17. +template <typename T, + typename TIter = decltype(std::begin(std::declval<T>())), + typename = decltype(std::end(std::declval<T>()))> +constexpr auto enumerate(T && iterable) +{ + struct iterator + { + size_t i; + TIter iter; + bool operator != (const iterator & other) const { return iter != other.iter; } + void operator ++ () { ++i; ++iter; } + auto operator * () const { return std::tie(i, *iter); } + }; + + struct iterable_wrapper + { + T iterable; + auto begin() { return iterator{ 0, std::begin(iterable) }; } + auto end() { return iterator{ 0, std::end(iterable) }; } + }; + + return iterable_wrapper{ std::forward<T>(iterable) }; +} + + } diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index c14d900ae..806ab7563 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -229,12 +229,6 @@ static StorePathSet maybeUseOutputs(const StorePath & storePath, bool useOutput, /* Some code to print a tree representation of a derivation dependency graph. Topological sorting is used to keep the tree relatively flat. */ - -const string treeConn = "+---"; -const string treeLine = "| "; -const string treeNull = " "; - - static void printTree(const StorePath & path, const string & firstPad, const string & tailPad, StorePathSet & done) { @@ -254,10 +248,11 @@ static void printTree(const StorePath & path, auto sorted = store->topoSortPaths(info->references); reverse(sorted.begin(), sorted.end()); - for (auto i = sorted.begin(); i != sorted.end(); ++i) { - auto j = i; ++j; - printTree(*i, tailPad + treeConn, - j == sorted.end() ? tailPad + treeNull : tailPad + treeLine, + for (const auto &[n, i] : enumerate(sorted)) { + bool last = n + 1 == sorted.size(); + printTree(i, + tailPad + (last ? treeLast : treeConn), + tailPad + (last ? treeNull : treeLine), done); } } diff --git a/src/nix/why-depends.cc b/src/nix/why-depends.cc index c24ae7c8e..d3b7a674a 100644 --- a/src/nix/why-depends.cc +++ b/src/nix/why-depends.cc @@ -143,11 +143,6 @@ struct CmdWhyDepends : SourceExprCommand and `dependency`. */ std::function<void(Node &, const string &, const string &)> printNode; - const string treeConn = "╠═══"; - const string treeLast = "╚═══"; - const string treeLine = "║ "; - const string treeNull = " "; - struct BailOut { }; printNode = [&](Node & node, const string & firstPad, const string & tailPad) { @@ -157,7 +152,7 @@ struct CmdWhyDepends : SourceExprCommand std::cout << fmt("%s%s%s%s" ANSI_NORMAL "\n", firstPad, node.visited ? "\e[38;5;244m" : "", - firstPad != "" ? "=> " : "", + firstPad != "" ? "→ " : "", pathS); if (node.path == dependencyPath && !all |