source_versions = {}
anais_output = ""
- duplicate_bins = {}
nfu_packages = {}
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
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
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"
from daklib.dbconn import *
from sqlalchemy import func
+from sqlalchemy.orm import object_session
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
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()