1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
#!/usr/bin/env perl
## Copyright © 2008-2009 by Daniel Friesel <derf@finalrewind.org>
## License: WTFPL <http://sam.zoy.org/wtfpl>
use strict;
use warnings;
use 5.010;
use AptPkg::Cache;
use Getopt::Long;
my $cache = AptPkg::Cache->new;
my $max_depth = 5;
my $all = 0;
my @deptypes = qw/Depends Recommends Suggests/;
my @known;
sub revdeps {
my $name = shift;
my $package = $cache->{$name};
my @return;
my $rdeps = $package->{RevDependsList};
foreach my $dependency ( @{$rdeps} ) {
if (
not $dependency->{ParentPkg}{Name} ~~ @known
and ( $all
or $cache->{ $dependency->{ParentPkg}{Name} }->{CurrentState} eq
'Installed' )
and "$dependency->{DepType}" ~~ @deptypes
)
{
push( @return, $dependency->{ParentPkg}{Name} );
}
}
push( @known, @return );
return (@return);
}
sub recurse {
my $name = shift;
my $depth = (shift) + 1;
printf( "%s%s\n", "\t" x ( $depth - 1 ), $name );
if ( $depth >= $max_depth ) {
return;
}
foreach ( revdeps($name) ) {
recurse( $_, $depth );
}
return;
}
GetOptions(
'all!' => \$all,
'deptype=s' => sub { @deptypes = split( /,/, $_[1] ) },
'depth=i' => \$max_depth,
'h|?|help' =>
sub { exec( 'perldoc', '-F', $0 ) or die("See perldoc -F $0\n") },
);
my $packagename = shift
or die("Usage: $0 [options] <package>; see $0 --help\n");
if ( not defined $cache->{$packagename} ) {
die("No such package: $packagename\n");
}
if ( $cache->{$packagename}->{Flags} =~ /Essential/ ) {
print "Essential: Yes\n";
}
recurse( $packagename, 0 );
__END__
=head1 NAME
apt-why - filtered reverse dependency displayer using AptPkg::Cache
=head1 SYNOPSIS
B<apt-why> [ I<options> ] I<package>
=head1 DESCRIPTION
B<apt-why> recursively displays I<package>'s reverse dependencies, thus
showing which installed packages require I<package> on the system.
=head1 OPTIONS
=over
=item B<--all>
Consider all packages, not just installed ones
=item B<--depth>=I<integer> (default: 5)
Specify the maximum recursion depth
=item B<--deptype>=I<types>
Only show reverse dependencies which mach the specified I<types> (comma separated list).
Right now, possible types are Depends, Suggests, Recommends.
=back
=head1 EXIT STATUS
Zero on success, non-zero on error (i.e. no such package).
=head1 CONFIGURATION
None.
=head1 DEPENDENCIES
This program requires the perl module B<AptPkg::Cache>. On Debian, it is
available via the package B<libapt-pkg-perl>.
=head1 BUGS AND LIMITATIONS
There may be problems with virtual packages and "Provides: " stuff.
=head1 AUTHOR
Daniel Friesel E<lt>derf@finalrewind.orgE<gt>
=head1 LICENSE
0. You just DO WHAT THE FUCK YOU WANT TO.
|