From 4e4e4303f641d4ef4b55b6e6cf7d25a5fdbd2d4d Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 1 Mar 2021 14:42:20 +0100 Subject: [PATCH] [IMP] runbot_merge: add name_search override to PRs Should allow filtering PRs by source or parent. Fixes #458 --- runbot_merge/models/pull_requests.py | 20 ++++++++++++++ runbot_merge/tests/test_oddities.py | 40 ++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/runbot_merge/models/pull_requests.py b/runbot_merge/models/pull_requests.py index f317fa64..b03ef637 100644 --- a/runbot_merge/models/pull_requests.py +++ b/runbot_merge/models/pull_requests.py @@ -21,6 +21,7 @@ from werkzeug.datastructures import Headers from odoo import api, fields, models, tools from odoo.exceptions import ValidationError +from odoo.osv import expression from odoo.tools import OrderedSet from .. import github, exceptions, controllers, utils @@ -721,6 +722,25 @@ class PullRequests(models.Model): for p in self ] + @api.model + def name_search(self, name='', args=None, operator='ilike', limit=100): + print(f'name_search({name!r}, {args!r}, {operator!r})', flush=True) + if not name or operator != 'ilike': + return super().name_search(name, args=args, operator=operator, limit=limit) + bits = [[('label', 'ilike', name)]] + if name.isdigit(): + bits.append([('number', '=', name)]) + if re.match(r'\w+#\d+$', name): + repo, num = name.rsplit('#', 1) + bits.append(['&', ('repository.name', 'ilike', repo), ('number', '=', int(num))]) + else: + bits.append([('repository.name', 'ilike', name)]) + domain = expression.OR(bits) + if args: + domain = expression.AND([args, domain]) + print('=>', domain, flush=True) + return self.search(domain, limit=limit).sudo().name_get() + @property def _approved(self): return self.state in ('approved', 'ready') or any( diff --git a/runbot_merge/tests/test_oddities.py b/runbot_merge/tests/test_oddities.py index d071be84..b2b2f984 100644 --- a/runbot_merge/tests/test_oddities.py +++ b/runbot_merge/tests/test_oddities.py @@ -20,3 +20,43 @@ def test_partner_merge(env): assert not p_src.exists() assert p_dest.name == 'Partner P. Partnersson' assert p_dest.github_login == 'xxx' + +def test_name_search(env): + """ PRs should be findable by: + + * number + * display_name (`repository#number`) + * label + + This way we can find parents or sources by these informations. + """ + p = env['runbot_merge.project'].create({ + 'name': 'proj', + 'github_token': 'no', + }) + b = env['runbot_merge.branch'].create({ + 'name': 'target', + 'project_id': p.id + }) + r = env['runbot_merge.repository'].create({ + 'name': 'repo', + 'project_id': p.id, + }) + + baseline = {'target': b.id, 'repository': r.id} + PRs = env['runbot_merge.pull_requests'] + prs = PRs.create({**baseline, 'number': 1964, 'label': 'victor:thump', 'head': 'a', 'message': 'x'})\ + | PRs.create({**baseline, 'number': 1959, 'label': 'marcus:frankenstein', 'head': 'b', 'message': 'y'})\ + | PRs.create({**baseline, 'number': 1969, 'label': 'victor:patch-1', 'head': 'c', 'message': 'z'}) + pr0, pr1, pr2 = prs.name_get() + + assert PRs.name_search('1964') == [pr0] + assert PRs.name_search('1969') == [pr2] + + assert PRs.name_search('frank') == [pr1] + assert PRs.name_search('victor') == [pr2, pr0] + + assert PRs.name_search('thump') == [pr0] + + assert PRs.name_search('repo') == [pr2, pr0, pr1] + assert PRs.name_search('repo#1959') == [pr1]