nix why-depends is awesome. However, (correct me if I'm wrong) it only seems to cover runtime dependencies. While it's not quite as much of a fuss to use nix-store -q --graph for build-time dependencies, since there aren't whole directory trees to search through, it would still be nice to have the computer trace the dependency path for you.
@lheckemann You mentioned a workaround using nix-store -q --graph. Is there any way to get the same behaviour as with nix why-depends with it, e.g. using a special filter program? Just with grep I have a hard time answering the question "Why does x depend on y".
@erictapen I use nix-store -q --graph on the drv then use my pager's search to find the dependency edges manually. Maybe this could be automated through the use of the dijkstra path-finding tool from the graphviz package though.
@lheckemann Thanks! I think this one-liner would provide a graph, showing the edges between glibc and hello. Just in case anyone else is looking for a workaround to this issue.
$ nix-shell -p graphviz
$ nix-store -q --graph $(nix-instantiate '<nixpkgs>' -A hello) | dijkstra -da $(nix-instantiate '<nixpkgs>' -A glibc) | gvpr -c 'N[dist>1000.0]{delete(NULL, $)}'
As a further tip, the command from @erictapen can be suffixed with | dot -Tsvg | display to render it directly into an image.
Continuing the trend of iterative improvement and over-engineering it a bit, here is a reusable shell script with interactive dependency selection (./why-depends.sh /nix/store/pqzs5kb5yjnrsfag3cs3cdzqjavwspmk-firefox-76.0.1.drv, it will let you fuzzy-select the dependency you're interested in):
#! /usr/bin/env nix-shell
#! nix-shell -i bash -p graphviz imagemagick coreutils fzf
# Drv that depends on the thing in question is the first argument
DRV="$1"
# Write the graph into a tempfile for further processing
GRAPH_FILE="$( mktemp )"
nix-store -q --graph "$DRV" > "$GRAPH_FILE"
# Dependency is either the second argument or specified interactively. Use sed
# to find all drvs mentioned in the graph file, fzf to fuzzy-filter the list.
DEPENDENCY="${2:-$(sed -n 's/^"\([^"]*\)".*/\1/p' "$GRAPH_FILE" | sort | uniq | fzf)}"
echo "Searching for paths from $DEPENDENCY to $DRV in $GRAPH_FILE"
# Use dijkstra to find the paths, dot to render and imagemagick to display.
# https://github.com/NixOS/nix/issues/1918
dijkstra -da "$DEPENDENCY" "$GRAPH_FILE" | gvpr -c 'N[dist>1000.0]{delete(NULL, $)}' | dot -Tsvg | display
rm "$GRAPH_FILE"
Most helpful comment
@lheckemann Thanks! I think this one-liner would provide a graph, showing the edges between
glibcandhello. Just in case anyone else is looking for a workaround to this issue.