summaryrefslogtreecommitdiff
path: root/bin/apt-why
diff options
context:
space:
mode:
Diffstat (limited to 'bin/apt-why')
-rwxr-xr-xbin/apt-why147
1 files changed, 147 insertions, 0 deletions
diff --git a/bin/apt-why b/bin/apt-why
new file mode 100755
index 0000000..b9df057
--- /dev/null
+++ b/bin/apt-why
@@ -0,0 +1,147 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use AptPkg::Cache;
+use Switch;
+
+my $cache = AptPkg::Cache->new;
+my $packagename = pop or dir("No packagename given");
+my $query = shift || '';
+my $package = $cache->{$packagename};
+
+unless($package) {
+ print STDERR "E: Package not found: $packagename\n";
+ exit(100);
+}
+
+sub revdeps {
+ my $rdepsref = shift;
+ my $depsref;
+ my $parent;
+
+ foreach(@$rdepsref) {
+ undef($parent);
+ $parent->{name} = $_->{ParentPkg}{Name};
+ $parent->{ver} = $_->{ParentVer}{VerStr};
+ $parent->{current_state} = $cache->{$_->{ParentPkg}{Name}}->{CurrentState};
+ $parent->{selected_state} = $cache->{$_->{ParentPkg}{Name}}->{SelectedState};
+ $parent->{deptype} = $_->{DepType};
+ $parent->{targetname} = $_->{TargetPkg}{Name};
+ if ($_->{TargetVer}) {
+ $parent->{depsign} = $_;
+ $parent->{depver} = $_;
+ }
+ $depsref->{$parent->{name}} = $parent;
+ }
+ return($depsref);
+}
+
+sub why {
+ my $revdeps = revdeps(shift);
+ my $why;
+ foreach(keys(%$revdeps)) {
+ if ($revdeps->{$_}->{current_state} eq 'Installed' and $revdeps->{$_}->{deptype} !~ /^(Conflicts|Replaces|Obsoletes)$/) {
+ $why->{$_} = $revdeps->{$_};
+ }
+ }
+ return($why);
+}
+
+sub why_not {
+ my $revdeps = revdeps(shift);
+ my $why_not;
+ foreach(keys(%$revdeps)) {
+ if ($revdeps->{$_}->{current_state} eq 'Installed' and $revdeps->{$_}->{deptype} =~ /^(Conflicts|Replaces|Obsoletes)$/) {
+ $why_not->{$_} = $revdeps->{$_};
+ }
+ }
+ return($why_not);
+}
+
+sub short_states {
+ my $pkg = shift;
+ my $state = '';
+ switch($pkg->{selected_state}) {
+ case('Unkwnon') {
+ $state .= ' ';
+ } case('Install') {
+ $state .= 'i';
+ } case('Hold') {
+ $state .= 'h';
+ } case('DeInstall') {
+ $state .= 'r';
+ } case('Purge') {
+ $state .= 'p';
+ }
+ }
+ switch($pkg->{current_state}) {
+ case('Installed') {
+ $state .= 'i';
+ } case('UnPacked') {
+ $state .= 'u';
+ } case('HalfConfigured') {
+ $state .= 'f';
+ } case('HalfInstalled') {
+ $state .= 'h';
+ } case('ConfigFiles') {
+ $state .= 'c';
+ } case('NotInstalled') {
+ $state .= ' ';
+ }
+ }
+ return($state);
+}
+
+
+sub print_deps {
+ my $deps = shift;
+ foreach(keys(%$deps)) {
+ printf "%-2s %-30s %-15s %s\n", short_states($deps->{$_}), $deps->{$_}->{name}, $deps->{$_}->{deptype}, $deps->{$_}->{targetname};
+ }
+}
+
+if ($query eq 'not') {
+ print_deps(why_not($package->{RevDependsList}));
+} else {
+ print_deps(why($package->{RevDependsList}));
+}
+
+__END__
+
+=head1 NAME
+
+apt-perl - reverse dependency displayer using AptPkg::Cache
+
+=head1 SYNOPSIS
+
+B<apt-perl> I<command> I<package>
+
+=head1 DESCRIPTION
+
+B<apt-perl> displays various informations based on a I<package>s reverse
+dependencies
+
+The output is prefixed by two charactes, the former representing the desired
+package state, the latter the current state.
+
+The states are I<i>nstall, I<h>old, I<r>emove (deinstall), I<p>urge,
+I<u>npacked, halI<f> configured, I<h>alf installed, I<c>onfigfiles installed.
+An empty field means not installed.
+
+I<command> may be one of:
+
+=over
+
+=item why
+
+Show dependencies that justify the installation of a package
+
+=item why-not
+
+Show dependencies that prohibit the installation of a package
+
+=item rdeps
+
+Show all reverse dependencies of a package
+
+=back