| git.druid.rocks | index | druid520 | mp | src/ | why.pl |
src/why.pl
#!/usr/bin/env perl
use v5.16;
use strict;
use warnings FATAL => 'all';
use FindBin;
use lib "$FindBin::Bin";
use mplib::config qw($CFG);
use mplib::util qw(fail note split_slot_key spin_start spin_tick spin_stop);
use mplib::db qw(read_db);
use mplib::resolve qw(init find_portdir try_pkgconf effective_deps resolve_dep_name resolved_db_key);
my $flags = mplib::config::parse_flags(\@ARGV);
mplib::config::load($flags);
fail("why needs a package name") unless @ARGV;
init();
my $db = read_db();
# resolved_db_key (falling back to the raw name if it isn't installed at
# all): a bare name for a slotted package needs to resolve to its actual
# installed canon, the same way $inst's own dependencies get normalized
# below, or the two never compare equal.
my $canon = resolved_db_key($ARGV[0], $db) // $ARGV[0];
my $hit = 0;
spin_start("resolving dependencies...");
for my $inst (sort keys %$db)
{
spin_tick();
# $inst is a raw db key, possibly slotted ("name:slot") -- find_portdir
# needs the slot split off and passed separately, or it never finds a
# slotted installed package's directory at all, silently skipping
# every one of its dependencies (so a slotted package that genuinely
# depends on the target was never even considered).
my ($base, $slot) = split_slot_key($inst);
my $dir = find_portdir($base, $slot);
next unless $dir;
my $pc = try_pkgconf($dir);
next unless $pc;
for my $d (effective_deps($pc, $inst))
{
my $target = resolve_dep_name($d, $inst, $db);
next unless defined $target;
my $tkey = resolved_db_key($target, $db) // $target;
if($tkey eq $canon)
{
# stop before the first hit prints, not only after the
# whole loop: several installed packages can all depend
# on the target, so a hit can print mid-scan -- stopping
# cleanly here avoids the spinner's own "\r" fighting
# with this line on the same terminal. harmless to leave
# it stopped for whatever's left to scan (spin_tick/
# spin_stop are both no-ops once inactive).
spin_stop();
print "$inst\n";
$hit = 1;
last;
}
}
}
spin_stop();
note("nothing installed depends on $canon") unless $hit;