#!/usr/bin/perl -w
# Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2015 Kevin Ryde
#
# This file is part of apt-reverse.
#
# apt-reverse is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3, or (at your option) any later
# version.
#
# apt-reverse is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with apt-reverse. If not, see .
use 5.004; # or AptPkg itself is 5.005_62 or some such
use strict;
use AptPkg::Config;
use AptPkg::Cache;
use Getopt::Long;
use vars '$VERSION';
$VERSION = 5;
# uncomment this to run the ### lines
# use Smart::Comments;
my $option_all = 0;
my $option_descriptions = 0;
my $option_installed = 0;
my $option_version = 0;
GetOptions('all|a' => \$option_all,
'descriptions|d' => \$option_descriptions,
'installed|i' => \$option_installed,
'version' => sub {
print "apt-reverse version $main::VERSION\n";
exit 0;
},
'help|?' => sub {
print "apt-reverse [--options] package...\n";
print " -a, --all show all usages, meaning Suggests and Recommends too\n";
print " -d, --descriptions print descriptions of depending packages\n";
print " -i, --installed print only installed depending packages\n";
print " --help print this help\n";
print " --version print program version number\n";
exit 0;
}) or exit 1;
unless (@ARGV) {
print "Usage: apt-reverse [--options] package...\n";
print "run \"apt-reverse --help\" for a summary of the options\n";
exit 1;
}
{
## no critic (ProtectPrivateVars)
$AptPkg::Config::_config->init;
$AptPkg::Config::_config->{'quiet'} = 2; # supress cache building messages
$AptPkg::System::_system = $AptPkg::Config::_config->system;
}
my $cache = AptPkg::Cache->new; # AptPkg::Cache
my $pkgrecords = $cache->packages; # AptPkg::PkgRecords
for my $pack (@ARGV)
{
my $p = $cache->{$pack}; # AptPkg::Cache::Package
unless ($p) {
warn "apt-reverse: don't know anything about package: $pack\n";
next;
}
my $revdeps = $p->{'RevDependsList'};
if (! $revdeps) {
# print " (no reverse depends)\n";
next;
}
my @revdeps = sort
{$a->{'ParentPkg'}{'Name'} cmp $b->{'ParentPkg'}{'Name'}} @$revdeps;
my $prev_parent = '';
for my $r (@revdeps) {
my $parent = $r->{'ParentPkg'}{'Name'};
# avoid duplicate versions of the same package
next if ($parent eq $prev_parent);
$prev_parent = $parent;
if ($option_installed) {
my $pp = $cache->{$parent};
next if (! defined $pp->{'CurrentVer'});
}
my $type;
if ($r->{'DepType'} eq 'Depends') {
$type = '';
} elsif (! $option_all) {
next;
} elsif ($r->{'DepType'} eq 'Conflicts'
|| $r->{'DepType'} eq 'Replaces'
|| $r->{'DepType'} eq 'Suggests') {
next;
} elsif (defined ($r->{'TargetVer'})) {
$type = " ($r->{'DepType'} $r->{'CompType'} $r->{'TargetVer'})";
} else {
$type = " ($r->{'DepType'})";
}
my $pr = $cache->packages()->lookup($parent);
my $str = $pr->{'ShortDesc'};
if ($option_descriptions) {
my $href = $pkgrecords->lookup($parent);
### $href
if ($href && $href->{'LongDesc'}) {
$str = $href->{'LongDesc'};
}
}
print "$parent$type - $str\n";
}
}
exit 0;
__END__
=for stopwords ie gnuplot AptPkg Ryde online
=head1 NAME
apt-reverse -- list packages which depend on (ie. use) a given package
=head1 SYNOPSIS
apt-reverse [--options] package...
=head1 DESCRIPTION
C lists all the packages which depend on those given on the
command line. These are the "reverse dependencies". For example
apt-reverse gnuplot
might print
battery-stats - Collects statistics about charge of laptop batteries
feedgnuplot - Pipe-oriented frontend to Gnuplot
gausssum - parse and display Gaussian, GAMESS, and etc's output
libgraphics-gnuplotif-perl - dynamic Perl interface to gnuplot
which means each of those packages needs gnuplot. Options below allow
"Suggests" and "Recommends" to be included too, or restrict to currently
installed packages.
This can find programming language interfaces to something (like the Perl
above). Or before deleting a package you might see what uses it, so keep it
if there's something of future interest which will need it.
=for mynotes -- patched here to /etc/bash_completion.d/apt-reverse for deb
An F is included with C for Bash tab
completion on package names and program options. It can be used with or
without the "bash_completion" system.
=head1 OPTIONS
The command line options are
=over 4
=item -a, --all
Show all uses, which means Recommends and Suggests as well as plain Depends.
=item -d, --description
Print the long description of each package. This will require the usual apt
"Translations" files. If apt has no translations (Languages "none" in
F) then the long descriptions are empty.
The default is the one-line short description.
=item -i, --installed
Print only currently installed packages, not all in the database.
=item --help
Print some brief help information.
=item --version
Print the program version number and exit.
=back
=head1 PREREQUISITES
=over 4
=item *
AptPkg -- Perl interface to the apt database (Debian package
C)
=back
=head1 OTHER WAYS TO DO IT
C gives the same information, but without the
descriptions and not in the simple format of C.
C can do the same too, though again without the descriptions,
and oriented towards recursive "depends of depends" tracing.
=head1 SEE ALSO
=for mynotes -- patched here to /etc/bash_completion.d/apt-reverse for deb
L, L, L, F
=head1 HOME PAGE
http://user42.tuxfamily.org/apt-reverse/index.html
=head1 LICENSE
Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2015 Kevin Ryde
apt-reverse is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
apt-reverse is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along
with apt-reverse. If not, see .
=cut