]> err.no Git - dak/commitdiff
Re-Implement the bms check in cruft-report.
authorTorsten Werner <twerner@debian.org>
Sun, 30 Jan 2011 11:39:20 +0000 (12:39 +0100)
committerTorsten Werner <twerner@debian.org>
Sun, 30 Jan 2011 18:19:16 +0000 (19:19 +0100)
Signed-off-by: Torsten Werner <twerner@debian.org>
dak/cruft_report.py
daklib/cruft.py
tests/dbtest_cruft.py

index fe9ba278d18c5f20d9f62b678c5960f921160ae5..08d336d4466ea41fcef987c49a9fa105006e8b45 100755 (executable)
@@ -551,7 +551,6 @@ def main ():
     source_versions = {}
 
     anais_output = ""
-    duplicate_bins = {}
 
     nfu_packages = {}
 
@@ -599,18 +598,10 @@ def main ():
             if "anais" in checks:
                 anais_output += do_anais(architecture, binaries_list, source, session)
 
-            # Check for duplicated packages and build indices for checking "no source" later
+            # build indices for checking "no source" later
             source_index = component + '/' + source
-            #if src_pkgs.has_key(source):
-            #    print " %s is a duplicated source package (%s and %s)" % (source, source_index, src_pkgs[source])
             src_pkgs[source] = source_index
             for binary in binaries_list:
-                if bin_pkgs.has_key(binary):
-                    key_list = [ source, bin_pkgs[binary] ]
-                    key_list.sort()
-                    key = '_'.join(key_list)
-                    duplicate_bins.setdefault(key, [])
-                    duplicate_bins[key].append(binary)
                 bin_pkgs[binary] = source
             source_binaries[source] = binaries
             source_versions[source] = source_version
@@ -667,14 +658,6 @@ def main ():
                     nbs[source].setdefault(package, {})
                     nbs[source][package][version] = ""
                 else:
-                    previous_source = bin_pkgs[package]
-                    if previous_source != source:
-                        key_list = [ source, previous_source ]
-                        key_list.sort()
-                        key = '_'.join(key_list)
-                        duplicate_bins.setdefault(key, [])
-                        if package not in duplicate_bins[key]:
-                            duplicate_bins[key].append(package)
                     if "nfu" in checks:
                         if package in nfu_entries and \
                                version != source_versions[source]: # only suggest to remove out-of-date packages
@@ -722,15 +705,7 @@ def main ():
         print
 
     if "bms" in checks:
-        print "Built from multiple source packages"
-        print "-----------------------------------"
-        print
-        keys = duplicate_bins.keys()
-        keys.sort()
-        for key in keys:
-            (source_a, source_b) = key.split("_")
-            print " o %s & %s => %s" % (source_a, source_b, ", ".join(duplicate_bins[key]))
-        print
+        report_multiple_source(suite)
 
     if "anais" in checks:
         print "Architecture Not Allowed In Source"
index 79787e26cc81ab120cfc1af5f7504f0ef544ed0c..baa5efe9a1ca98f132902ff5ea7802e3861f25ea 100644 (file)
@@ -24,6 +24,7 @@ helper functions for cruft-report
 from daklib.dbconn import *
 
 from sqlalchemy import func
