| git.druid.rocks | index | druid520 | mp | plugins/ | lint.pl |
plugins/lint.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(slot_key strip_flag_value);
use mplib::version qw(parse_dep_token);
use mplib::resolve qw(init find_portdir try_pkgconf all_ports);
use mplib::portformat qw(resolve_slot);
use mplib::portlint qw(lint_port);
# static, no-build checks against pkg.conf/add.sh/del.sh (legacy or
# class-based, resolve_port already merged either shape the same way) --
# every check in mplib::portlint exists because it's a real bug this tree
# actually shipped, caught only by an actual install/remove cycle. this
# is meant to catch the same class of thing BEFORE that, in seconds, no
# sandbox required. see mplib::portlint's own comments for exactly which
# port taught us each one.
#
# usage: mp lint [port...] -- no args: the whole tree.
# mp lint --min=<low|medium|high> -- only report at/above this
# severity (default: low, i.e.
# everything).
# mp lint --dir=<root> [port...] -- also search <root> (the same
# way CUSTOM_PORTS_DIR already
# is, first, ahead of every
# configured repo) -- lints a
# port scaffolded via "mp new
# --dir=<root>" before it's
# been added to any repo.
my $flags = mplib::config::parse_flags(\@ARGV);
mplib::config::load($flags);
my $dir = strip_flag_value(\@ARGV, 'dir');
$CFG->{CUSTOM_PORTS} = $dir if defined $dir;
init();
my %SEV_RANK = (low => 0, medium => 1, high => 2);
my $minsev = 0;
for(my $i = 0; $i < @ARGV; $i = $i + 1)
{
next unless $ARGV[$i] =~ /^--min=(low|medium|high)$/;
$minsev = $SEV_RANK{$1};
splice(@ARGV, $i, 1);
$i = $i - 1;
}
my @targets;
if(@ARGV)
{
@targets = map { my $tok = parse_dep_token($_); { name => $_, dir => find_portdir($tok->{name}, $tok->{slot}) } } @ARGV;
}
else
{
@targets = map { { name => "$_->{cat}/$_->{name}", dir => $_->{dir} } } all_ports();
}
my ($nports, $nfindings, $nhigh) = (0, 0, 0);
for my $t (@targets)
{
unless($t->{dir})
{
print "err: $t->{name}, no such port.\n";
next;
}
my $pc = try_pkgconf($t->{dir});
unless($pc)
{
print "err: $t->{name}, bad pkg.conf.\n";
next;
}
$nports = $nports + 1;
my $slot = resolve_slot($pc, $pc->{pkg_name});
my $canon = slot_key($pc->{pkg_name}, $slot);
my @findings = grep { $SEV_RANK{$_->{severity}} >= $minsev } lint_port($pc, $canon);
next unless @findings;
print "$t->{name}:\n";
for my $f (@findings)
{
$nfindings = $nfindings + 1;
$nhigh = $nhigh + 1 if $f->{severity} eq 'high';
print " [$f->{severity}] $f->{msg}\n";
}
}
print "\n$nfindings finding(s) across $nports port(s) checked" . ($nhigh ? " ($nhigh high)" : '') . ".\n";
exit(1) if $nhigh;