From: MyungJoo Ham Date: Thu, 27 Oct 2016 05:26:00 +0000 (+0900) Subject: Recognize Recommends relations of RPMs. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=aa1621c640f2da1b3362495b2f14feeb45e1916e;p=tools%2Fbuild.git Recognize Recommends relations of RPMs. When there are multiple candidate packages as a result of Provides, the current obs-build gives an error: "have choice for". However, according to http://www.rpm.org/wiki/PackagerDocs/Dependencies , Recommends tells the system to install the corresponding package unless there is a conflict; thus, if there is a package recommended (as described in issue #302), obs-build shall install the recommended package, resolving "have choice for" error. To enable, OBS project should declare: "BuildFlags: UseRecommendsForChoices=1" or "BuildFlags: UseRecommendsForChoices" in its project config. Fixes #302 Signed-off-by: MyungJoo Ham Conflicts: createdirdeps expanddeps Change-Id: I65dc6dd16a6874b7c1ae47932d37c23ec98b9cdf Conflicts: Build.pm createdirdeps expanddeps --- diff --git a/Build.pm b/Build.pm index c1ebe1c..8a0803c 100644 --- a/Build.pm +++ b/Build.pm @@ -488,6 +488,7 @@ sub readdeps { my ($config, $pkginfo, @depfiles) = @_; my %requires = (); + my %recommends = (); local *F; my %provides; my $dofileprovides = %{$config->{'fileprovides'}}; @@ -496,6 +497,7 @@ sub readdeps { for my $rr (keys %$depfile) { $provides{$rr} = $depfile->{$rr}->{'provides'}; $requires{$rr} = $depfile->{$rr}->{'requires'}; + $recommends{$rr} = $depfile->{$rr}->{'recommends'}; } next; } @@ -528,7 +530,7 @@ sub readdeps { } my %ss; @ss = grep {!$ss{$_}++} @ss; - if ($s =~ /^(P|R):(.*)\.(.*)-\d+\/\d+\/\d+:$/) { + if ($s =~ /^(P|R|r):(.*)\.(.*)-\d+\/\d+\/\d+:$/) { my $pkgid = $2; my $arch = $3; if ($1 eq "R") { @@ -547,6 +549,11 @@ sub readdeps { $pkginfo->{$pkgid}->{'release'} = $r if defined($r); $pkginfo->{$pkgid}->{'arch'} = $arch; $pkginfo->{$pkgid}->{'provides'} = \@ss; + if ($1 eq "r") { + $recommends{$pkgid} = \@ss; + $pkginfo->{$pkgid}->{'recommends'} = \@ss if $pkginfo; + next; + } } } } @@ -554,9 +561,39 @@ sub readdeps { } $config->{'providesh'} = \%provides; $config->{'requiresh'} = \%requires; + $config->{'recommendsh'} = \%recommends; makewhatprovidesh($config); } +sub getbuildid { + my ($q) = @_; + my $evr = $q->{'version'}; + $evr = "$q->{'epoch'}:$evr" if $q->{'epoch'}; + $evr .= "-$q->{'release'}" if defined $q->{'release'};; + my $buildtime = $q->{'buildtime'} || 0; + $evr .= " $buildtime"; + $evr .= "-$q->{'arch'}" if defined $q->{'arch'}; + return "$q->{'name'}-$evr"; +} + +sub writedeps { + my ($fh, $pkg, $url) = @_; + $url = '' unless defined $url; + return unless defined($pkg->{'name'}) && defined($pkg->{'arch'}); + return if $pkg->{'arch'} eq 'src' || $pkg->{'arch'} eq 'nosrc'; + my $id = $pkg->{'id'}; + $id = ($pkg->{'buildtime'} || 0)."/".($pkg->{'filetime'} || 0)."/0" unless $id; + $id = "$pkg->{'name'}.$pkg->{'arch'}-$id: "; + 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 "I:$id".getbuildid($pkg)."\n"; +} + +>>>>>>> d6ff6eb... Recognize Recommends relations of RPMs. sub makewhatprovidesh { my ($config) = @_; @@ -587,6 +624,7 @@ sub forgetdeps { delete $config->{'providesh'}; delete $config->{'whatprovidesh'}; delete $config->{'requiresh'}; + delete $config->{'recommendsh'}; } my %addproviders_fm = ( @@ -667,6 +705,7 @@ sub expand { my $whatprovides = $config->{'whatprovidesh'}; my $requires = $config->{'requiresh'}; + my $recommends = $config->{'recommendsh'}; my %xignore = map {substr($_, 1) => 1} grep {/^-/} @p; @p = grep {!/^-/} @p; @@ -745,6 +784,22 @@ 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 (@q > 1) { if ($r ne $p) { push @error, "have choice for $r needed by $p: @q"; @@ -782,6 +837,7 @@ sub order { my ($config, @p) = @_; my $requires = $config->{'requiresh'}; + my $recommends = $config->{'recommendsh'}; my $whatprovides = $config->{'whatprovidesh'}; my %deps; my %rdeps; @@ -879,6 +935,7 @@ sub add_all_providers { my ($config, @p) = @_; my $whatprovides = $config->{'whatprovidesh'}; my $requires = $config->{'requiresh'}; + my $recommends = $config->{'recommendsh'}; my %a; for my $p (@p) { for my $r (@{$requires->{$p} || [$p]}) { diff --git a/expanddeps b/expanddeps index 3a8d561..e3151d8 100755 --- a/expanddeps +++ b/expanddeps @@ -83,7 +83,7 @@ if ($spec =~ /(^|\/)PKGBUILD$/) { push @archs, 'noarch' unless grep {$_ eq 'noarch'} @archs; } -my (%fn, %prov, %req); +my (%fn, %prov, %req, %rec); 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); +my ($pkgF, $pkgP, $pkgR, $pkgr); while() { chomp; if (/^F:(.*?)-\d+\/\d+\/\d+: (.*)$/) { @@ -157,6 +157,8 @@ while() { $pkgR = $2; next if $req{$1}; $req{$1} = $2; + } elsif (/^r:(.*?)-\d+\/\d+\/\d+: (.*)$/) { + $pkgr = $2; } elsif (/^I:(.*?)-\d+\/\d+\/\d+: (.*)$/) { my $r = 0; if ($usehigherdeps) { @@ -178,6 +180,7 @@ while() { $fn{$i} = $pkgF; $prov{$i} = $pkgP; $req{$i} = $pkgR; + $rec{$i} = $pkgr; } } else { next if $ids{$1}; @@ -186,6 +189,7 @@ while() { undef $pkgF; undef $pkgP; undef $pkgR; + undef $pkgr; } elsif ($_ eq 'D:') { %packs_done = %ids; } @@ -197,7 +201,7 @@ for my $arch (@archs) { } for my $pack (keys %packs) { my $r = {}; - my (@s, $s, @pr, @re); + my (@s, $s, @pr, @re, @rc); @s = split(' ', $prov{$packs{$pack}} || ''); while (@s) { $s = shift @s; @@ -222,6 +226,7 @@ for my $pack (keys %packs) { } $r->{'provides'} = \@pr; $r->{'requires'} = \@re; + $r->{'recommends'} = \@rc; $repo{$pack} = $r; }