Skip to content

Commit ad96f39

Browse files
committed
Extend gitea_api.PullRequest with methods that work with 'PR:' references
1 parent 66e9881 commit ad96f39

File tree

2 files changed

+111
-0
lines changed

2 files changed

+111
-0
lines changed

osc/gitea_api/pr.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,46 @@ def parse_pr_references(self) -> List[Tuple[str, str, int]]:
8787

8888
return result
8989

90+
@classmethod
91+
def add_pr_references(cls, text: str, pr_id_list: List[Tuple[str, str, int]]) -> str:
92+
pos = 0
93+
add_newline = False
94+
95+
for match in re.finditer(r"^PR: *(.*)$", text, re.M):
96+
pos = match.end()
97+
if pos < len(text) and text[pos] == "\n":
98+
pos += 1
99+
else:
100+
add_newline = True
101+
102+
references_str = ""
103+
if add_newline:
104+
references_str += "\n"
105+
for owner, repo, number in pr_id_list:
106+
references_str += f"PR: {owner}/{repo}!{number}\n"
107+
text = text[:pos] + references_str + text[pos:]
108+
return text
109+
110+
@classmethod
111+
def remove_pr_references(cls, text: str, pr_id_list: List[Tuple[str, str, int]]) -> str:
112+
# HACK: reverse matches so we can modify the text from end without breaking any indexes
113+
for match in reversed(list(re.finditer(r"^PR: *(.*)$", text, re.M))):
114+
try:
115+
pr_id = PullRequest.split_id(match.group(1))
116+
if pr_id not in pr_id_list:
117+
continue
118+
except ValueError:
119+
continue
120+
121+
start_pos = match.start()
122+
end_pos = match.end()
123+
if end_pos < len(text) and text[end_pos] == "\n":
124+
end_pos += 1
125+
126+
text = text[:start_pos] + text[end_pos:]
127+
128+
return text
129+
90130
@property
91131
def is_pull_request(self):
92132
# determine if we're working with a proper pull request or an issue without pull request details

tests/test_gitea_api_pr.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,5 +164,76 @@ def test_get_host_owner_repo_number_invalid_format(self):
164164
PullRequest.get_host_owner_repo_number(url)
165165

166166

167+
class TestGiteaApiPullRequestReferences(unittest.TestCase):
168+
PR_BODY = """
169+
PR: foo/bar!1
170+
PR: foo/bar#2
171+
text
172+
PR: bar/baz#3
173+
text
174+
175+
text
176+
text
177+
""".strip()
178+
179+
def test_parse_pr_references(self):
180+
pr_obj = PullRequest({"body": self.PR_BODY})
181+
actual = pr_obj.parse_pr_references()
182+
expected = [
183+
('foo', 'bar', 1),
184+
('foo', 'bar', 2),
185+
('bar', 'baz', 3),
186+
]
187+
self.assertEqual(actual, expected)
188+
189+
def test_add_pr_references(self):
190+
actual = PullRequest.add_pr_references(self.PR_BODY, [('xxx', 'xxx', 4), ('yyy', 'yyy', 5)])
191+
expected = """
192+
PR: foo/bar!1
193+
PR: foo/bar#2
194+
text
195+
PR: bar/baz#3
196+
PR: xxx/xxx!4
197+
PR: yyy/yyy!5
198+
text
199+
200+
text
201+
text
202+
""".strip()
203+
204+
self.assertEqual(actual, expected)
205+
206+
def test_add_pr_references_end(self):
207+
actual = PullRequest.add_pr_references(self.PR_BODY + "\nPR: a/b#123", [('xxx', 'xxx', 4), ('yyy', 'yyy', 5)])
208+
expected = """
209+
PR: foo/bar!1
210+
PR: foo/bar#2
211+
text
212+
PR: bar/baz#3
213+
text
214+
215+
text
216+
text
217+
PR: a/b#123
218+
PR: xxx/xxx!4
219+
PR: yyy/yyy!5
220+
""".lstrip()
221+
222+
self.assertEqual(actual, expected)
223+
224+
def test_remove_pr_references(self):
225+
actual = PullRequest.remove_pr_references(self.PR_BODY, [("foo", "bar", 2)])
226+
expected = """
227+
PR: foo/bar!1
228+
text
229+
PR: bar/baz#3
230+
text
231+
232+
text
233+
text
234+
""".strip()
235+
self.assertEqual(actual, expected)
236+
237+
167238
if __name__ == "__main__":
168239
unittest.main()

0 commit comments

Comments
 (0)