From 5b5c99e401d6eddc3e082f1a8d876ed00dffc31b Mon Sep 17 00:00:00 2001 From: Iain Lane Date: Tue, 28 Jul 2020 10:52:03 +0100 Subject: [PATCH] excuse, excusefinder: Allow excuses to invalidate each other Sometimes (for the LinuxPolicy), excuses don't have enough information when they are processed. They need to defer some of their work until another excuse has been evaluated and then perhaps get invalidated. Introduce the concept of "external invalidation" to deal with this. A policy can keep references to other excuses around, and then invalidate them later (when processing another one). The excuse finder needs to know this happened to remove the excuse from the list of "actionable excuses". For example. The Linux policy invalidates linux-foo if linux-meta-foo is invalid. If linux-foo is encountered first, we will not yet know if linux-meta-foo is going to be invalid. We effectively defer the evaluation until after linux-meta-foo has been dealt with, and then we know whether we need to invalidate linux-foo or not. --- britney2/excuse.py | 24 ++++++++++++++++++++++++ britney2/excusefinder.py | 3 +++ 2 files changed, 27 insertions(+) diff --git a/britney2/excuse.py b/britney2/excuse.py index b6e0026..01ab72a 100644 --- a/britney2/excuse.py +++ b/britney2/excuse.py @@ -156,6 +156,7 @@ class Excuse(object): self.hints = [] self.forced = False self._policy_verdict = PolicyVerdict.REJECTED_PERMANENTLY + self.invalidated_externally = False self.all_deps = [] self.break_deps = [] @@ -219,6 +220,29 @@ class Excuse(object): value = PolicyVerdict.PASS_HINTED self._policy_verdict = value + @property + def tentative_policy_verdict(self): + """If we've not finished running all of the policies, we can find out + what all of the policies that have run so far said.""" + all_verdicts = { + info["verdict"] + if isinstance(info["verdict"], PolicyVerdict) + else PolicyVerdict[info["verdict"]] + for info in self.policy_info.values() + } + + return max(all_verdicts) + + def invalidate_externally(self, verdict): + """A policy might want to invalidate an excuse other than the one it + is currently looking at, e.g. if it later learns of a fact that it + didn't know when it was processing the first excuse. + + We need to know, so that we can remove this excuse from the list of + actionable excuses.""" + self.policy_verdict = verdict + self.invalidated_externally = True + def set_vers(self, tver, uver): """Set the versions of the item from target and source suite""" if tver and uver: diff --git a/britney2/excusefinder.py b/britney2/excusefinder.py index 31ccdf4..ca6702d 100644 --- a/britney2/excusefinder.py +++ b/britney2/excusefinder.py @@ -520,6 +520,9 @@ class ExcuseFinder(object): if should_upgrade_srcarch(item): actionable_items_add(item) + # If anything was discarded by a different excuse, it's not actionable any more + actionable_items = {item for item in actionable_items if not self.excuses[item.name].invalidated_externally} + # process the `remove' hints, if the given package is not yet in actionable_items for hint in self.hints['remove']: src = hint.package