From bddac0a645a0d7cb90dc745e89590891e8b688c5 Mon Sep 17 00:00:00 2001 From: Christophe Monniez Date: Fri, 22 Dec 2023 10:01:26 +0100 Subject: [PATCH] [IMP] runbot: allow to choose the replacement string When defining cleaning regex, the replacement character is always the percent sign as it's hard coded in various methods. With this commit, a replacement string can be defined by cleaning regex and fallback to the percent sign by default. --- runbot/models/build_error.py | 13 +++++++------ runbot/models/ir_logging.py | 2 +- runbot/tests/test_build_error.py | 7 ++++++- runbot/views/build_error_views.xml | 2 ++ 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/runbot/models/build_error.py b/runbot/models/build_error.py index 1a1abeaf..a9b9acca 100644 --- a/runbot/models/build_error.py +++ b/runbot/models/build_error.py @@ -63,7 +63,7 @@ class BuildError(models.Model): cleaners = self.env['runbot.error.regex'].search([('re_type', '=', 'cleaning')]) for vals in vals_list: content = vals.get('content') - cleaned_content = cleaners._r_sub('%', content) + cleaned_content = cleaners._r_sub(content) vals.update({ 'cleaned_content': cleaned_content, 'fingerprint': self._digest(cleaned_content) @@ -170,7 +170,7 @@ class BuildError(models.Model): for log in ir_logs: if search_regs._r_search(log.message): continue - fingerprint = self._digest(cleaning_regs._r_sub('%', log.message)) + fingerprint = self._digest(cleaning_regs._r_sub(log.message)) hash_dict[fingerprint] |= log build_errors = self.env['runbot.build.error'] @@ -292,7 +292,7 @@ class BuildError(models.Model): changed_fingerprints = set() for build_error in self: fingerprint_before = build_error.fingerprint - build_error.cleaned_content = cleaning_regs._r_sub('%', build_error.content) + build_error.cleaned_content = cleaning_regs._r_sub(build_error.content) if fingerprint_before != build_error.fingerprint: changed_fingerprints.add(build_error.fingerprint) @@ -334,11 +334,12 @@ class ErrorRegex(models.Model): regex = fields.Char('Regular expression') re_type = fields.Selection([('filter', 'Filter out'), ('cleaning', 'Cleaning')], string="Regex type") sequence = fields.Integer('Sequence', default=100) + replacement = fields.Char('Replacement string', help="String used as a replacment in cleaning. '%' if not set") - def _r_sub(self, replace, s): - """ replaces patterns from the recordset by replace in the given string """ + def _r_sub(self, s): + """ replaces patterns from the recordset by replacement's or '%' in the given string """ for c in self: - s = re.sub(c.regex, '%', s) + s = re.sub(c.regex, c.replacement or '%', s) return s def _r_search(self, s): diff --git a/runbot/models/ir_logging.py b/runbot/models/ir_logging.py index cd59c015..c88140c3 100644 --- a/runbot/models/ir_logging.py +++ b/runbot/models/ir_logging.py @@ -55,7 +55,7 @@ class IrLogging(models.Model): for ir_logging in self: ir_logging.error_id = False if ir_logging.level in ('ERROR', 'CRITICAL', 'WARNING') and ir_logging.type == 'server': - fingerprints[self.env['runbot.build.error']._digest(cleaning_regexes._r_sub('%', ir_logging.message))].append(ir_logging) + fingerprints[self.env['runbot.build.error']._digest(cleaning_regexes._r_sub(ir_logging.message))].append(ir_logging) for build_error in self.env['runbot.build.error'].search([('fingerprint', 'in', list(fingerprints.keys()))], order='active asc'): for ir_logging in fingerprints[build_error.fingerprint]: ir_logging.error_id = build_error.id diff --git a/runbot/tests/test_build_error.py b/runbot/tests/test_build_error.py index 4cda4709..3bf0c7bd 100644 --- a/runbot/tests/test_build_error.py +++ b/runbot/tests/test_build_error.py @@ -113,7 +113,10 @@ class TestBuildError(RunbotCase): ko_build = self.create_test_build({'local_result': 'ok', 'local_state': 'testing'}) ok_build = self.create_test_build({'local_result': 'ok', 'local_state': 'running'}) - + cleaner = self.env['runbot.error.regex'].create({ + 'regex': '^FAIL: ', + 're_type': 'cleaning', + }) error_team = self.BuildErrorTeam.create({ 'name': 'test-error-team', @@ -143,6 +146,8 @@ class TestBuildError(RunbotCase): ok_build._parse_logs() build_error = self.BuildError.search([('build_ids', 'in', [ko_build.id])]) self.assertTrue(build_error) + self.assertTrue(build_error.fingerprint.startswith('af0e88f3')) + self.assertTrue(build_error.cleaned_content.startswith('%'), 'The cleaner should have replace "FAIL: " with a "%" sign by default') self.assertIn(ko_build, build_error.build_ids, 'The parsed build should be added to the runbot.build.error') self.assertFalse(self.BuildError.search([('build_ids', 'in', [ok_build.id])]), 'A successful build should not associated to a runbot.build.error') self.assertEqual(error_team, build_error.team_id) diff --git a/runbot/views/build_error_views.xml b/runbot/views/build_error_views.xml index dee52f78..23b82afe 100644 --- a/runbot/views/build_error_views.xml +++ b/runbot/views/build_error_views.xml @@ -221,6 +221,7 @@ +
@@ -239,6 +240,7 @@ +