- obey versions in provides/requires
authorMichael Schröder <mls@suse.de>
Mon, 12 Mar 2007 12:05:18 +0000 (12:05 +0000)
committerMichael Schröder <mls@suse.de>
Mon, 12 Mar 2007 12:05:18 +0000 (12:05 +0000)
Build.pm
Build/Deb.pm
Build/Rpm.pm

index e9c196e..8b8539d 100644 (file)
--- a/Build.pm
+++ b/Build.pm
@@ -239,14 +239,14 @@ sub get_runscripts {
 sub readdeps {
   my ($config, $pkgidp, @depfiles) = @_;
 
-  my %provides = ();
+  my %rprovides = ();
   my %requires = ();
   local *F;
-  my %prov;
+  my %provides;
   for my $depfile (@depfiles) {
     if (ref($depfile) eq 'HASH') {
       for my $rr (keys %$depfile) {
-       $prov{$rr} = $depfile->{$rr}->{'provides'};
+       $provides{$rr} = $depfile->{$rr}->{'provides'};
        $requires{$rr} = $depfile->{$rr}->{'requires'};
       }
       next;
@@ -269,6 +269,7 @@ sub readdeps {
        }
        push @ss, shift @s;
        if (@s && $s[0] =~ /^[<=>]/) {
+         $ss[-1] .= " $s[0] $s[1]";
          shift @s;
          shift @s;
        }
@@ -278,7 +279,7 @@ sub readdeps {
       if ($s =~ s/^P:(.*):$/$1/) {
        my $pkgid = $s;
        $s =~ s/-[^-]+-[^-]+-[^-]+$//;
-       $prov{$s} = \@ss; 
+       $provides{$s} = \@ss; 
        $pkgidp->{$s} = $pkgid if $pkgidp;
       } elsif ($s =~ s/^R:(.*):$/$1/) {
        my $pkgid = $s;
@@ -289,26 +290,78 @@ sub readdeps {
     }
     close F;
   }
-  for my $p (keys %prov) {
-    push @{$provides{$_}}, $p for unify(@{$prov{$p}});
-  }
-  my @ors = grep {/\|/} map {@$_} values %requires;
-  @ors = unify(@ors) if @ors > 1;
-  for my $or (@ors) {
-    my @p = map {@{$provides{$_} || []}} split(/\|/, $or);
-    @p = unify(@p) if @p > 1;
-    $provides{$or} = \@p;
+  for my $p (keys %provides) {
+    my @pp = @{$provides{$p}};
+    s/[ <=>].*// for @pp;
+    push @{$rprovides{$_}}, $p for unify(@pp);
   }
   $config->{'providesh'} = \%provides;
+  $config->{'rprovidesh'} = \%rprovides;
   $config->{'requiresh'} = \%requires;
 }
 
 sub forgetdeps {
   my $config;
   delete $config->{'providesh'};
+  delete $config->{'rprovidesh'};
   delete $config->{'requiresh'};
 }
 
+my %addproviders_fm = (
+  '>'  => 1,
+  '='  => 2,
+  '>=' => 3,
+  '<'  => 4,
+  '<=' => 6,
+);
+
+sub addproviders {
+  my ($config, $r) = @_;
+
+  my @p;
+  my $rprovides = $config->{'rprovidesh'};
+  $rprovides->{$r} = \@p;
+  if ($r =~ /\|/) {
+    for my $or (split(/\s*\|\s*/, $r)) {
+      push @p, @{$rprovides->{$or} || addproviders($config, $or)};
+    }
+    @p = unify(@p) if @p > 1;
+    return \@p;
+  }
+  return \@p if $r !~ /^(.*?)\s*([<=>]{1,2})\s*(.*?)$/;
+  my $rn = $1;
+  my $rv = $3;
+  my $rf = $addproviders_fm{$2};
+  return \@p unless $rf;
+  my $provides = $config->{'providesh'};
+  my @rp = @{$rprovides->{$rn} || []};
+  for my $rp (@rp) {
+    for my $pp (@{$provides->{$rp} || []}) {
+      if ($pp eq $rn) {
+       push @p, $rp;
+       last;
+      }
+      next unless $pp =~ /^\Q$rn\E\s*([<=>]{1,2})\s*(.*?)$/;
+      my $pv = $2;
+      my $pf = $addproviders_fm{$1};
+      next unless $pf;
+      if ($pf & $rf & 5) {
+       push @p, $rp;
+       last;
+      }
+      my $rr = $rf == 2 ? $pf : ($rf ^ 5);
+      $rr &= 5 unless $pf & 2;
+      my $vv = Build::Rpm::verscmp($pv, $rv, 1);
+      if ($rr & (1 << ($vv + 1))) {
+       push @p, $rp;
+       last;
+      }
+    }
+  }
+  @p = unify(@p) if @p > 1;
+  return \@p;
+}
+
 sub expand {
   my ($config, @p) = @_;
 
@@ -316,7 +369,7 @@ sub expand {
   my $prefer = $config->{'preferh'};
   my $ignore = $config->{'ignoreh'};
 
-  my $provides = $config->{'providesh'};
+  my $rprovides = $config->{'rprovidesh'};
   my $requires = $config->{'requiresh'};
 
   my %xignore = map {substr($_, 1) => 1} grep {/^-/} @p;
@@ -337,9 +390,10 @@ sub expand {
     my @rerror = ();
     for my $p (splice @p) {
       for my $r (@{$requires->{$p} || [$p]}) {
-       next if $ignore->{"$p:$r"} || $xignore{"$p:$r"};
-       next if $ignore->{$r} || $xignore{$r};
-       my @q = @{$provides->{$r} || []};
+        my $ri = (split(/[ <=>]/, $r, 2))[0];
+       next if $ignore->{"$p:$ri"} || $xignore{"$p:$ri"};
+       next if $ignore->{$ri} || $xignore{$ri};
+       my @q = @{$rprovides->{$r} || addproviders($config, $r)};
        next if grep {$p{$_}} @q;
        next if grep {$xignore{$_}} @q;
        next if grep {$ignore->{"$p:$_"} || $xignore{"$p:$_"}} @q;
@@ -371,9 +425,9 @@ sub expand {
        if (@q > 1 && $r =~ /\|/) {
            # choice op, implicit prefer of first match...
            my %pq = map {$_ => 1} @q;
-           for my $rr (split(/\|/, $r)) {
-               next unless $provides->{$rr};
-               my @pq = grep {$pq{$_}} @{$provides->{$rr}};
+           for my $rr (split(/\s*\|\s*/, $r)) {
+               next unless $rprovides->{$rr};
+               my @pq = grep {$pq{$_}} @{$rprovides->{$rr}};
                next unless @pq;
                @q = @pq;
                last;
@@ -414,12 +468,13 @@ sub expand {
 
 sub add_all_providers {
   my ($config, @p) = @_;
-  my $provides = $config->{'providesh'};
+  my $rprovides = $config->{'rprovidesh'};
   my $requires = $config->{'requiresh'};
   my %a;
   for my $p (@p) {
     for my $r (@{$requires->{$p} || [$p]}) {
-      $a{$_} = 1 for @{$provides->{$r} || []};
+      my $rn = (split(' ', $r, 2))[0];
+      $a{$_} = 1 for @{$rprovides->{$rn} || []};
     }
   }
   push @p, keys %a;
index 11be8d0..1b296c7 100644 (file)
@@ -185,14 +185,16 @@ sub query {
   my $src = $name;
   $src = $res{'SOURCE'} if $res{'SOURCE'};
   my @provides = split(',\s*', $res{'PROVIDES'} || '');
-  s/\s.*// for @provides;      #for now
-  push @provides, $name unless grep {$_ eq $name} @provides;
+  push @provides, "$name = $res{'VERSION'}" unless grep {/^\Q$name\E(?: |$)/} @provides;
   my @depends = split(',\s*', $res{'DEPENDS'} || '');
   my @predepends = split(',\s*', $res{'PRE-DEPENDS'} || '');
   push @depends, @predepends;
-  s/\s.*// for @provides;      #for now
-  s/\|\s*/\|/g for @depends;   #for now
-  s/\s[^\|]*//g for @depends;  #for now
+  s/ \(([^\)]*)\)/ $1/g for @provides;
+  s/ \(([^\)]*)\)/ $1/g for @depends;
+  s/>>/>/g for @provides;
+  s/<</</g for @provides;
+  s/>>/>/g for @depends;
+  s/<</</g for @depends;
   my $data = {
     name => $name,
     hdrmd5 => $res{'CONTROL_MD5'},
index ec72db5..1a9c95e 100644 (file)
@@ -576,7 +576,7 @@ sub rpmq {
   return %res;
 }
 
-sub rpmq_add_flagsvers {
+sub add_flagsvers {
   my $res = shift;
   my $name = shift;
   my $flags = shift;
@@ -629,7 +629,7 @@ sub verscmp_part {
       return -1 if $x1 eq '' || $x2 eq '';
       $r = $x1 cmp $x2;
     }
-    return $r if $r;
+    return $r > 0 ? 1 : -1 if $r;
     if ($s1 eq '') {
       return $s2 eq '' ? 0 : -1;
     }
@@ -638,23 +638,25 @@ sub verscmp_part {
 }
 
 sub verscmp {
-  my ($s1, $s2) = @_;
+  my ($s1, $s2, $dtest) = @_;
 
   return 0 if $s1 eq $s2;
   my ($e1, $v1, $r1) = $s1 =~ /^(?:(\d+):)?(.*?)(?:-([^-]*))?$/s;
   $e1 = 0 unless defined $e1;
-  $r1 = '' unless defined $r1;
   my ($e2, $v2, $r2) = $s2 =~ /^(?:(\d+):)?(.*?)(?:-([^-]*))?$/s;
   $e2 = 0 unless defined $e2;
-  $r2 = '' unless defined $r2;
   if ($e1 ne $e2) {
     my $r = verscmp_part($e1, $e2);
     return $r if $r;
   }
+  return 0 if $dtest && ($v1 eq '' || $v2 eq '');
   if ($v1 ne $v2) {
     my $r = verscmp_part($v1, $v2);
     return $r if $r;
   }
+  $r1 = '' unless defined $r1;
+  $r2 = '' unless defined $r2;
+  return 0 if $dtest && ($r1 eq '' || $r2 eq '');
   if ($r1 ne $r2) {
     return verscmp_part($r1, $r2);
   }
@@ -669,6 +671,8 @@ sub query {
   my $src = $res{'SOURCERPM'}->[0];
   $src = '' unless defined $src;
   $src =~ s/-[^-]*-[^-]*\.[^\.]*\.rpm//;
+  add_flagsvers(\%res, 'PROVIDENAME', 'PROVIDEFLAGS', 'PROVIDEVERSION');
+  add_flagsvers(\%res, 'REQUIRENAME', 'REQUIREFLAGS', 'REQUIREVERSION');
   my $data = {
     name => $res{'NAME'}->[0],
     hdrmd5 => unpack('H32', $res{'SIGTAG_MD5'}->[0]),