clean_debbugs
+# Generate list of override disparities
+dak override-disparity | gzip -9 > ${webdir}/override-disparity.gz
+
################################################################################
"Generate changelog between two suites"),
("copy-installer",
"Copies the installer from one suite to another"),
+ ("override-disparity",
+ "Generate a list of override disparities"),
]
return functionality
AND s.file = f.id AND f.location = l.id AND l.component = c.id
AND s.maintainer = m.id %s
""" % (comparison_operator, con_suites), {'package': package})
- ql.extend(q.fetchall())
+ if not Options["Architecture"] or con_architectures:
+ ql.extend(q.fetchall())
+ else:
+ ql = q.fetchall()
d = {}
highver = {}
for i in ql:
Make microchanges or microqueries of the binary overrides
-h, --help show this help and exit
+ -c, --check chech override compliance
-d, --done=BUG# send priority/section change as closure to bug#
-n, --no-action don't do anything
-s, --suite specify the suite to use
"""
sys.exit(exit_code)
+def check_override_compliance(package, priority, suite, cnf, session):
+ print "Checking compliance with related overrides..."
+
+ depends = set()
+ rdepends = set()
+ components = cnf.ValueList("Suite::%s::Components" % suite)
+ arches = set([x.arch_string for x in get_suite_architectures(suite)])
+ arches -= set(["source", "all"])
+ for arch in arches:
+ for component in components:
+ Packages = utils.get_packages_from_ftp(cnf['Dir::Root'], suite, component, arch)
+ while Packages.Step():
+ package_name = Packages.Section.Find("Package")
+ dep_list = Packages.Section.Find("Depends")
+ if dep_list:
+ if package_name == package:
+ for d in apt_pkg.ParseDepends(dep_list):
+ for i in d:
+ depends.add(i[0])
+ else:
+ for d in apt_pkg.ParseDepends(dep_list):
+ for i in d:
+ if i[0] == package:
+ rdepends.add(package_name)
+
+ query = """SELECT o.package, p.level, p.priority
+ FROM override o
+ JOIN suite s ON s.id = o.suite
+ JOIN priority p ON p.id = o.priority
+ WHERE s.suite_name = '%s'
+ AND o.package in ('%s')""" \
+ % (suite, "', '".join(depends.union(rdepends)))
+ packages = session.execute(query)
+
+ excuses = []
+ for p in packages:
+ if p[0] == package or not p[1]:
+ continue
+ if p[0] in depends:
+ if priority.level < p[1]:
+ excuses.append("%s would have priority %s, its dependency %s has priority %s" \
+ % (package, priority.priority, p[0], p[2]))
+ if p[0] in rdepends:
+ if priority.level > p[1]:
+ excuses.append("%s would have priority %s, its reverse dependency %s has priority %s" \
+ % (package, priority.priority, p[0], p[2]))
+
+ if excuses:
+ for ex in excuses:
+ print ex
+ else:
+ print "Proposed override change complies with Debian Policy"
+
def main ():
cnf = Config()
Arguments = [('h',"help","Override::Options::Help"),
+ ('c',"check","Override::Options::Check"),
('d',"done","Override::Options::Done", "HasArg"),
('n',"no-action","Override::Options::No-Action"),
('s',"suite","Override::Options::Suite", "HasArg"),
]
- for i in ["help", "no-action"]:
+ for i in ["help", "check", "no-action"]:
if not cnf.has_key("Override::Options::%s" % (i)):
cnf["Override::Options::%s" % (i)] = ""
if not cnf.has_key("Override::Options::Suite"):
if oldpriority == 'source' and newpriority != 'source':
utils.fubar("Trying to change priority of a source-only package")
+ if Options["Check"] and newpriority != oldpriority:
+ check_override_compliance(package, p, suite, cnf, session)
+
# If we're in no-action mode
if Options["No-Action"]:
if newpriority != oldpriority:
--- /dev/null
+#!/usr/bin/env python
+
+"""
+Generate a list of override disparities
+
+@contact: Debian FTP Master <ftpmaster@debian.org>
+@copyright: 2010 Luca Falavigna <dktrkranz@debian.org>
+@license: GNU General Public License version 2 or later
+"""
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+################################################################################
+
+# <adsb> Yay bugzilla *sigh*
+# <phil> :)
+# <Ganneff> quick, replace the bts with it
+# * jcristau replaces dak with soyuz
+# <adsb> and expects Ganneff to look after it?
+# <jcristau> nah, elmo can do that
+# * jcristau hides
+
+################################################################################
+
+import os
+import sys
+import apt_pkg
+import yaml
+
+from daklib.config import Config
+from daklib.dbconn import *
+from daklib import utils
+
+################################################################################
+
+def usage (exit_code=0):
+ print """Generate a list of override disparities
+
+ Usage:
+ dak override-disparity [-f <file>] [ -p <package> ] [ -s <suite> ]
+
+Options:
+
+ -h, --help show this help and exit
+ -f, --file store output into given file
+ -p, --package limit check on given package only
+ -s, --suite choose suite to look for (default: unstable)"""
+
+ sys.exit(exit_code)
+
+def main():
+ cnf = Config()
+ Arguments = [('h','help','Override-Disparity::Options::Help'),
+ ('f','file','Override-Disparity::Options::File','HasArg'),
+ ('s','suite','Override-Disparity::Options::Suite','HasArg'),
+ ('p','package','Override-Disparity::Options::Package','HasArg')]
+
+ for i in ['help', 'package']:
+ if not cnf.has_key('Override-Disparity::Options::%s' % (i)):
+ cnf['Override-Disparity::Options::%s' % (i)] = ''
+ if not cnf.has_key('Override-Disparity::Options::Suite'):
+ cnf['Override-Disparity::Options::Suite'] = 'unstable'
+
+ apt_pkg.ParseCommandLine(cnf.Cnf, Arguments, sys.argv)
+ Options = cnf.SubTree('Override-Disparity::Options')
+
+ if Options['help']:
+ usage()
+
+ depends = {}
+ session = DBConn().session()
+ suite = Options['suite']
+ components = cnf.ValueList('Suite::%s::Components' % suite)
+ arches = set([x.arch_string for x in get_suite_architectures(suite)])
+ arches -= set(['source', 'all'])
+ for arch in arches:
+ for component in components:
+ Packages = utils.get_packages_from_ftp(cnf['Dir::Root'], suite, component, arch)
+ while Packages.Step():
+ package = Packages.Section.Find('Package')
+ dep_list = Packages.Section.Find('Depends')
+ if Options['package'] and package != Options['package']:
+ continue
+ if dep_list:
+ for d in apt_pkg.ParseDepends(dep_list):
+ for i in d:
+ if not depends.has_key(package):
+ depends[package] = set()
+ depends[package].add(i[0])
+
+ priorities = {}
+ query = """SELECT DISTINCT o.package, p.level, p.priority, m.name
+ FROM override o
+ JOIN suite s ON s.id = o.suite
+ JOIN priority p ON p.id = o.priority
+ JOIN binaries b ON b.package = o.package
+ JOIN maintainer m ON m.id = b.maintainer
+ JOIN bin_associations ba ON ba.bin = b.id
+ WHERE s.suite_name = '%s'
+ AND ba.suite = s.id
+ AND p.level <> 0""" % suite
+ packages = session.execute(query)
+
+ out = {}
+ if Options.has_key('file'):
+ outfile = file(os.path.expanduser(Options['file']), 'w')
+ else:
+ outfile = sys.stdout
+ for p in packages:
+ priorities[p[0]] = [p[1], p[2], p[3], True]
+ for d in sorted(depends.keys()):
+ for p in depends[d]:
+ if priorities.has_key(d) and priorities.has_key(p):
+ if priorities[d][0] < priorities[p][0]:
+ if priorities[d][3]:
+ if not out.has_key(d):
+ out[d] = {}
+ out[d]['priority'] = priorities[d][1]
+ out[d]['maintainer'] = priorities[d][2]
+ out[d]['priority'] = priorities[d][1]
+ priorities[d][3] = False
+ if not out[d].has_key('dependency'):
+ out[d]['dependency'] = {}
+ out[d]['dependency'][p] = priorities[p][1]
+ yaml.dump(out, outfile, default_flow_style=False)
+ if Options.has_key('file'):
+ outfile.close()
+
+if __name__ == '__main__':
+ main()
bugs.append(bug_no)
wnpp[source] = bugs
return wnpp
+
+################################################################################
+
+def get_packages_from_ftp(root, suite, component, architecture):
+ """
+ Returns an object containing apt_pkg-parseable data collected by
+ aggregating Packages.gz files gathered for each architecture.
+
+ @type root: string
+ @param root: path to ftp archive root directory
+
+ @type suite: string
+ @param suite: suite to extract files from
+
+ @type component: string
+ @param component: component to extract files from
+
+ @type architecture: string
+ @param architecture: architecture to extract files from
+
+ @rtype: TagFile
+ @return: apt_pkg class containing package data
+
+ """
+ filename = "%s/dists/%s/%s/binary-%s/Packages.gz" % (root, suite, component, architecture)
+ (fd, temp_file) = temp_filename()
+ (result, output) = commands.getstatusoutput("gunzip -c %s > %s" % (filename, temp_file))
+ if (result != 0):
+ fubar("Gunzip invocation failed!\n%s\n" % (output), result)
+ filename = "%s/dists/%s/%s/debian-installer/binary-%s/Packages.gz" % (root, suite, component, architecture)
+ if os.path.exists(filename):
+ (result, output) = commands.getstatusoutput("gunzip -c %s >> %s" % (filename, temp_file))
+ if (result != 0):
+ fubar("Gunzip invocation failed!\n%s\n" % (output), result)
+ packages = open_file(temp_file)
+ Packages = apt_pkg.ParseTagFile(packages)
+ os.unlink(temp_file)
+ return Packages