why-depends: asyncify printNode
Instead of logging directly, we now write into a `Strings` set that is referenced by the caller. While at it, added a test-case to ensure that self-reference invocations and --all behave properly. Change-Id: Ib183ab8e8e90436300e1c870fb3ae8f18730abbf
This commit is contained in:
+51
-38
@@ -3,6 +3,7 @@
|
||||
#include "lix/libstore/fs-accessor.hh"
|
||||
#include "lix/libmain/shared.hh"
|
||||
#include "lix/libutil/error.hh"
|
||||
#include "lix/libutil/generator.hh"
|
||||
#include "lix/libutil/result.hh"
|
||||
#include "why-depends.hh"
|
||||
|
||||
@@ -99,9 +100,6 @@ try {
|
||||
co_return result::current_exception();
|
||||
}
|
||||
|
||||
struct BailOut : BaseException
|
||||
{};
|
||||
|
||||
auto const inf = std::numeric_limits<size_t>::max();
|
||||
struct Node
|
||||
{
|
||||
@@ -114,29 +112,32 @@ struct Node
|
||||
bool visited = false;
|
||||
};
|
||||
|
||||
static void printNode(
|
||||
struct BailOut : BaseException
|
||||
{};
|
||||
|
||||
static kj::Promise<Result<void>> printNode(
|
||||
Node & node,
|
||||
const std::string & firstPad,
|
||||
const std::string & tailPad,
|
||||
bool all,
|
||||
bool precise,
|
||||
Store & store,
|
||||
AsyncIoRoot & aio,
|
||||
const StorePath & packagePath,
|
||||
const StorePath & dependencyPath,
|
||||
std::map<StorePath, Node> & graph
|
||||
std::map<StorePath, Node> & graph,
|
||||
Strings & output
|
||||
)
|
||||
{
|
||||
try {
|
||||
auto pathS = store.printStorePath(node.path);
|
||||
|
||||
assert(node.dist != inf);
|
||||
if (precise) {
|
||||
logger->cout(
|
||||
"%s%s%s%s" ANSI_NORMAL,
|
||||
firstPad,
|
||||
node.visited ? "\e[38;5;244m" : "",
|
||||
firstPad != "" ? "→ " : "",
|
||||
pathS
|
||||
output.push_back(
|
||||
fmt("%s%s%s%s" ANSI_NORMAL,
|
||||
firstPad,
|
||||
node.visited ? "\e[38;5;244m" : "",
|
||||
firstPad != "" ? "→ " : "",
|
||||
pathS)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -145,8 +146,9 @@ static void printNode(
|
||||
}
|
||||
|
||||
if (node.visited) {
|
||||
return;
|
||||
co_return result::success();
|
||||
}
|
||||
|
||||
if (precise) {
|
||||
node.visited = true;
|
||||
}
|
||||
@@ -175,7 +177,7 @@ static void printNode(
|
||||
// FIXME: should use scanForReferences().
|
||||
|
||||
if (precise) {
|
||||
hits = aio.blockOn(visitPath(
|
||||
hits = TRY_AWAIT(visitPath(
|
||||
pathS, store, pathS, dependencyPath.hashPart(), hashes, packagePath, dependencyPath
|
||||
));
|
||||
}
|
||||
@@ -187,11 +189,11 @@ static void printNode(
|
||||
|
||||
for (auto & hit : hits[hash]) {
|
||||
bool first = hit == *hits[hash].begin();
|
||||
logger->cout(
|
||||
"%s%s%s",
|
||||
tailPad,
|
||||
(first ? (last ? treeLast : treeConn) : (last ? treeNull : treeLine)),
|
||||
hit
|
||||
output.push_back(
|
||||
fmt("%s%s%s",
|
||||
tailPad,
|
||||
(first ? (last ? treeLast : treeConn) : (last ? treeNull : treeLine)),
|
||||
hit)
|
||||
);
|
||||
if (!all) {
|
||||
break;
|
||||
@@ -200,29 +202,33 @@ static void printNode(
|
||||
|
||||
if (!precise) {
|
||||
auto pathS = store.printStorePath(ref.second->path);
|
||||
logger->cout(
|
||||
"%s%s%s%s" ANSI_NORMAL,
|
||||
firstPad,
|
||||
ref.second->visited ? "\e[38;5;244m" : "",
|
||||
last ? treeLast : treeConn,
|
||||
pathS
|
||||
output.push_back(
|
||||
fmt("%s%s%s%s" ANSI_NORMAL,
|
||||
firstPad,
|
||||
ref.second->visited ? "\e[38;5;244m" : "",
|
||||
last ? treeLast : treeConn,
|
||||
pathS)
|
||||
);
|
||||
node.visited = true;
|
||||
}
|
||||
|
||||
printNode(
|
||||
TRY_AWAIT(printNode(
|
||||
*ref.second,
|
||||
tailPad + (last ? treeNull : treeLine),
|
||||
tailPad + (last ? treeNull : treeLine),
|
||||
all,
|
||||
precise,
|
||||
store,
|
||||
aio,
|
||||
packagePath,
|
||||
dependencyPath,
|
||||
graph
|
||||
);
|
||||
graph,
|
||||
output
|
||||
));
|
||||
}
|
||||
|
||||
co_return result::success();
|
||||
} catch (...) {
|
||||
co_return result::current_exception();
|
||||
}
|
||||
|
||||
struct CmdWhyDepends : SourceExprCommand, MixOperateOnOptions
|
||||
@@ -356,23 +362,30 @@ struct CmdWhyDepends : SourceExprCommand, MixOperateOnOptions
|
||||
'dependency'). Print every edge on a path between `package`
|
||||
and `dependency`. */
|
||||
RunPager pager;
|
||||
if (!precise) {
|
||||
logger->cout("%s", store->printStorePath(graph.at(packagePath).path));
|
||||
}
|
||||
|
||||
Strings output;
|
||||
try {
|
||||
if (!precise) {
|
||||
logger->cout("%s", store->printStorePath(graph.at(packagePath).path));
|
||||
}
|
||||
printNode(
|
||||
aio().blockOn(printNode(
|
||||
graph.at(packagePath),
|
||||
"",
|
||||
"",
|
||||
all,
|
||||
precise,
|
||||
*store,
|
||||
aio(),
|
||||
packagePath,
|
||||
dependencyPath,
|
||||
graph
|
||||
);
|
||||
} catch (BailOut & ) { }
|
||||
graph,
|
||||
output
|
||||
));
|
||||
} catch (BailOut &) {
|
||||
}
|
||||
|
||||
for (auto & l : output) {
|
||||
logger->cout("%s", l);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ mkdir $out
|
||||
echo $(cat $input1/foo)$(cat $input2/bar) > $out/foobar
|
||||
|
||||
ln -s $input2 $out/reference-to-input-2
|
||||
ln -s $input3 $out/reference-to-input-3
|
||||
|
||||
# Self-reference.
|
||||
ln -s $out $out/self
|
||||
|
||||
@@ -20,9 +20,15 @@ let
|
||||
head -c 100k /dev/zero > $out/filler
|
||||
echo BAR > $out/bar
|
||||
echo ${input0} > $out/input0
|
||||
echo ${input3} > $out/input3
|
||||
'';
|
||||
};
|
||||
|
||||
input3 = mkDerivation {
|
||||
name = "dependencies-input-3";
|
||||
buildCommand = "mkdir $out; echo FOO > $out/foo";
|
||||
};
|
||||
|
||||
fod_input = mkDerivation {
|
||||
name = "fod-input";
|
||||
buildCommand = ''
|
||||
@@ -40,8 +46,10 @@ mkDerivation {
|
||||
builder = ./dependencies.builder0.sh + "/FOOBAR/../.";
|
||||
input1 = input1 + "/.";
|
||||
input2 = "${input2}/.";
|
||||
input3 = "${input3}/.";
|
||||
input1_drv = input1;
|
||||
input2_drv = input2;
|
||||
input3_drv = input3;
|
||||
input0_drv = input0;
|
||||
fod_input_drv = fod_input;
|
||||
meta.description = "Random test package";
|
||||
|
||||
@@ -11,7 +11,7 @@ checkRef() {
|
||||
|
||||
outPath=$(nix-build ./export-graph.nix -A 'foo."bar.runtimeGraph"' -o $TEST_ROOT/result)
|
||||
|
||||
test $(nix-store -q --references $TEST_ROOT/result | wc -l) = 3 || fail "bad nr of references"
|
||||
test $(nix-store -q --references $TEST_ROOT/result | wc -l) = 4 || fail "bad nr of references"
|
||||
|
||||
checkRef input-2
|
||||
for i in $(cat $outPath); do checkRef $i; done
|
||||
|
||||
@@ -10,6 +10,7 @@ nix why-depends --derivation --file ./dependencies.nix input2_drv input1_drv
|
||||
nix why-depends --file ./dependencies.nix input2_drv input1_drv
|
||||
|
||||
nix-build ./dependencies.nix -A input0_drv -o dep
|
||||
nix-build ./dependencies.nix -A input3_drv -o dep3
|
||||
nix-build ./dependencies.nix -o toplevel
|
||||
|
||||
FAST_WHY_DEPENDS_OUTPUT=$(nix why-depends ./toplevel ./dep)
|
||||
@@ -27,3 +28,14 @@ echo "$PRECISE_WHY_DEPENDS_OUTPUT" | grepQuiet reference-to-input-2
|
||||
<<<"$PRECISE_WHY_DEPENDS_OUTPUT" sed -n '3p' | grep " →" | grepQuiet "dependencies-input-2"
|
||||
<<<"$PRECISE_WHY_DEPENDS_OUTPUT" sed -n '4p' | grepQuiet " └───input0: …" # in input-2, file input0
|
||||
<<<"$PRECISE_WHY_DEPENDS_OUTPUT" sed -n '5p' | grep " →" | grepQuiet "dependencies-input-0" # is dependencies-input-0 referenced
|
||||
|
||||
WHY_DEPENDS_SELF_REF="$(nix why-depends ./toplevel ./toplevel)"
|
||||
<<<"$WHY_DEPENDS_SELF_REF" sed -n '1p' | grepQuiet "dependencies-top"
|
||||
<<<"$WHY_DEPENDS_SELF_REF" sed -n '2p' | grep "└─" | grepQuiet "dependencies-top"
|
||||
test -z "$(<<<"$WHY_DEPENDS_SELF_REF" sed -n '3p')"
|
||||
|
||||
WHY_DEPENDS_ALL="$(nix why-depends ./toplevel ./dep3 --all)"
|
||||
<<<"$WHY_DEPENDS_ALL" sed -n '1p' | grep -v "└─" | grepQuiet "dependencies-top"
|
||||
<<<"$WHY_DEPENDS_ALL" sed -n '2p' | grep "├─" | grepQuiet "input-3"
|
||||
<<<"$WHY_DEPENDS_ALL" sed -n '3p' | grep "└─" | grepQuiet "input-2"
|
||||
<<<"$WHY_DEPENDS_ALL" sed -n '4p' | grep " └─" | grepQuiet "input-3"
|
||||
|
||||
Reference in New Issue
Block a user