From 3d05b834adee59ae2a3036ca96e0dd0b8470cb9a Mon Sep 17 00:00:00 2001 From: Niels Thykier Date: Sun, 1 Apr 2018 10:32:12 +0000 Subject: [PATCH] Refactor logging of uninst Signed-off-by: Niels Thykier --- britney.py | 43 +++++++++++++++++++++++++++++-------------- britney2/utils.py | 25 +++++++++++++++---------- 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/britney.py b/britney.py index 9fbd65c..773e384 100755 --- a/britney.py +++ b/britney.py @@ -204,7 +204,7 @@ from britney2.policies.autopkgtest import AutopkgtestPolicy from britney2.utils import (old_libraries_format, undo_changes, compute_reverse_tree, possibly_compressed, read_nuninst, write_nuninst, write_heidi, - eval_uninst, newly_uninst, make_migrationitem, + format_and_log_uninst, newly_uninst, make_migrationitem, write_excuses, write_heidi_delta, write_controlfiles, old_libraries, is_nuninst_asgood_generous, clone_nuninst, check_installability, @@ -2283,8 +2283,10 @@ class Britney(object): self.output_write(" finish: [%s]\n" % ",".join( x.uvname for x in selected )) self.output_write("endloop: %s\n" % (self.eval_nuninst(self.nuninst_orig))) self.output_write(" now: %s\n" % (self.eval_nuninst(nuninst_last_accepted))) - self.output_write(eval_uninst(self.options.architectures, - newly_uninst(self.nuninst_orig, nuninst_last_accepted))) + format_and_log_uninst(self.output_logger, + self.options.architectures, + newly_uninst(self.nuninst_orig, nuninst_last_accepted) + ) self.output_write("\n") return (nuninst_last_accepted, maybe_rescheduled_packages) @@ -2355,8 +2357,10 @@ class Britney(object): self.output_write("easy: %s\n" % nuninst_end_str) if not force: - self.output_write(eval_uninst(self.options.architectures, - newly_uninst(nuninst_start, nuninst_end))) + format_and_log_uninst(self.output_logger, + self.options.architectures, + newly_uninst(nuninst_start, nuninst_end) + ) if force: # Force implies "unconditionally better" @@ -2381,9 +2385,16 @@ class Britney(object): self.output_write(" orig: %s\n" % self.eval_nuninst(self.nuninst_orig)) self.output_write(" end: %s\n" % nuninst_end_str) if force: - self.output_write("force breaks:\n") - self.output_write(eval_uninst(self.options.architectures, - newly_uninst(nuninst_start, nuninst_end))) + broken = newly_uninst(nuninst_start, nuninst_end) + if broken: + self.output_logger.warning("force breaks:") + format_and_log_uninst(self.output_logger, + self.options.architectures, + broken, + loglevel=logging.WARNING, + ) + else: + self.output_logger.info("force did not break any packages") self.output_write("SUCCESS (%d/%d)\n" % (len(actions or self.upgrade_me), len(extra))) self.nuninst_orig = nuninst_end self.all_selected += selected @@ -2562,12 +2573,16 @@ class Britney(object): def printuninstchange(self): self.logger.info("Checking for newly uninstallable packages") - text = eval_uninst(self.options.architectures, newly_uninst( - self.nuninst_orig_save, self.nuninst_orig)) - - if text != '': - self.output_write("\nNewly uninstallable packages in testing:\n%s" % \ - (text)) + uninst = newly_uninst(self.nuninst_orig_save, self.nuninst_orig) + + if uninst: + self.output_logger.warning("") + self.output_logger.warning("Newly uninstallable packages in testing:") + format_and_log_uninst(self.output_logger, + self.options.architectures, + uninst, + loglevel=logging.WARNING, + ) def hint_tester(self): """Run a command line interface to test hints diff --git a/britney2/utils.py b/britney2/utils.py index 105f0de..5a74e40 100644 --- a/britney2/utils.py +++ b/britney2/utils.py @@ -23,6 +23,7 @@ import apt_pkg import errno +import logging import os import sys import time @@ -234,28 +235,32 @@ def newly_uninst(nuold, nunew): "nunew" from the statistic "nuold". It returns a dictionary with the architectures as keys and the list - of uninstallable packages as values. + of uninstallable packages as values. If there are no regressions + on a given architecture, then the architecture will be omitted in + the result. Accordingly, if none of the architectures have + regressions an empty directory is returned. """ res = {} for arch in ifilter_only(nunew, nuold): - res[arch] = [x for x in nunew[arch] if x not in nuold[arch]] + arch_nuninst = [x for x in nunew[arch] if x not in nuold[arch]] + # Leave res empty if there are no newly uninst packages + if arch_nuninst: + res[arch] = arch_nuninst return res -def eval_uninst(architectures, nuninst): - """Return a string which represents the uninstallable packages - - This method returns a string which represents the uninstallable - packages reading the uninstallability statistics "nuninst". +def format_and_log_uninst(logger, architectures, nuninst, *, loglevel=logging.INFO): + """Emits the uninstallable packages to the log An example of the output string is: * i386: broken-pkg1, broken-pkg2 + + Note that if there is no uninstallable packages, then nothing is emitted. """ - parts = [] for arch in architectures: if arch in nuninst and nuninst[arch]: - parts.append(" * %s: %s\n" % (arch,", ".join(sorted(nuninst[arch])))) - return "".join(parts) + msg = " * %s: %s" % (arch, ", ".join(sorted(nuninst[arch]))) + logger.log(loglevel, msg) def write_heidi(filename, sources_t, packages_t, *, outofsync_arches=frozenset(), sorted=sorted):