[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[SCM] Debian package checker branch, master, updated. 2.5.11-65-gc084295



The following commit has been merged in the master branch:
commit c08429540979f450140c0cb94ebf7b7a82244676
Author: Niels Thykier <niels@thykier.net>
Date:   Tue Aug 7 15:08:50 2012 +0200

    L::Relation: Explicitly handle <pkg>:<arch> cases
    
    Extract and check the <arch> part of a relation.  The Multi-Arch
    spec[1] recommends assuming that if <arch> is present and not "any"
    that the relation is unsatisfiable.
      Beyond that it is vague on how the <arch> part is applied in
    practise (except that the package in the relation must be "Multi-Arch:
    allowed").
    
    This implementation assumes that if <arch> is present", the (only)
    identity holds.  i.e. "pkg:a" implies "pkg:b" iff a == b.
    
    This assumption is handy for identity relations and for finding
    duplicated relations, where the check relies on implication to find
    possible duplications.  However, it fails the cases where ":X" implies
    ":any" (for any valid value of X).
    
    [1] https://wiki.ubuntu.com/MultiarchSpec
    
    Signed-off-by: Niels Thykier <niels@thykier.net>

diff --git a/lib/Lintian/Relation.pm b/lib/Lintian/Relation.pm
index 1fe1c1d..f9e2543 100644
--- a/lib/Lintian/Relation.pm
+++ b/lib/Lintian/Relation.pm
@@ -103,29 +103,30 @@ sub parse_element {
           \$\{[a-zA-Z0-9:-]+\}          #   substvar
          )*                             #  zero or more portions or substvars
         )                               # end of package name or substvar
+        (?:[:]([a-z0-9-]+))?            # optional Multi-arch arch specification (2)
         (?:                             # start of optional version
          \s* \(                         # open parenthesis for version part
-         \s* (<<|<=|=|>=|>>|<|>)        # relation part (2)
-         \s* (.*?)                      # version (3)
+         \s* (<<|<=|=|>=|>>|<|>)        # relation part (3)
+         \s* (.*?)                      # version (4)
          \s* \)                         # closing parenthesis
         )?                              # end of optional version
         (?:                             # start of optional architecture
          \s* \[                         # open bracket for architecture
-         \s* (.*?)                      # architectures (4)
+         \s* (.*?)                      # architectures (5)
          \s* \]                         # closing bracket
         )?                              # end of optional architecture
     /x;
 
+    my ($pkgname, $march, $relop, $relver, $bdarch) = ($1, $2, $3, $4, $5);
     # If there's no version, we don't need to do any further processing.
     # Otherwise, convert the legacy < and > relations to the current ones.
-    return ['PRED', $1, undef, undef, $4] if not defined $2;
-    my $two = $2;
-    if ($two eq '<') {
-        $two = '<<';
-    } elsif ($two eq '>') {
-        $two = '>>';
+    return ['PRED', $pkgname, undef, undef, $bdarch, $march] if not defined $relop;
+    if ($relop eq '<') {
+        $relop = '<<';
+    } elsif ($relop eq '>') {
+        $relop = '>>';
     }
-    return ['PRED', $1, $two, $3, $4];
+    return ['PRED', $pkgname, $relop, $relver, $bdarch, $march];
 }
 
 
@@ -377,6 +378,29 @@ sub implies_element {
         }
     }
 
+    # Multi-arch architecture specification
+
+    # According to the spec, only the special value "any" is allowed
+    # and it is "recommended" to consider "other such package
+    # relations as unsatisfiable".  That said, there seem to be an
+    # interest in supporting ":<arch>" as well, so we will (probably)
+    # have to accept those as well.
+    #
+    # Other than that, we would need to know that the package has the
+    # field "Multi-arch: allowed", but we cannot check that here.  So
+    # we assume that it is okay.
+    #
+    # For now assert that only the identity holds.  In practise, the
+    # "pkg:X" (for any valid value of X) seems to imply "pkg:any",
+    # fixing that is a TODO (because version clauses complicates
+    # matters)
+    if (defined $$p[5]) {
+        # Assume the identity to hold
+        return unless defined $$q[5] and $$p[5] eq $$q[5];
+    } elsif (defined $$q[5]) {
+        return;
+    }
+
     # Now, down to version.  The implication is true if p's clause is stronger
     # than q's, or is equivalent.
 
@@ -650,6 +674,9 @@ sub unparse {
     my $relation = defined($partial) ? $partial : $self;
     if ($relation->[0] eq 'PRED') {
         my $text = $relation->[1];
+        if (defined $relation->[5]) {
+            $text .= ":$relation->[5]";
+        }
         if (defined $relation->[2]) {
             $text .= " ($relation->[2] $relation->[3])";
         }
diff --git a/t/scripts/Lintian/Relation/04-multiarch.t b/t/scripts/Lintian/Relation/04-multiarch.t
index 23675b3..6f94f15 100644
--- a/t/scripts/Lintian/Relation/04-multiarch.t
+++ b/t/scripts/Lintian/Relation/04-multiarch.t
@@ -2,11 +2,50 @@
 
 use strict;
 use warnings;
-use Test::More tests => 2;
+use Test::More tests => 12;
 
 use Lintian::Relation;
 
-my $relation = Lintian::Relation->new('pkgA:i386');
+my $orig = 'pkgA:any, pkgB, pkgC:i386';
+my $relation = Lintian::Relation->new ($orig);
 
-ok($relation->implies('pkgA:i386'),   'Same arch implies');
-ok($relation->implies('pkgA'),        'Archless implies');
+ok($relation->implies ('pkgA:any'),   'identity implies [pkgA]');
+
+ok($relation->implies ('pkgB'),       'identity implies [pkgB]');
+
+ok(! $relation->implies ('pkgC'),     'archless implies [pkgC]');
+ok($relation->implies ('pkgC:i386'),  'identity implies [pkgC]');
+
+TODO: {
+    local $TODO = ":X => :Y cases are not implemented";
+
+    ok($relation->implies ('pkgA'),       'archless implies [pkgA]');
+
+    ok($relation->implies ('pkgB:any'),   'arch any implies [pkgB]');
+
+    ok($relation->implies ('pkgC:any'),   'arch any implies [pkgC]');
+}
+
+
+is($relation->unparse, $orig,          'unparse eq original');
+
+my @dups1 =  Lintian::Relation->new ('pkgD, pkgD:any')->duplicates;
+my @dups2 =  Lintian::Relation->new ('pkgD:i386, pkgD:any')->duplicates;
+my @dups3 =  Lintian::Relation->new ('pkgD:i386, pkgD')->duplicates;
+my @dups4 =  Lintian::Relation->new ('pkgD:i386, pkgD:i386 (>= 1.0)')->duplicates;
+
+is_deeply(\@dups3, [],                                    'pkgD:i386 and pkgD are not dups');
+is_deeply(\@dups4, [['pkgD:i386', 'pkgD:i386 (>= 1.0)']], 'Can detect pkgD:i386 dups');
+
+TODO: {
+    local $TODO = ":X => :Y cases are not implemented";
+
+    is_deeply(\@dups1, [['pkgD', 'pkgD:any']],                'pkgD and pkgD:any are dups');
+    is_deeply(\@dups2, [['pkgD:i386', 'pkgD:any']],           'pkgD:i386 and pkgD:any are dups');
+}
+
+# Local Variables:
+# indent-tabs-mode: nil
+# cperl-indent-level: 4
+# End:
+# vim: syntax=perl sw=4 sts=4 sr et

-- 
Debian package checker


Reply to: