aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2020-01-31 14:01:46 +0100
committerEelco Dolstra <edolstra@gmail.com>2020-01-31 14:09:27 +0100
commit678301072f05b650dc15c5edb4c25f08f0d6cace (patch)
tree76dc9f3e2adcec62fe4c39cfb417bf1984595f69 /src
parenta6e2b6b36044d7708cf50b464009e50c8d120730 (diff)
nix flake list-inputs: Pretty-print the tree
Diffstat (limited to 'src')
-rw-r--r--src/libutil/util.hh34
-rw-r--r--src/nix-store/nix-store.cc15
-rw-r--r--src/nix/flake.cc17
-rw-r--r--src/nix/why-depends.cc5
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) {