debtree — package dependency graphs on steroids

Introduction

This started with the simple question "how exactly does package X pull in package Y when I install it". The only way I knew of was to use aptitude interactively and just guess which package was the most likely culprit.

So I set out to create a simple script to recurse through dependencies...

Basically this meant building a dependency tree. I'd long wanted to play with dot, and this seemed like a good opportunity as visualizing the trees looked like a nice way to check their correctness.

To make a long story short, after the basic functionality had been implemented, it turned out to be fairly easy (and irresistible) to extend the functionality bit by bit.

So now we have a script that can show dependency paths between packages and can also generate dependency graphs in the form of .dot files that serve as input for dot (from the graphviz package).

The command apt-cache already has a similar option, but debtree is a lot more powerful.

Examples

The examples below show the different levels of detail that can be obtained using debtree and explain the graphs. Please view them in the indicated order.

Note that Postscript viewers may not display some of the larger graphs until you zoom out one or more times. I've used kghostview and that at least always showed the thumbnail correctly.

Other packages for which (mostly default) graphs have been produced, roughly in ascending order of complexity:
bind9, debmirror, gettext, iceweasel, logcheck, logrotate, mutt, mysql-client, mysql-server, ssh, subversion, debiandoc-sgml, exim4, cupsys, gimp, lintian, apache2, wesnoth, vlc.

To get usable graphs for some of these, a number of packages have been added to the /etc/debtree/endlist configuration file. If you try other packages, you may need to do the same. Try to add only packages for which it is "logical" not to expand the graph any further.

Another option is to limit the number of dependency levels (the "depth" of the graph) by specifying a maximum depth or to reduce the amount of information included in the graph using the available command line options.

Download

The debtree script can be installed using this package (source, .dsc). It is of course free software (GPL).

Its only dependency is dctrl-tools; graphviz is recommended.

You can also check out its git repository using:
$ git clone git://git.debian.org/~fjp/debtree.git

Comments, bugs and patches to: Frans Pop.

Known issues

  • As debtree is currently written in bash and does individual calls to the dctrl-tools utilities, it is not terribly fast. But then again, it is not terribly slow either.
  • In some cases graphs can get fairly messy when there are alternatives that have very similar dependencies. Good examples are apache and wesnoth.

Future development

There is still a lot of improvement possible. See also the comments in the current script.

  • Re-implement in a decent language. C++ seems most logical as that is also used in apt-cache, which could be used as a basis.
    As I don't have the skills needed to do this myself: volunteers are welcome!
  • Have the tool automatically determine points where to stop recursing or where to create sub-graphs on a separate page.
$ debtree dpkg

Dependency graph for dpkg
$ debtree dpkg libsepol1
dpkg -> coreutils (PD) -> libselinux1 (PD) -> libsepol1 (D)

Usage

See the debtree(1) man page for detailed usage information.

Examples

  • Show the dependency path between two packages
    $ debtree <package1> <package2>
  • Create a .dot file
    $ debtree --with-suggests <package> >out.dot
  • Create a graph (PNG) from a .dot file
    $ dot -T png -o out.png out.dot
  • Create a graph (Postscript) and view it using kghostview
    $ debtree <package> | dot -Tps | kghostview - &

Option summary

--show-installed | -I
Show which packages are installed on the system
--build-dep | -b
Generate a graph showing build dependencies instead of package dependencies
--arch=<arch>
Specify the architecture (or 'all') for the build dependency graph (default is the architecture of the system)
--with-suggests | -S
Include suggested packages; dependencies of suggested packages are never included
--no-recommends
Don't show recommended packages
--no-alternatives
Only show the first dependency from a set of alternatives (i.e. show what would be installed by default)
--no-provides
Do not show virtual packages provided by the requested package
--max-providers=<num>
Limit the display of packages that provide a virtual package (default: 3)
--no-versions
Don't show the versions for versioned dependencies
--no-conflicts
Don't show unversioned conflicts
--versioned-conflicts | -VC
Include versioned conflicts; by default only unversioned conflicts are shown
--max-depth=<num>
Limit the number of levels of dependencies
--no-skip
Also display packages that are suppressed by default (e.g. libc6)
--show-all
Generate full dependency tree (recurse for all packages); implies --no-skip
--rotate | -r
Draw the graph top-town instead of left-to-right
--condense
Condense the graph by merging lines (relationships) between packages
--quiet | -q
Suppress any informational/warning messages
--verbose | -v
Increase verbosity to display debug messages; can be repeated

Configuration

/etc/debtree/skiplist
Packages that by default will be excluded from dependency graphs.
/etc/debtree/endlist
Packages for which by default no dependencies will be shown on graphs.

See the comments in these files and the examples on these pages for information on how they are used. The configuration can be overruled on a per-user basis by creating a directory ~/.debtree/ and adding custom versions of these files there.

Suggestions for packages to add are welcome. Please mail both the command for the graph you'd like to reduce and the packages you're proposing to add to the lists.

The current list of 'skip' packages is:
libc6, libgcc1, libstdc++6, zlib1g, libx11-6.
Reason these packages are excluded is that they are so common that including them only result in cluttering the graph without adding any real information. An option is available that allows to generate a full graph that includes these packages.