| git.druid.rocks | index | druid520 | mp | src/ | conflicts.pl |
src/conflicts.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 set_pkgconf);
use mplib::util qw(fail ok bare_name);
use mplib::version qw(parse_dep_token);
use mplib::portformat qw(USE_NONE);
use mplib::resolve qw(init find_portdir pkgconf effective_conflicts);
my $flags = mplib::config::parse_flags(\@ARGV);
mplib::config::load($flags);
fail("conflicts needs a package name") unless @ARGV;
init();
# a "name:slot" argument only disambiguates WHICH port directory to read
# pkg_conflicts from -- $canon itself stays the bare name, since
# CONFLICTS= is always persisted/read under the bare name (mplib::util::
# pconf_lookup's own fallback), same reasoning as use.pl's identical
# $canon/$portdir split.
my $tok = parse_dep_token(shift @ARGV);
my $canon = bare_name($tok->{name});
my $portdir = find_portdir($canon, $tok->{slot}, $tok->{repo});
fail("port $canon not found") unless $portdir;
my $pc = pkgconf($portdir);
# no +token/-token args: read-only listing of this port's currently
# effective conflicts (its own declared pkg_conflicts, plus any
# CONFLICTS= override already in effect).
unless(@ARGV)
{
my @cur = grep { /\S/ } split ' ', effective_conflicts($canon, $pc);
fail("$canon has no conflicts") unless @cur;
print "$_\n" for @cur;
exit 0;
}
# +token/-token: toggle relative to whatever is CURRENTLY effective, then
# persist the resulting full set under this port's bare name. a token
# carries pkg_conflicts' own '!'/'!!' soft/hard markers as part of its
# literal name -- mplib::resolve::check_static_conflicts parses those the
# same way regardless of whether the token came from pkg_conflicts= or
# here -- so "+!!other-libc" adds a hard blocker the port itself never
# declared, and lifting a declared soft one needs the same leading '!'
# the declaration itself used ("-!somepkg", not "-somepkg").
my %en = map { $_ => 1 } grep { /\S/ } split ' ', effective_conflicts($canon, $pc);
for my $t (@ARGV)
{
if($t =~ /^\+(.+)$/) { $en{$1} = 1; }
elsif($t =~ /^-(.+)$/) { delete $en{$1}; }
else { fail("conflicts tokens must be +token or -token, got: $t"); }
}
my $result = join(' ', sort keys %en);
# USE_NONE (not undef/empty) for the empty case -- set_pkgconf treats an
# empty value as "no override, fall back to the declared default" same
# as every other config key, which would silently UNDO exactly the
# "-lastconflict" toggle that just ran, same reasoning as use.pl's
# identical USE_NONE round-trip.
set_pkgconf($canon, 'CONFLICTS', $result eq '' ? USE_NONE : $result);
ok("$canon CONFLICTS set to: " . ($result eq '' ? '(none)' : $result));