From 4d15379ff67d213c08b94edca3634829436cb676 Mon Sep 17 00:00:00 2001 From: Torsten Werner Date: Sun, 30 Jan 2011 12:39:20 +0100 Subject: [PATCH] Re-Implement the bms check in cruft-report. Signed-off-by: Torsten Werner --- dak/cruft_report.py | 29 ++---------------- daklib/cruft.py | 70 +++++++++++++++++++++++++++++++++++++++++++ tests/dbtest_cruft.py | 33 ++++++++++++++++++++ 3 files changed, 105 insertions(+), 27 deletions(-) diff --git a/dak/cruft_report.py b/dak/cruft_report.py index fe9ba278..08d336d4 100755 --- a/dak/cruft_report.py +++ b/dak/cruft_report.py @@ -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" diff --git a/daklib/cruft.py b/daklib/cruft.py index 79787e26..baa5efe9 100644 --- a/daklib/cruft.py +++ b/daklib/cruft.py @@ -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 diff --git a/tests/dbtest_cruft.py b/tests/dbtest_cruft.py index 4fd2666d..27e321c7 100755 --- a/tests/dbtest_cruft.py +++ b/tests/dbtest_cruft.py @@ -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() -- 2.39.2