]> git.donarmstrong.com Git - dak.git/commitdiff
Merge remote branch 'drkranz/overrides' into merge
authorJoerg Jaspert <joerg@debian.org>
Mon, 10 Jan 2011 21:37:54 +0000 (22:37 +0100)
committerJoerg Jaspert <joerg@debian.org>
Mon, 10 Jan 2011 21:37:54 +0000 (22:37 +0100)
* drkranz/overrides:
  Move more objects into get_packages_from_ftp()
  Pipes ftw!
  Add dak override-disparity command to cron.daily
  override_disparity.py: display YAML output
  Move common code to the new get_packages_from_ftp()
  override_disparity.py: generate a list of override disparities
  override.py: check override compliance
  ls.py: let -a source display sources only (#458186)

Signed-off-by: Joerg Jaspert <joerg@debian.org>
config/debian/cron.daily
dak/dak.py
dak/ls.py
dak/override.py
dak/override_disparity.py [new file with mode: 0755]
daklib/utils.py

index 5b4335684f6c97eaca0cd6e5a4f3b98dffec378f..0e7f7da4e580ebcff42c4ab5a3dba48e32c4a315 100755 (executable)
@@ -35,4 +35,7 @@ reports
 
 clean_debbugs
 
+# Generate list of override disparities
+dak override-disparity | gzip -9 > ${webdir}/override-disparity.gz
+
 ################################################################################
index cdb0331f7afb56f95533e2ab39064c67fd54f2f8..fb0021024505b971819647ba7c155e57a49e9fee 100755 (executable)
@@ -146,6 +146,8 @@ def init():
          "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
 
index 85ad4905214114c6a4d89a0fe40437c575d2a40d..66e8d42751eba2714779610939a05f7a4704800d 100755 (executable)
--- a/dak/ls.py
+++ b/dak/ls.py
@@ -150,7 +150,10 @@ SELECT s.source, s.version, 'source', su.suite_name, c.name, m.name
    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:
index d280aa8b4427205f39ff61736182f3e527502e15..75edbb580f88d11cef0e5022821b41c023c42a76 100755 (executable)
@@ -49,21 +49,76 @@ def usage (exit_code=0):
 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"):
@@ -171,6 +226,9 @@ def main ():
     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:
diff --git a/dak/override_disparity.py b/dak/override_disparity.py
new file mode 100755 (executable)
index 0000000..fd3bc50
--- /dev/null
@@ -0,0 +1,142 @@
+#!/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()
index 1756f58fa2d27132a3675a95716ab4404cf9a898..b5e090da3eb24324f89307fedff7920928115d4c 100755 (executable)
@@ -1571,3 +1571,41 @@ def parse_wnpp_bug_file(file = "/srv/ftp-master.debian.org/scripts/masterfiles/w
                 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