From b5285f21d7065733a32124dede229d11e152dc87 Mon Sep 17 00:00:00 2001
From: Ivo De Decker <ivodd@debian.org>
Date: Fri, 3 Jan 2020 20:13:36 +0000
Subject: [PATCH] Track packages (source and binary) for excuses

---
 britney2/excuse.py       | 19 +++++++++++++++++++
 britney2/excusefinder.py |  8 +++++++-
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/britney2/excuse.py b/britney2/excuse.py
index 6b4a60b..128b439 100644
--- a/britney2/excuse.py
+++ b/britney2/excuse.py
@@ -92,6 +92,17 @@ class Excuse(object):
         self.infoline = []
         self.detailed_info = []
 
+        # packages (source and binary) that will migrate to testing if the
+        # item from this excuse migrates
+        self.packages = defaultdict(set)
+
+        # for each deptype, there is a set that contains
+        # frozensets of PackageIds (of sources or binaries) that can satisfy
+        # the dep
+        self.depends_packages = defaultdict(set)
+        # contains all PackageIds in any over the sets above
+        self.depends_packages_flattened = set()
+
         self.bounty = {}
         self.penalty = {}
 
@@ -210,6 +221,14 @@ class Excuse(object):
     def add_hint(self, hint):
         self.hints.append(hint)
 
+    def add_package(self, pkg_id):
+        self.packages[pkg_id.architecture].add(pkg_id)
+
+    def add_package_depends(self, deptype, depends):
+        """depends is a set of PackageIds (source or binary) that can satisfy the dependency"""
+        self.depends_packages[deptype].add(frozenset(depends))
+        self.depends_packages_flattened |= depends
+
     def _format_verdict_summary(self):
         verdict = self._policy_verdict
         if verdict in VERDICT2DESC:
diff --git a/britney2/excusefinder.py b/britney2/excusefinder.py
index a7cb092..b4b43a1 100644
--- a/britney2/excusefinder.py
+++ b/britney2/excusefinder.py
@@ -3,7 +3,7 @@ from urllib.parse import quote
 
 import apt_pkg
 
-from britney2 import DependencyType
+from britney2 import DependencyType, PackageId
 from britney2.excuse import Excuse
 from britney2.policies import PolicyVerdict
 from britney2.utils import (invalidate_excuses, find_smooth_updateable_binaries, compute_item_name,
@@ -198,6 +198,8 @@ class ExcuseFinder(object):
         # for every binary package produced by this source in unstable for this architecture
         for pkg_id in sorted(x for x in source_u.binaries if x.architecture == arch):
             pkg_name = pkg_id.package_name
+            # TODO filter binaries based on checks below?
+            excuse.add_package(pkg_id)
 
             # retrieve the testing (if present) and unstable corresponding binary packages
             binary_t = packages_t_a[pkg_name] if pkg_name in packages_t_a else None
@@ -372,6 +374,7 @@ class ExcuseFinder(object):
         excuse.set_vers(source_t and source_t.version or None, source_u.version)
         source_u.maintainer and excuse.set_maint(source_u.maintainer)
         source_u.section and excuse.set_section(source_u.section)
+        excuse.add_package(PackageId(src, source_u.version, "source"))
 
         # if the version in unstable is older, then stop here with a warning in the excuse and return False
         if source_t and apt_pkg.version_compare(source_u.version, source_t.version) < 0:
@@ -438,6 +441,9 @@ class ExcuseFinder(object):
                 if binary_u.architecture != arch:
                     continue
 
+                # TODO filter binaries based on checks below?
+                excuse.add_package(pkg_id)
+
                 # if it wasn't built by the same source, it is out-of-date
                 # if there is at least one binary on this arch which is
                 # up-to-date, there is a build on this arch