+from sqlalchemy.orm import object_session
 
 def newer_version(lowersuite_name, highersuite_name, session):
     '''
@@ -48,3 +49,72 @@ def newer_version(lowersuite_name, highersuite_name, session):
             list.append((source, higherversion, lowerversion))
     return list
 
+def get_package_names(suite):
+    '''
+    Returns a query that selects all distinct package names from suite ordered
+    by package name.
+    '''
+
+    session = object_session(suite)
+    return session.query(DBBinary.package).with_parent(suite). \
+        group_by(DBBinary.package).order_by(DBBinary.package)
+
+class NamedSource(object):
+    '''
+    A source package identified by its name with all of its versions in a
+    suite.
+    '''
+    def __init__(self, suite, source):
+        self.source = source
+        query = suite.sources.filter_by(source = source). \
+            order_by(DBSource.version)
+        self.versions = [src.version for src in query]
+
+    def __str__(self):
+        return "%s(%s)" % (self.source, ", ".join(self.versions))
+
+class DejavuBinary(object):
+    '''
+    A binary package identified by its name which gets built by multiple source
+    packages in a suite. The architecture is ignored which leads to the
+    following corner case, e.g.:
+
+    If a source package 'foo-mips' that builds a binary package 'foo' on mips
+    and another source package 'foo-mipsel' builds a binary package with the
+    same name 'foo' on mipsel then the binary package 'foo' will be reported as
+    built from multiple source packages.
+    '''
+
+    def __init__(self, suite, package):
+        self.package = package
+        session = object_session(suite)
+        # We need a subquery to make sure that both binary and source packages
+        # are in the right suite.
+        bin_query = suite.binaries.filter_by(package = package).subquery()
+        src_query = session.query(DBSource.source).with_parent(suite). \
+            join(bin_query).group_by(DBSource.source)
+        self.sources = []
+        if src_query.count() > 1:
+            for source, in src_query:
+                self.sources.append(str(NamedSource(suite, source)))
+
+    def has_multiple_sources(self):
+        'Has the package been built by multiple sources?'
+        return len(self.sources) > 1
+
+    def __str__(self):
+        return "%s built by: %s" % (self.package, ", ".join(self.sources))
+
+def report_multiple_source(suite):
+    '''
+    Reports binary packages built from multiple source package with different
+    names.
+    '''
+
+    print "Built from multiple source packages"
+    print "-----------------------------------"
+    print
+    for package, in get_package_names(suite):
+        binary = DejavuBinary(suite, package)
+        if binary.has_multiple_sources():
+            print binary
index 4fd2666db141d4c4be6245d8fcfc5a895ce020fc..27e321c77917dd76f86f73436f8bcdfb1f14aadf 100755 (executable)
@@ -33,5 +33,38 @@ class CruftTestCase(DBDakTestCase):
         list = newer_version('squeeze', 'sid', self.session)
         self.assertEqual([('sl', '3.03-16', '3.03-17')], list)
 
+    def test_multiple_source(self):
+        'tests functions related to report_multiple_source()'
+
+        # test get_package_names()
+        suite = get_suite('sid', self.session)
+        self.assertEqual([('gnome-hello', ), ('hello', )], \
+            get_package_names(suite).all())
+        # test class NamedSource
+        src = NamedSource(suite, 'hello')
+        self.assertEqual('hello', src.source)
+        self.assertEqual(['2.2-1', '2.2-2'], src.versions)
+        self.assertEqual('hello(2.2-1, 2.2-2)', str(src))
+        # test class DejavuBinary
+        bin = DejavuBinary(suite, 'hello')
+        self.assertEqual(False, bin.has_multiple_sources())
+        # add another binary
+        self.file['hello_2.2-3'] = PoolFile(filename = 'main/s/sl/hello_2.2-3_i386.deb', \
+            location = self.loc['main'], filesize = 0, md5sum = '')
+        self.binary['hello_2.2-3_i386'] = DBBinary(package = 'hello', \
+            source = self.source['sl_3.03-16'], version = '2.2-3', \
+            maintainer = self.maintainer['maintainer'], \
+            architecture = self.arch['i386'], \
+            poolfile = self.file['hello_2.2-3'])
+        self.session.add(self.binary['hello_2.2-3_i386'])
+        bin = DejavuBinary(suite, 'hello')
+        self.assertEqual(False, bin.has_multiple_sources())
+        # add it to suite sid
+        self.binary['hello_2.2-3_i386'].suites.append(self.suite['sid'])
+        bin = DejavuBinary(suite, 'hello')
+        self.assertEqual(True, bin.has_multiple_sources())
+        self.assertEqual('hello built by: hello(2.2-1, 2.2-2), sl(3.03-16)', \
+            str(bin))
+
 if __name__ == '__main__':
     unittest.main()