diff options
Diffstat (limited to 'src/nix/why-depends.cc')
-rw-r--r-- | src/nix/why-depends.cc | 63 |
1 files changed, 49 insertions, 14 deletions
diff --git a/src/nix/why-depends.cc b/src/nix/why-depends.cc index 2f6b361bb..1d9ab28ba 100644 --- a/src/nix/why-depends.cc +++ b/src/nix/why-depends.cc @@ -31,11 +31,25 @@ struct CmdWhyDepends : SourceExprCommand { std::string _package, _dependency; bool all = false; + bool precise = false; CmdWhyDepends() { - expectArg("package", &_package); - expectArg("dependency", &_dependency); + expectArgs({ + .label = "package", + .handler = {&_package}, + .completer = {[&](size_t, std::string_view prefix) { + completeInstallable(prefix); + }} + }); + + expectArgs({ + .label = "dependency", + .handler = {&_dependency}, + .completer = {[&](size_t, std::string_view prefix) { + completeInstallable(prefix); + }} + }); addFlag({ .longName = "all", @@ -43,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 in the dependency graph, show the files in the parent that cause the dependency.", + .handler = {&precise, true}, + }); } std::string description() override @@ -62,9 +82,9 @@ struct CmdWhyDepends : SourceExprCommand void run(ref<Store> store) override { auto package = parseInstallable(store, _package); - auto packagePath = toStorePath(getEvalStore(), store, Realise::Outputs, operateOn, package); + auto packagePath = Installable::toStorePath(getEvalStore(), store, Realise::Outputs, operateOn, package); auto dependency = parseInstallable(store, _dependency); - auto dependencyPath = toStorePath(getEvalStore(), store, Realise::Derivation, operateOn, dependency); + auto dependencyPath = Installable::toStorePath(getEvalStore(), store, Realise::Derivation, operateOn, dependency); auto dependencyPathHash = dependencyPath.hashPart(); StorePathSet closure; @@ -137,26 +157,28 @@ struct CmdWhyDepends : SourceExprCommand closure (i.e., that have a non-infinite distance to 'dependency'). Print every edge on a path between `package` and `dependency`. */ - std::function<void(Node &, const string &, const string &)> printNode; + std::function<void(Node &, const std::string &, const std::string &)> printNode; struct BailOut { }; - printNode = [&](Node & node, const string & firstPad, const string & tailPad) { + printNode = [&](Node & node, const std::string & firstPad, const std::string & tailPad) { 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); + } if (node.path == dependencyPath && !all && packagePath != dependencyPath) throw BailOut(); if (node.visited) return; - node.visited = true; + if (precise) node.visited = true; /* Sort the references by distance to `dependency` to ensure that the shortest path is printed first. */ @@ -224,9 +246,8 @@ struct CmdWhyDepends : SourceExprCommand // FIXME: should use scanForReferences(). - visitPath(pathS); + if (precise) visitPath(pathS); - RunPager pager; for (auto & ref : refs) { std::string hash(ref.second->path.hashPart()); @@ -240,13 +261,27 @@ struct CmdWhyDepends : SourceExprCommand if (!all) break; } + 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); + node.visited = true; + } + printNode(*ref.second, tailPad + (last ? treeNull : treeLine), tailPad + (last ? treeNull : treeLine)); } }; + RunPager pager; try { + if (!precise) { + logger->cout("%s", store->printStorePath(graph.at(packagePath).path)); + } printNode(graph.at(packagePath), "", ""); } catch (BailOut & ) { } } |