]> git.decadent.org.uk Git - dak.git/blob - daklib/cruft.py
silent map first
[dak.git] / daklib / cruft.py
1 """
2 helper functions for cruft-report
3
4 @contact: Debian FTPMaster <ftpmaster@debian.org>
5 @copyright 2011 Torsten Werner <twerner@debian.org>
6 """
7
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
12
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU General Public License for more details.
17
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
22 ################################################################################
23
24 from daklib.dbconn import *
25
26 from sqlalchemy import func
27 from sqlalchemy.orm import object_session
28
29 def newer_version(lowersuite_name, highersuite_name, session):
30     '''
31     Finds newer versions in lowersuite_name than in highersuite_name. Returns a
32     list of tuples (source, higherversion, lowerversion) where higherversion is
33     the newest version from highersuite_name and lowerversion is the newest
34     version from lowersuite_name.
35     '''
36
37     lowersuite = get_suite(lowersuite_name, session)
38     highersuite = get_suite(highersuite_name, session)
39
40     query = session.query(DBSource.source, func.max(DBSource.version)). \
41         with_parent(highersuite).group_by(DBSource.source)
42
43     list = []
44     for (source, higherversion) in query:
45         lowerversion = session.query(func.max(DBSource.version)). \
46             filter_by(source = source).filter(DBSource.version > higherversion). \
47             with_parent(lowersuite).group_by(DBSource.source).scalar()
48         if lowerversion is not None:
49             list.append((source, higherversion, lowerversion))
50     return list
51
52 def get_package_names(suite):
53     '''
54     Returns a query that selects all distinct package names from suite ordered
55     by package name.
56     '''
57
58     session = object_session(suite)
59     return session.query(DBBinary.package).with_parent(suite). \
60         group_by(DBBinary.package).order_by(DBBinary.package)
61
62 class NamedSource(object):
63     '''
64     A source package identified by its name with all of its versions in a
65     suite.
66     '''
67     def __init__(self, suite, source):
68         self.source = source
69         query = suite.sources.filter_by(source = source). \
70             order_by(DBSource.version)
71         self.versions = [src.version for src in query]
72
73     def __str__(self):
74         return "%s(%s)" % (self.source, ", ".join(self.versions))
75
76 class DejavuBinary(object):
77     '''
78     A binary package identified by its name which gets built by multiple source
79     packages in a suite. The architecture is ignored which leads to the
80     following corner case, e.g.:
81
82     If a source package 'foo-mips' that builds a binary package 'foo' on mips
83     and another source package 'foo-mipsel' builds a binary package with the
84     same name 'foo' on mipsel then the binary package 'foo' will be reported as
85     built from multiple source packages.
86     '''
87
88     def __init__(self, suite, package):
89         self.package = package
90         session = object_session(suite)
91         # We need a subquery to make sure that both binary and source packages
92         # are in the right suite.
93         bin_query = suite.binaries.filter_by(package = package).subquery()
94         src_query = session.query(DBSource.source).with_parent(suite). \
95             join(bin_query).order_by(DBSource.source).group_by(DBSource.source)
96         self.sources = []
97         if src_query.count() > 1:
98             for source, in src_query:
99                 self.sources.append(str(NamedSource(suite, source)))
100
101     def has_multiple_sources(self):
102         'Has the package been built by multiple sources?'
103         return len(self.sources) > 1
104
105     def __str__(self):
106         return "%s built by: %s" % (self.package, ", ".join(self.sources))
107
108 def report_multiple_source(suite):
109     '''
110     Reports binary packages built from multiple source package with different
111     names.
112     '''
113
114     print "Built from multiple source packages"
115     print "-----------------------------------"
116     print
117     for package, in get_package_names(suite):
118         binary = DejavuBinary(suite, package)
119         if binary.has_multiple_sources():
120             print binary
121     print