diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2020-01-31 14:01:46 +0100 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2020-01-31 14:09:27 +0100 |
commit | 678301072f05b650dc15c5edb4c25f08f0d6cace (patch) | |
tree | 76dc9f3e2adcec62fe4c39cfb417bf1984595f69 /src | |
parent | a6e2b6b36044d7708cf50b464009e50c8d120730 (diff) |
nix flake list-inputs: Pretty-print the tree
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/flake.cc | 17 | ||||
-rw-r--r-- | src/nix/why-depends.cc | 5 |
4 files changed, 50 insertions, 21 deletions
diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 2f1613ac1..5d44b92c3 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -458,6 +458,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 @@ -583,4 +590,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 45e152c47..9336baa83 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/flake.cc b/src/nix/flake.cc index 5450f1fb5..9b23570bd 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -193,22 +193,27 @@ struct CmdFlakeListInputs : FlakeCommand, MixJSON { auto flake = lockFlake(); + stopProgressBar(); + if (json) std::cout << ((LockedInputs &) flake.lockFile).toJson() << "\n"; else { std::cout << fmt("%s\n", flake.flake.resolvedRef); - std::function<void(const LockedInputs & inputs, size_t depth)> recurse; + std::function<void(const LockedInputs & inputs, const std::string & prefix)> recurse; - recurse = [&](const LockedInputs & inputs, size_t depth) + recurse = [&](const LockedInputs & inputs, const std::string & prefix) { - for (auto & input : inputs.inputs) { - std::cout << fmt("%s%s: %s\n", std::string(depth * 2, ' '), input.first, input.second.ref); - recurse(input.second, depth + 1); + for (const auto & [i, input] : enumerate(inputs.inputs)) { + //auto tree2 = tree.child(i + 1 == inputs.inputs.size()); + bool last = i + 1 == inputs.inputs.size(); + std::cout << fmt("%s" ANSI_BOLD "%s" ANSI_NORMAL ": %s\n", + prefix + (last ? treeLast : treeConn), input.first, input.second.ref); + recurse(input.second, prefix + (last ? treeNull : treeLine)); } }; - recurse(flake.lockFile, 1); + recurse(flake.lockFile, ""); } } }; diff --git a/src/nix/why-depends.cc b/src/nix/why-depends.cc index c539adb7f..fb12d5380 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) { |