Also recored supplements, use recommends as choice breaker only in 3rd pass
authorMichael Schroeder <mls@suse.de>
Mon, 28 Nov 2016 12:59:20 +0000 (13:59 +0100)
committerSoonKyu Park <sk7.park@samsung.com>
Tue, 10 Jan 2017 10:47:11 +0000 (19:47 +0900)
Conflicts:
Build.pm
expanddeps

Change-Id: I0eee5303d2098bfc7a69f6ecda239db2263818e2

Conflicts:
Build.pm
createdirdeps
expanddeps

Build.pm
expanddeps

index 8a0803c4542c4343496b13ec76a0d74a32d8be6d..d0f24c69076257e9d10f0cc99f374bbb9b7090bd 100644 (file)
--- a/Build.pm
+++ b/Build.pm
@@ -487,10 +487,12 @@ sub get_cbinstalls { return @{[]}; }
 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') {
@@ -498,6 +500,7 @@ sub readdeps {
        $provides{$rr} = $depfile->{$rr}->{'provides'};
        $requires{$rr} = $depfile->{$rr}->{'requires'};
        $recommends{$rr} = $depfile->{$rr}->{'recommends'};
+       $supplements{$rr} = $depfile->{$rr}->{'supplements'};
       }
       next;
     }
@@ -530,7 +533,7 @@ sub readdeps {
       }
       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") {
@@ -554,6 +557,10 @@ sub readdeps {
          $pkginfo->{$pkgid}->{'recommends'} = \@ss if $pkginfo;
          next;
        }
+       if ($1 eq "s") {
+         $supplements{$pkgid} = \@ss;
+         $pkginfo->{$pkgid}->{'supplements'} = \@ss if $pkginfo;
+         next;
        }
       }
     }
@@ -562,6 +569,7 @@ sub readdeps {
   $config->{'providesh'} = \%provides;
   $config->{'requiresh'} = \%requires;
   $config->{'recommendsh'} = \%recommends;
+  $config->{'supplementsh'} = \%supplements;
   makewhatprovidesh($config);
 }
 
@@ -587,9 +595,10 @@ sub writedeps {
   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";
 }
 
@@ -625,6 +634,7 @@ sub forgetdeps {
   delete $config->{'whatprovidesh'};
   delete $config->{'requiresh'};
   delete $config->{'recommendsh'};
+  delete $config->{'supplementsh'};
 }
 
 my %addproviders_fm = (
@@ -696,20 +706,43 @@ sub addproviders {
   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
 
@@ -730,7 +763,13 @@ sub expand {
     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 = ();
@@ -784,21 +823,11 @@ sub expand {
                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) {
@@ -812,7 +841,13 @@ sub expand {
        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;
       }
@@ -821,11 +856,12 @@ sub expand {
     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;
index e3151d8dc3e09e06405bb87606669c7de0ebdcfb..25bc3d7a7e50378aac2b0c4682b572b7c5fbb451 100755 (executable)
@@ -83,7 +83,7 @@ if ($spec =~ /(^|\/)PKGBUILD$/) {
   push @archs, 'noarch' unless grep {$_ eq 'noarch'} @archs;
 }
 
-my (%fn, %prov, %req, %rec);
+my (%fn, %prov, %req, %rec, %sup);
 
 my %packs;
 my %repo;
@@ -127,7 +127,7 @@ my $dofileprovides = %{$cf->{'fileprovides'}};
 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+: (.*)$/) {
@@ -159,6 +159,8 @@ while(<F>) {
     $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) {
@@ -181,6 +183,7 @@ while(<F>) {
         $prov{$i} = $pkgP;
         $req{$i}  = $pkgR;
         $rec{$i}  = $pkgr;
+        $sup{$i}  = $pkgs
       }
     } else {
       next if $ids{$1};
@@ -190,6 +193,7 @@ while(<F>) {
     undef $pkgP;
     undef $pkgR;
     undef $pkgr;
+    undef $pkgs;
   } elsif ($_ eq 'D:') {
     %packs_done = %ids;
   }
@@ -201,7 +205,7 @@ for my $arch (@archs) {
 }
 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;
@@ -227,6 +231,7 @@ for my $pack (keys %packs) {
   $r->{'provides'} = \@pr;
   $r->{'requires'} = \@re;
   $r->{'recommends'} = \@rc;
+  $r->{'supplements'} = \@su;
   $repo{$pack} = $r;
 }