Pretty-print 'nix why-depends' / 'nix-store -q --tree' output

Extracted from 678301072f.
This commit is contained in:
Eelco Dolstra 2020-03-24 14:17:10 +01:00
parent 4260a22a55
commit 7a8de57d3e
4 changed files with 44 additions and 20 deletions

View file

@ -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) };
}
}

View file

@ -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);
}
}

View file

@ -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

View file

@ -6,7 +6,7 @@ drvPath=$(nix-instantiate dependencies.nix)
echo "derivation is $drvPath"
nix-store -q --tree "$drvPath" | grep ' +---.*builder1.sh'
nix-store -q --tree "$drvPath" | grep '───.*builder1.sh'
# Test Graphviz graph generation.
nix-store -q --graph "$drvPath" > $TEST_ROOT/graph
@ -22,9 +22,9 @@ nix-store -q --graph "$outPath" > $TEST_ROOT/graph
if test -n "$dot"; then
# Does it parse?
$dot < $TEST_ROOT/graph
fi
fi
nix-store -q --tree "$outPath" | grep '+---.*dependencies-input-2'
nix-store -q --tree "$outPath" | grep '───.*dependencies-input-2'
echo "output path is $outPath"
@ -49,4 +49,4 @@ nix-store -q --referrers-closure "$input2OutPath" | grep "$outPath"
# Check that the derivers are set properly.
test $(nix-store -q --deriver "$outPath") = "$drvPath"
nix-store -q --deriver "$input2OutPath" | grep -q -- "-input-2.drv"
nix-store -q --deriver "$input2OutPath" | grep -q -- "-input-2.drv"