forked from lix-project/lix
nix flake list-inputs: Pretty-print the tree
This commit is contained in:
parent
a6e2b6b360
commit
678301072f
|
@ -458,6 +458,13 @@ void ignoreException();
|
||||||
#define ANSI_BLUE "\e[34;1m"
|
#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'
|
/* Truncate a string to 'width' printable characters. If 'filterAll'
|
||||||
is true, all ANSI escape sequences are filtered out. Otherwise,
|
is true, all ANSI escape sequences are filtered out. Otherwise,
|
||||||
some escape sequences (such as colour setting) are copied but not
|
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);
|
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) };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,12 +229,6 @@ static StorePathSet maybeUseOutputs(const StorePath & storePath, bool useOutput,
|
||||||
/* Some code to print a tree representation of a derivation dependency
|
/* Some code to print a tree representation of a derivation dependency
|
||||||
graph. Topological sorting is used to keep the tree relatively
|
graph. Topological sorting is used to keep the tree relatively
|
||||||
flat. */
|
flat. */
|
||||||
|
|
||||||
const string treeConn = "+---";
|
|
||||||
const string treeLine = "| ";
|
|
||||||
const string treeNull = " ";
|
|
||||||
|
|
||||||
|
|
||||||
static void printTree(const StorePath & path,
|
static void printTree(const StorePath & path,
|
||||||
const string & firstPad, const string & tailPad, StorePathSet & done)
|
const string & firstPad, const string & tailPad, StorePathSet & done)
|
||||||
{
|
{
|
||||||
|
@ -254,10 +248,11 @@ static void printTree(const StorePath & path,
|
||||||
auto sorted = store->topoSortPaths(info->references);
|
auto sorted = store->topoSortPaths(info->references);
|
||||||
reverse(sorted.begin(), sorted.end());
|
reverse(sorted.begin(), sorted.end());
|
||||||
|
|
||||||
for (auto i = sorted.begin(); i != sorted.end(); ++i) {
|
for (const auto &[n, i] : enumerate(sorted)) {
|
||||||
auto j = i; ++j;
|
bool last = n + 1 == sorted.size();
|
||||||
printTree(*i, tailPad + treeConn,
|
printTree(i,
|
||||||
j == sorted.end() ? tailPad + treeNull : tailPad + treeLine,
|
tailPad + (last ? treeLast : treeConn),
|
||||||
|
tailPad + (last ? treeNull : treeLine),
|
||||||
done);
|
done);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,22 +193,27 @@ struct CmdFlakeListInputs : FlakeCommand, MixJSON
|
||||||
{
|
{
|
||||||
auto flake = lockFlake();
|
auto flake = lockFlake();
|
||||||
|
|
||||||
|
stopProgressBar();
|
||||||
|
|
||||||
if (json)
|
if (json)
|
||||||
std::cout << ((LockedInputs &) flake.lockFile).toJson() << "\n";
|
std::cout << ((LockedInputs &) flake.lockFile).toJson() << "\n";
|
||||||
else {
|
else {
|
||||||
std::cout << fmt("%s\n", flake.flake.resolvedRef);
|
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) {
|
for (const auto & [i, input] : enumerate(inputs.inputs)) {
|
||||||
std::cout << fmt("%s%s: %s\n", std::string(depth * 2, ' '), input.first, input.second.ref);
|
//auto tree2 = tree.child(i + 1 == inputs.inputs.size());
|
||||||
recurse(input.second, depth + 1);
|
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, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -143,11 +143,6 @@ struct CmdWhyDepends : SourceExprCommand
|
||||||
and `dependency`. */
|
and `dependency`. */
|
||||||
std::function<void(Node &, const string &, const string &)> printNode;
|
std::function<void(Node &, const string &, const string &)> printNode;
|
||||||
|
|
||||||
const string treeConn = "╠═══";
|
|
||||||
const string treeLast = "╚═══";
|
|
||||||
const string treeLine = "║ ";
|
|
||||||
const string treeNull = " ";
|
|
||||||
|
|
||||||
struct BailOut { };
|
struct BailOut { };
|
||||||
|
|
||||||
printNode = [&](Node & node, const string & firstPad, const string & tailPad) {
|
printNode = [&](Node & node, const string & firstPad, const string & tailPad) {
|
||||||
|
|
|
@ -6,7 +6,7 @@ drvPath=$(nix-instantiate dependencies.nix)
|
||||||
|
|
||||||
echo "derivation is $drvPath"
|
echo "derivation is $drvPath"
|
||||||
|
|
||||||
nix-store -q --tree "$drvPath" | grep ' +---.*builder1.sh'
|
nix-store -q --tree "$drvPath" | grep '║ ╚═══.*builder1.sh'
|
||||||
|
|
||||||
# Test Graphviz graph generation.
|
# Test Graphviz graph generation.
|
||||||
nix-store -q --graph "$drvPath" > $TEST_ROOT/graph
|
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
|
if test -n "$dot"; then
|
||||||
# Does it parse?
|
# Does it parse?
|
||||||
$dot < $TEST_ROOT/graph
|
$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"
|
echo "output path is $outPath"
|
||||||
|
|
||||||
|
@ -49,4 +49,4 @@ nix-store -q --referrers-closure "$input2OutPath" | grep "$outPath"
|
||||||
|
|
||||||
# Check that the derivers are set properly.
|
# Check that the derivers are set properly.
|
||||||
test $(nix-store -q --deriver "$outPath") = "$drvPath"
|
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"
|
||||||
|
|
Loading…
Reference in a new issue