sub readdeps {
my ($config, $pkginfo, @depfiles) = @_;
+ local *F;
my %requires = ();
my %recommends = ();
- local *F;
+ my %supplements = ();
my %provides;
+
my $dofileprovides = %{$config->{'fileprovides'}};
for my $depfile (@depfiles) {
if (ref($depfile) eq 'HASH') {
$provides{$rr} = $depfile->{$rr}->{'provides'};
$requires{$rr} = $depfile->{$rr}->{'requires'};
$recommends{$rr} = $depfile->{$rr}->{'recommends'};
+ $supplements{$rr} = $depfile->{$rr}->{'supplements'};
}
next;
}
}
my %ss;
@ss = grep {!$ss{$_}++} @ss;
- if ($s =~ /^(P|R|r):(.*)\.(.*)-\d+\/\d+\/\d+:$/) {
+ if ($s =~ /^(P|R|r|s):(.*)\.(.*)-\d+\/\d+\/\d+:$/) {
my $pkgid = $2;
my $arch = $3;
if ($1 eq "R") {
$pkginfo->{$pkgid}->{'recommends'} = \@ss if $pkginfo;
next;
}
+ if ($1 eq "s") {
+ $supplements{$pkgid} = \@ss;
+ $pkginfo->{$pkgid}->{'supplements'} = \@ss if $pkginfo;
+ next;
}
}
}
$config->{'providesh'} = \%provides;
$config->{'requiresh'} = \%requires;
$config->{'recommendsh'} = \%recommends;
+ $config->{'supplementsh'} = \%supplements;
makewhatprovidesh($config);
}
print $fh "F:$id$url$pkg->{'location'}\n";
print $fh "P:$id".join(' ', @{$pkg->{'provides'} || []})."\n";
print $fh "R:$id".join(' ', @{$pkg->{'requires'}})."\n" if $pkg->{'requires'};
- print $fh "r:$id".join(' ', @{$pkg->{'recommends'}})."\n" if $pkg->{'recommends'};
print $fh "C:$id".join(' ', @{$pkg->{'conflicts'}})."\n" if $pkg->{'conflicts'};
print $fh "O:$id".join(' ', @{$pkg->{'obsoletes'}})."\n" if $pkg->{'obsoletes'};
+ print $fh "r:$id".join(' ', @{$pkg->{'recommends'}})."\n" if $pkg->{'recommends'};
+ print $fh "s:$id".join(' ', @{$pkg->{'supplements'}})."\n" if $pkg->{'supplements'};
print $fh "I:$id".getbuildid($pkg)."\n";
}
delete $config->{'whatprovidesh'};
delete $config->{'requiresh'};
delete $config->{'recommendsh'};
+ delete $config->{'supplementsh'};
}
my %addproviders_fm = (
return \@p;
}
+sub todo2recommended {
+ my ($config, $recommended, $todo) = @_;
+ my $whatprovides = $config->{'whatprovidesh'};
+ my $pkgrecommends = $config->{'recommendsh'} || {};
+ for my $p (splice @$todo) {
+ for my $r (@{$pkgrecommends->{$p} || []}) {
+ $recommended->{$_} = 1 for @{$whatprovides->{$r} || addproviders($config, $r)}
+ }
+ }
+}
+
sub expand {
my ($config, @p) = @_;
my $conflicts = $config->{'conflicth'};
my $prefer = $config->{'preferh'};
my $ignore = $config->{'ignoreh'};
+ my $ignoreignore;
+ my $userecommendsforchoices = 1;
my $whatprovides = $config->{'whatprovidesh'};
my $requires = $config->{'requiresh'};
- my $recommends = $config->{'recommendsh'};
my %xignore = map {substr($_, 1) => 1} grep {/^-/} @p;
@p = grep {!/^-/} @p;
+ my %aconflicts; # packages we are conflicting with
+ for (grep {/^!/} @p) {
+ my $r = /^!!/ ? substr($_, 2) : substr($_, 1);
+ my @q = @{$whatprovides->{$r} || addproviders($config, $r)};
+ @q = nevrmatch($config, $r, @q) if /^!!/;
+ $aconflicts{$_} = "is in BuildConflicts" for @q;
+ }
+ my %recommended; # recommended by installed packages
+ my @rec_todo; # installed todo
+
+ @p = grep {!/^[-!]/} @p;
my %p; # expanded packages
my %aconflicts; # packages we are conflicting with
print "added $q[0] because of $p (direct dep)\n" if $expand_dbg;
push @p, $q[0];
$p{$q[0]} = 1;
- $aconflicts{$_} = 1 for @{$conflicts->{$q[0]} || []};
+ $aconflicts{$_} = "conflict from project config with $q[0]" for @{$conflicts->{$q[0]} || []};
+ if (!$ignoreconflicts) {
+ for my $r (@{$pkgconflicts->{$q[0]}}) {
+ $aconflicts{$_} = "conflicts with installed $q[0]" for @{$whatprovides->{$r} || addproviders($config, $r)};
+ }
+ }
+ push @rec_todo, $q[0] if $userecommendsforchoices;
}
my @pamb = ();
last;
}
}
- if (@q > 1 && $config->{"buildflags:userecommendsforchoices"} && @{$recommends->{$p} || []} > 0) {
- my @recommendedq;
- my $i;
-
- for my $iq (@q) {
- for my $rpkg (@{$recommends->{$p}}) {
- if ($rpkg =~ /$iq/) {
- push @recommendedq, $iq;
- }
- }
- }
- if (@recommendedq > 0) {
- print "recommended [@recommendedq] among [@q]\n" if $expand_dbg;
- @q = @recommendedq;
- }
+ if ($doamb == 2) {
+ todo2recommended($config, \%recommended, \@rec_todo) if @rec_todo;
+ my @pq = grep {$recommended{$_}} @q;
+ print "recommended [@pq] among [@q]\n" if $expand_dbg;
+ @q = @pq if @pq;
}
if (@q > 1) {
if ($r ne $p) {
push @p, $q[0];
print "added $q[0] because of $p:$r\n" if $expand_dbg;
$p{$q[0]} = 1;
- $aconflicts{$_} = 1 for @{$conflicts->{$q[0]} || []};
+ $aconflicts{$_} = "conflict from project config with $q[0]" for @{$conflicts->{$q[0]} || []};
+ if (!$ignoreconflicts) {
+ for my $r (@{$pkgconflicts->{$q[0]}}) {
+ $aconflicts{$_} = "conflicts with installed $q[0]" for @{$whatprovides->{$r} || addproviders($config, $r)};
+ }
+ }
+ push @rec_todo, $q[0] if $userecommendsforchoices;
@error = ();
$doamb = 0;
}
next if @p; # still work to do
# only ambig stuff left
- if (@pamb && !$doamb) {
+ if (@pamb && ($doamb == 0 || $doamb == 1)) {
@p = @pamb;
@pamb = ();
- $doamb = 1;
- print "now doing undecided dependencies\n" if $expand_dbg;
+ todo2recommended($config, \%recommended, \@rec_todo) if @rec_todo;
+ $doamb = %recommended ? 2 : 3;
+ print "now doing undecided dependencies, $doamb = $doamb\n" if $expand_dbg;
next;
}
return undef, @error if @error;
push @archs, 'noarch' unless grep {$_ eq 'noarch'} @archs;
}
-my (%fn, %prov, %req, %rec);
+my (%fn, %prov, %req, %rec, %sup);
my %packs;
my %repo;
my %exportfilters = %{$cf->{'exportfilter'}};
open(F, '<', $rpmdeps) || die("$rpmdeps: $!\n");
# WARNING: the following code assumes that the 'I' tag comes last
-my ($pkgF, $pkgP, $pkgR, $pkgr);
+my ($pkgF, $pkgP, $pkgR, $pkgr, $pkgs);
while(<F>) {
chomp;
if (/^F:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
$req{$1} = $2;
} elsif (/^r:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
$pkgr = $2;
+ } elsif (/^s:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
+ $pkgs = $2;
} elsif (/^I:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
my $r = 0;
if ($usehigherdeps) {
$prov{$i} = $pkgP;
$req{$i} = $pkgR;
$rec{$i} = $pkgr;
+ $sup{$i} = $pkgs
}
} else {
next if $ids{$1};
undef $pkgP;
undef $pkgR;
undef $pkgr;
+ undef $pkgs;
} elsif ($_ eq 'D:') {
%packs_done = %ids;
}
}
for my $pack (keys %packs) {
my $r = {};
- my (@s, $s, @pr, @re, @rc);
+ my (@s, $s, @pr, @re, @rc, @su);
@s = split(' ', $prov{$packs{$pack}} || '');
while (@s) {
$s = shift @s;
$r->{'provides'} = \@pr;
$r->{'requires'} = \@re;
$r->{'recommends'} = \@rc;
+ $r->{'supplements'} = \@su;
$repo{$pack} = $r;
}