#!/usr/bin/perl # # Output a dot graph of installed reverse dependencies for a package. # use strict; use warnings; use AptPkg::Config '$_config'; use AptPkg::System '$_system'; use AptPkg::Cache; use Getopt::Long; (my $self = $0) =~ s#.*/##; # Default is to include recommended packages, but not suggested. my %want; $want{$_} = 1 for (AptPkg::Dep::Depends, AptPkg::Dep::PreDepends, AptPkg::Dep::Recommends); $want{$_} = 0 for (AptPkg::Dep::Suggests); die "Usage: $self [--suggests] [--norecommends] PACKAGE\n" unless GetOptions('suggests!' => \$want{AptPkg::Dep::Suggests}, 'recommends!' => \$want{AptPkg::Dep::Recommends}) and @ARGV == 1; $_config->init; $_system = $_config->system; $_config->{quiet} = 2; my $cache = AptPkg::Cache->new; my @todo = @ARGV; my %deps; my %seen; do { my @next; for my $pack (@todo) { my $p = $cache->{$pack} or next; next unless $p->{CurrentState} == AptPkg::State::Installed; my $revdeps = $p->{RevDependsList} or next; my @instrevdeps; for my $r (map $_->{ParentPkg}{ShortName}, grep $want{0+$_->{DepType}}, @$revdeps) { next if $seen{$r}++; $p = $cache->{$r} or next; push @instrevdeps, $r if $p->{CurrentState} == AptPkg::State::Installed; } next unless @instrevdeps; $deps{$pack} = \@instrevdeps; push @next, @instrevdeps; } @todo = @next; } while (@todo); $\ = "\n"; print "digraph deps {"; while (my ($p, $d) = each %deps) { print qq/ "$_" -> "$p"/ for @$d; } print "}";