mirror of
https://github.com/odoo/runbot.git
synced 2025-03-15 15:35:46 +07:00
[REF] forwardport: update re_matches to not use a regex
Using a regex as the pattern is quite frustrating due to all the escaping necessary, which in this refactoring I found out I'd missed, multiple times. Convert the pattern to something bespoke but not too complicated, we may want to add anchoring support and a bit more finesse and the future but for now straightforward "holes" seem to work well. I've added support for capturing and even named groups even if this as yet unnecessary and unused. Fixes #861 [^1]: https://docs.pytest.org/en/stable/reference.html#pytest.hookspec.pytest_assertrepr_compare
This commit is contained in:
parent
98aaa9107f
commit
c1e2e5a2e0
@ -1,6 +1,6 @@
|
||||
import re
|
||||
|
||||
from utils import Commit, make_basic, to_pr, seen, re_matches
|
||||
from utils import Commit, make_basic, to_pr, seen, matches
|
||||
|
||||
|
||||
def test_single_updated(env, config, make_repo):
|
||||
@ -381,26 +381,26 @@ def test_add_to_forward_port_conflict(env, config, make_repo, users):
|
||||
assert pr2_c.comments == [
|
||||
seen(env, pr2_c, users),
|
||||
# should have conflicts
|
||||
(users['user'], re_matches(r"""@{user} cherrypicking of pull request {previous.display_name} failed\.
|
||||
(users['user'], matches("""@{user} cherrypicking of pull request {previous.display_name} failed.
|
||||
|
||||
stdout:
|
||||
```
|
||||
Auto-merging b
|
||||
CONFLICT \(add/add\): Merge conflict in b
|
||||
CONFLICT (add/add): Merge conflict in b
|
||||
|
||||
```
|
||||
|
||||
stderr:
|
||||
```
|
||||
.*
|
||||
$$
|
||||
```
|
||||
|
||||
Either perform the forward-port manually \(and push to this branch, proceeding as usual\) or close this PR \(maybe\?\)\.
|
||||
Either perform the forward-port manually (and push to this branch, proceeding as usual) or close this PR (maybe?).
|
||||
|
||||
In the former case, you may want to edit this PR message as well\.
|
||||
In the former case, you may want to edit this PR message as well.
|
||||
|
||||
:warning: after resolving this conflict, you will need to merge it via @{project.github_prefix}\.
|
||||
:warning: after resolving this conflict, you will need to merge it via @{project.github_prefix}.
|
||||
|
||||
More info at https://github\.com/odoo/odoo/wiki/Mergebot#forward-port
|
||||
""".format(project=project, previous=pr2_b_id, **users), re.DOTALL))
|
||||
More info at https://github.com/odoo/odoo/wiki/Mergebot#forward-port
|
||||
""".format(project=project, previous=pr2_b_id, **users)))
|
||||
]
|
||||
|
@ -2,7 +2,7 @@ import re
|
||||
import time
|
||||
from operator import itemgetter
|
||||
|
||||
from utils import make_basic, Commit, validate_all, re_matches, seen, REF_PATTERN, to_pr
|
||||
from utils import make_basic, Commit, validate_all, matches, seen, REF_PATTERN, to_pr
|
||||
|
||||
|
||||
def test_conflict(env, config, make_repo, users):
|
||||
@ -59,39 +59,39 @@ def test_conflict(env, config, make_repo, users):
|
||||
assert prod.read_tree(c) == {
|
||||
'f': 'c',
|
||||
'g': 'a',
|
||||
'h': re_matches(r'''<<<\x3c<<< HEAD
|
||||
'h': matches('''<<<\x3c<<< HEAD
|
||||
a
|
||||
|||||||| parent of [\da-f]{7,}.*
|
||||
||||||| parent of $$ (temp)
|
||||
=======
|
||||
xxx
|
||||
>>>\x3e>>> [\da-f]{7,}.*
|
||||
>>>\x3e>>> $$ (temp)
|
||||
'''),
|
||||
}
|
||||
assert prc.comments == [
|
||||
seen(env, prc, users),
|
||||
(users['user'], re_matches(
|
||||
fr'''@{users['user']} @{users['reviewer']} cherrypicking of pull request {pra_id.display_name} failed\.
|
||||
(users['user'], matches(
|
||||
f'''@{users['user']} @{users['reviewer']} cherrypicking of pull request {pra_id.display_name} failed.
|
||||
|
||||
stdout:
|
||||
```
|
||||
Auto-merging h
|
||||
CONFLICT \(add/add\): Merge conflict in h
|
||||
CONFLICT (add/add): Merge conflict in h
|
||||
|
||||
```
|
||||
|
||||
stderr:
|
||||
```
|
||||
.*
|
||||
$$
|
||||
```
|
||||
|
||||
Either perform the forward-port manually \(and push to this branch, proceeding as usual\) or close this PR \(maybe\?\)\.
|
||||
Either perform the forward-port manually (and push to this branch, proceeding as usual) or close this PR (maybe?).
|
||||
|
||||
In the former case, you may want to edit this PR message as well\.
|
||||
In the former case, you may want to edit this PR message as well.
|
||||
|
||||
:warning: after resolving this conflict, you will need to merge it via @{project.github_prefix}\.
|
||||
:warning: after resolving this conflict, you will need to merge it via @{project.github_prefix}.
|
||||
|
||||
More info at https://github\.com/odoo/odoo/wiki/Mergebot#forward-port
|
||||
''', re.DOTALL))
|
||||
More info at https://github.com/odoo/odoo/wiki/Mergebot#forward-port
|
||||
'''))
|
||||
]
|
||||
|
||||
prb = prod.get_pr(prb_id.number)
|
||||
@ -372,7 +372,7 @@ b
|
||||
|
||||
assert pr2.comments == [
|
||||
seen(env, pr2, users),
|
||||
(users['user'], re_matches(r'@%s @%s .*CONFLICT' % (users['user'], users['reviewer']), re.DOTALL)),
|
||||
(users['user'], matches('@%s @%s $$CONFLICT' % (users['user'], users['reviewer']))),
|
||||
(users['reviewer'], 'hansen r+'),
|
||||
(users['user'], f"@{users['user']} @{users['reviewer']} unable to stage: "
|
||||
"All commits must have author and committer email, "
|
||||
|
@ -6,7 +6,7 @@ from datetime import datetime, timedelta
|
||||
|
||||
import pytest
|
||||
|
||||
from utils import seen, Commit, make_basic, REF_PATTERN, MESSAGE_TEMPLATE, validate_all, part_of, to_pr, re_matches
|
||||
from utils import seen, Commit, make_basic, REF_PATTERN, MESSAGE_TEMPLATE, validate_all, part_of, to_pr, matches
|
||||
|
||||
FMT = '%Y-%m-%d %H:%M:%S'
|
||||
FAKE_PREV_WEEK = (datetime.now() + timedelta(days=1)).strftime(FMT)
|
||||
@ -346,27 +346,27 @@ def test_empty(env, config, make_repo, users):
|
||||
pr1_id.display_name
|
||||
)
|
||||
)
|
||||
conflict = (users['user'], re_matches(
|
||||
fr"""@{users['user']} @{users['reviewer']} cherrypicking of pull request {pr1_id.display_name} failed\.
|
||||
conflict = (users['user'], matches(
|
||||
f"""@{users['user']} @{users['reviewer']} cherrypicking of pull request {pr1_id.display_name} failed.
|
||||
|
||||
stdout:
|
||||
```
|
||||
.*
|
||||
$$
|
||||
```
|
||||
|
||||
stderr:
|
||||
```
|
||||
.*
|
||||
$$
|
||||
```
|
||||
|
||||
Either perform the forward-port manually \(and push to this branch, proceeding as usual\) or close this PR \(maybe\?\)\.
|
||||
Either perform the forward-port manually (and push to this branch, proceeding as usual) or close this PR (maybe?).
|
||||
|
||||
In the former case, you may want to edit this PR message as well\.
|
||||
In the former case, you may want to edit this PR message as well.
|
||||
|
||||
:warning: after resolving this conflict, you will need to merge it via @{project.github_prefix}\.
|
||||
:warning: after resolving this conflict, you will need to merge it via @{project.github_prefix}.
|
||||
|
||||
More info at https://github\.com/odoo/odoo/wiki/Mergebot#forward-port
|
||||
""", re.DOTALL))
|
||||
More info at https://github.com/odoo/odoo/wiki/Mergebot#forward-port
|
||||
"""))
|
||||
assert pr1.comments == [
|
||||
(users['reviewer'], 'hansen r+'),
|
||||
seen(env, pr1, users),
|
||||
|
@ -6,7 +6,7 @@ import re
|
||||
|
||||
import pytest
|
||||
|
||||
from utils import seen, re_matches, Commit, make_basic, to_pr
|
||||
from utils import seen, matches, Commit, make_basic, to_pr
|
||||
|
||||
|
||||
@pytest.mark.parametrize("merge_parent", [False, True])
|
||||
@ -433,12 +433,12 @@ def test_subsequent_conflict(env, make_repo, config, users):
|
||||
assert repo.read_tree(repo.commit(pr3_id.head)) == {
|
||||
'f': 'c',
|
||||
'g': 'a',
|
||||
'h': re_matches(r'''<<<\x3c<<< HEAD
|
||||
'h': matches('''<<<\x3c<<< HEAD
|
||||
a
|
||||
|||||||| parent of [\da-f]{7,}.*
|
||||
||||||| parent of $$ (temp)
|
||||
=======
|
||||
conflict!
|
||||
>>>\x3e>>> [\da-f]{7,}.*
|
||||
>>>\x3e>>> $$ (temp)
|
||||
'''),
|
||||
'x': '0',
|
||||
}
|
||||
@ -458,18 +458,22 @@ conflict!
|
||||
# 1. link to status page
|
||||
# 2. forward-port chain thing
|
||||
assert repo.get_pr(pr3_id.number).comments[2:] == [
|
||||
(users['user'], re_matches(f'''\
|
||||
(users['user'], matches(f'''\
|
||||
@{users['user']} @{users['reviewer']} WARNING: the update of {pr2_id.display_name} to {pr2_id.head} has caused a \
|
||||
conflict in this pull request, data may have been lost.
|
||||
|
||||
stdout:
|
||||
```.*?
|
||||
CONFLICT \(add/add\): Merge conflict in h.*?
|
||||
```
|
||||
Auto-merging h
|
||||
CONFLICT (add/add): Merge conflict in h
|
||||
```
|
||||
|
||||
stderr:
|
||||
```
|
||||
\\d{{2}}:\\d{{2}}:\\d{{2}}.\\d+ .* {pr2_id.head}
|
||||
error: could not apply [0-9a-f]+\\.\\.\\. newfiles
|
||||
''', re.DOTALL))
|
||||
$$:$$:$$.$$ {pr2_id.head}
|
||||
error: could not apply $$... newfiles
|
||||
hint: $$
|
||||
----------
|
||||
status:
|
||||
'''))
|
||||
]
|
||||
|
@ -42,18 +42,26 @@ def _simple_init(repo):
|
||||
prx = repo.make_pr(title='title', body='body', target='master', head=c2)
|
||||
return prx
|
||||
|
||||
class re_matches:
|
||||
class matches(str):
|
||||
# necessary so str.__new__ does not freak out on `flags`
|
||||
def __new__(cls, pattern, flags=0):
|
||||
return super().__new__(cls, pattern)
|
||||
|
||||
def __init__(self, pattern, flags=0):
|
||||
self._r = re.compile(pattern, flags)
|
||||
p, n = re.subn(
|
||||
# `re.escape` will escape the `$`, so we need to handle that...
|
||||
# maybe it should not be $?
|
||||
r'\\\$(\w*?)\\\$',
|
||||
lambda m: f'(?P<{m[1]}>.*?)' if m[1] else '(.*?)',
|
||||
re.escape(self),
|
||||
)
|
||||
assert n, f"matches' pattern should have at least one placeholder, found none in\n{pattern}"
|
||||
self._r = re.compile(p, flags | re.DOTALL)
|
||||
|
||||
def __eq__(self, text):
|
||||
return self._r.match(text)
|
||||
|
||||
def __str__(self):
|
||||
return re.sub(r'\\(.)', r'\1', self._r.pattern)
|
||||
|
||||
def __repr__(self):
|
||||
return repr(str(self))
|
||||
if not isinstance(text, str):
|
||||
return NotImplemented
|
||||
return self._r.search(text)
|
||||
|
||||
def seen(env, pr, users):
|
||||
url = to_pr(env, pr).url
|
||||
|
@ -10,7 +10,7 @@ import requests
|
||||
from lxml import html
|
||||
|
||||
import odoo
|
||||
from utils import _simple_init, seen, re_matches, get_partner, Commit, pr_page, to_pr, part_of, ensure_one
|
||||
from utils import _simple_init, seen, matches, get_partner, Commit, pr_page, to_pr, part_of, ensure_one
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -174,7 +174,7 @@ def test_trivial_flow(env, repo, page, users, config):
|
||||
('', 'Reviewer'),
|
||||
]),
|
||||
# staging succeeded
|
||||
(re_matches(r'.*'), f'<p>staging {st.id} succeeded</p>', [
|
||||
(matches('$$'), f'<p>staging {st.id} succeeded</p>', [
|
||||
# set merge date
|
||||
(False, pr_id.merge_date + 'Z'),
|
||||
# updated state
|
||||
@ -676,7 +676,7 @@ def test_ff_failure(env, repo, config, page):
|
||||
_new, prev = doc.cssselect('li.staging')
|
||||
|
||||
assert 'bg-gray-lighter' in prev.classes, "ff failure is ~ cancelling"
|
||||
assert prev.get('title') == re_matches('fast forward failed \(update is not a fast forward\)')
|
||||
assert 'fast forward failed (update is not a fast forward)' in prev.get('title')
|
||||
|
||||
assert env['runbot_merge.pull_requests'].search([
|
||||
('repository.name', '=', repo.name),
|
||||
@ -1029,7 +1029,7 @@ def test_rebase_failure(env, repo, users, config):
|
||||
assert pr_a.comments == [
|
||||
(users['reviewer'], 'hansen r+'),
|
||||
seen(env, pr_a, users),
|
||||
(users['user'], re_matches(r'^Unable to stage PR')),
|
||||
(users['user'], matches('Unable to stage PR')),
|
||||
]
|
||||
assert pr_b.comments == [
|
||||
(users['reviewer'], 'hansen r+'),
|
||||
@ -3968,7 +3968,7 @@ class TestInfrastructure:
|
||||
assert repo.get_ref('heads/master') == m1
|
||||
|
||||
def node(name, *children):
|
||||
assert type(name) in (str, re_matches)
|
||||
assert type(name) in (str, matches)
|
||||
return name, frozenset(children)
|
||||
def log_to_node(log):
|
||||
log = list(log)
|
||||
|
Loading…
Reference in New Issue
Block a user