From 2ad2678c0baaa755becdbb7be82e2bb2e8ba1ada Mon Sep 17 00:00:00 2001 From: regnat Date: Tue, 18 Jan 2022 16:54:53 +0100 Subject: [PATCH 1/3] Add a simple test for `nix why-depends` --- tests/dependencies.nix | 2 ++ tests/local.mk | 3 ++- tests/why-depends.sh | 13 +++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 tests/why-depends.sh diff --git a/tests/dependencies.nix b/tests/dependencies.nix index e320d81c9..45aca1793 100644 --- a/tests/dependencies.nix +++ b/tests/dependencies.nix @@ -27,6 +27,8 @@ let { input1 = input1 + "/."; input2 = "${input2}/."; input1_drv = input1; + input2_drv = input2; + input0_drv = input0; meta.description = "Random test package"; }; diff --git a/tests/local.mk b/tests/local.mk index 8580ecac9..93cf20d43 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -61,7 +61,8 @@ nix_tests = \ ca/concurrent-builds.sh \ ca/nix-copy.sh \ eval-store.sh \ - readfile-context.sh + readfile-context.sh \ + why-depends.sh # parallel.sh ifeq ($(HAVE_LIBCPUID), 1) diff --git a/tests/why-depends.sh b/tests/why-depends.sh new file mode 100644 index 000000000..11b54b5b6 --- /dev/null +++ b/tests/why-depends.sh @@ -0,0 +1,13 @@ +source common.sh + +clearStore + +cp ./dependencies.nix ./dependencies.builder0.sh ./config.nix $TEST_HOME + +cd $TEST_HOME + +nix-build ./dependencies.nix -A input0_drv -o dep +nix-build ./dependencies.nix -o toplevel + +nix why-depends ./toplevel ./dep | + grep input-2 From dd7c2e0695b02639d8fe6c7bc050da14373b9513 Mon Sep 17 00:00:00 2001 From: regnat Date: Wed, 19 Jan 2022 14:15:45 +0100 Subject: [PATCH 2/3] Make `nix why-depends` quieter by default Unless `--precise` is passed, make `nix why-depends` only show the dependencies between the store paths, without introspecting them to find the actual references. This also makes it ~3x faster --- src/nix/why-depends.cc | 27 +++++++++++++++++++++------ tests/dependencies.builder0.sh | 2 +- tests/gc.sh | 4 ++-- tests/why-depends.sh | 12 ++++++++++-- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/nix/why-depends.cc b/src/nix/why-depends.cc index dd43bd1c3..74377c912 100644 --- a/src/nix/why-depends.cc +++ b/src/nix/why-depends.cc @@ -31,6 +31,7 @@ struct CmdWhyDepends : SourceExprCommand { std::string _package, _dependency; bool all = false; + bool precise = false; CmdWhyDepends() { @@ -56,6 +57,12 @@ struct CmdWhyDepends : SourceExprCommand .description = "Show all edges in the dependency graph leading from *package* to *dependency*, rather than just a shortest path.", .handler = {&all, true}, }); + + addFlag({ + .longName = "precise", + .description = "For each edge of the graph, inspect the parent node to display the exact location in the path that causes the dependency", + .handler = {&precise, true}, + }); } std::string description() override @@ -158,11 +165,19 @@ struct CmdWhyDepends : SourceExprCommand auto pathS = store->printStorePath(node.path); assert(node.dist != inf); - logger->cout("%s%s%s%s" ANSI_NORMAL, - firstPad, - node.visited ? "\e[38;5;244m" : "", - firstPad != "" ? "→ " : "", - pathS); + if (precise) { + logger->cout("%s%s%s%s" ANSI_NORMAL, + firstPad, + node.visited ? "\e[38;5;244m" : "", + firstPad != "" ? "→ " : "", + pathS); + } else { + logger->cout("%s%s%s%s" ANSI_NORMAL, + firstPad, + node.visited ? "\e[38;5;244m" : "", + firstPad != "" ? treeLast : "", + pathS); + } if (node.path == dependencyPath && !all && packagePath != dependencyPath) @@ -237,7 +252,7 @@ struct CmdWhyDepends : SourceExprCommand // FIXME: should use scanForReferences(). - visitPath(pathS); + if (precise) visitPath(pathS); for (auto & ref : refs) { std::string hash(ref.second->path.hashPart()); diff --git a/tests/dependencies.builder0.sh b/tests/dependencies.builder0.sh index c37bf909a..9b11576e0 100644 --- a/tests/dependencies.builder0.sh +++ b/tests/dependencies.builder0.sh @@ -4,7 +4,7 @@ mkdir $out echo $(cat $input1/foo)$(cat $input2/bar) > $out/foobar -ln -s $input2 $out/input-2 +ln -s $input2 $out/reference-to-input-2 # Self-reference. ln -s $out $out/self diff --git a/tests/gc.sh b/tests/gc.sh index a736b63db..ad09a8b39 100644 --- a/tests/gc.sh +++ b/tests/gc.sh @@ -18,7 +18,7 @@ if nix-store --gc --print-dead | grep -E $outPath$; then false; fi nix-store --gc --print-dead -inUse=$(readLink $outPath/input-2) +inUse=$(readLink $outPath/reference-to-input-2) if nix-store --delete $inUse; then false; fi test -e $inUse @@ -35,7 +35,7 @@ nix-collect-garbage # Check that the root and its dependencies haven't been deleted. cat $outPath/foobar -cat $outPath/input-2/bar +cat $outPath/reference-to-input-2/bar # Check that the derivation has been GC'd. if test -e $drvPath; then false; fi diff --git a/tests/why-depends.sh b/tests/why-depends.sh index 11b54b5b6..c12941e76 100644 --- a/tests/why-depends.sh +++ b/tests/why-depends.sh @@ -9,5 +9,13 @@ cd $TEST_HOME nix-build ./dependencies.nix -A input0_drv -o dep nix-build ./dependencies.nix -o toplevel -nix why-depends ./toplevel ./dep | - grep input-2 +FAST_WHY_DEPENDS_OUTPUT=$(nix why-depends ./toplevel ./dep) +PRECISE_WHY_DEPENDS_OUTPUT=$(nix why-depends ./toplevel ./dep --precise) + +# Both outputs should show that `input-2` is in the dependency chain +echo "$FAST_WHY_DEPENDS_OUTPUT" | grep -q input-2 +echo "$PRECISE_WHY_DEPENDS_OUTPUT" | grep -q input-2 + +# But only the “precise” one should refere to `reference-to-input-2` +echo "$FAST_WHY_DEPENDS_OUTPUT" | (! grep -q reference-to-input-2) +echo "$PRECISE_WHY_DEPENDS_OUTPUT" | grep -q reference-to-input-2 From fa53250c366708ea17dab9d0c549719f0609e3fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophane=20Hufschmitt?= <7226587+thufschmitt@users.noreply.github.com> Date: Fri, 21 Jan 2022 09:52:40 +0100 Subject: [PATCH 3/3] Improve the description of the `--precise` option Co-authored-by: Eelco Dolstra --- src/nix/why-depends.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nix/why-depends.cc b/src/nix/why-depends.cc index 74377c912..657df30d7 100644 --- a/src/nix/why-depends.cc +++ b/src/nix/why-depends.cc @@ -60,7 +60,7 @@ struct CmdWhyDepends : SourceExprCommand addFlag({ .longName = "precise", - .description = "For each edge of the graph, inspect the parent node to display the exact location in the path that causes the dependency", + .description = "For each edge in the dependency graph, show the files in the parent that cause the dependency.", .handler = {&precise, true}, }); }