>From a0250c645646b934d96722167982274bc747e589 Mon Sep 17 00:00:00 2001
From: Karsten Hopp <karsten@redhat.com>
Date: Fri, 20 Jun 2014 14:49:39 +0200
Subject: [PATCH] show top blocking packages

Signed-off-by: Karsten Hopp <karsten@redhat.com>
---
 util/koji-shadow | 47 +++++++++++++++++++++++++++++++++++------------
 1 file changed, 35 insertions(+), 12 deletions(-)

diff --git a/util/koji-shadow b/util/koji-shadow
index bdf3ce3..37bdee6 100755
--- a/util/koji-shadow
+++ b/util/koji-shadow
@@ -20,6 +20,7 @@
 # Authors:
 #       Mike McLean <mikem@redhat.com>
 #       Dennis Gilmore <dennis@ausil.us>
+#       Karsten Hopp <karsten@redhat.com>
 
 try:
     import krbV
@@ -1093,17 +1094,17 @@ class BuildTracker(object):
         return task_id
 
     def report(self):
-        print "-- %s --" % time.asctime()
-        self.report_brief()
+        brokenpackage = {}
+        thispackageblocks = {}
         for state in ('broken', 'noroot', 'blocked'):
             builds = self.state_idx[state].values()
             not_replaced = [b for b in builds if not b.substitute]
             n_replaced = len(builds) - len(not_replaced)
-            print "%s: %i (+%i replaced)" % (state, len(not_replaced), n_replaced)
-            if not_replaced and len(not_replaced) < 8:
-                print '', ' '.join([b.nvr for b in not_replaced])
-        #generate a report of the most frequent problem deps
-        problem_counts = {}
+            for b in not_replaced:
+                if not b.nvr in brokenpackage:
+                    brokenpackage.update({b.nvr:[b.nvr]})
+                else:
+                    brokenpackage[b.nvr].append(b.nvr)
         for build in self.state_idx['brokendeps'].values():
             for dep_id in build.deps:
                 dep = self.builds.get(dep_id)
@@ -1124,15 +1125,36 @@ class BuildTracker(object):
                         continue
                     #otherwise the substitution is the problem
                     nvr = dep.substitute
-                problem_counts.setdefault(nvr, 0)
-                problem_counts[nvr] += 1
-        order = [(c, nvr) for (nvr, c) in problem_counts.iteritems()]
+                    if dep.state == 'broken':
+                        brokenpackage[dep.nvr].append(build.nvr)
+                    elif dep.state == 'brokendeps':
+                        found = 0
+                        for i in brokenpackage:
+                            if dep.nvr in brokenpackage[i]:
+                                brokenpackage[i] += [build.nvr]
+                                found = 1
+                        if found == 0:
+                            if not dep.nvr in thispackageblocks:
+                                thispackageblocks.update({dep.nvr:[build.nvr]})
+                            else:
+                                thispackageblocks[dep.nvr].append(build.nvr)
+        # group all brokendeps
+        for package in thispackageblocks:
+            for blockedpackage in thispackageblocks:
+                if package in thispackageblocks[blockedpackage]:
+                    thispackageblocks[blockedpackage] += thispackageblocks[package]
+        for package in brokenpackage:
+        # Remove duplicates, use 'set' as order isn't important:
+            brokenpackage[package] = set(brokenpackage[package])
+            # Enable to get a verbose list of all packages that are blocked by this package:
+            # print "brokenpackage: %s %s" % (package, brokenpackage[package])
+        order = [(len(c), nvr) for (nvr, c) in brokenpackage.iteritems()]
         if order:
             order.sort()
             order.reverse()
-            #print top 5 problems
+            #print top problems
             print "-- top problems --"
-            for (c, nvr) in order[:5]:
+            for (c, nvr) in order[:10]:
                 print " %s (%i)" % (nvr, c)
 
     def report_brief(self):
@@ -1247,6 +1269,7 @@ class BuildTracker(object):
             if (not self.state_idx['missing'] and not self.state_idx['pending']) or \
                (options.prefer_new and not self.state_idx['pending']):
                 #we're done
+                self.report()
                 break
             changed1 = self.checkJobs(tag)
             changed2 = self.rebuildMissing()
-- 
1.8.3.1

