Skip to content

Commit aa3cb2c

Browse files
committed
feat: add new function PullRequest.get_host_owner_repo_number
The existing `get_owner_repo_number` throws away the parsed host, which is occasionally useful. Therefore we add a new method `get_host_owner_repo_number` that also returns the full host (scheme + hostname + port) and keep the old method for compatibility. Also add tests.
1 parent 5d244c9 commit aa3cb2c

File tree

2 files changed

+67
-3
lines changed

2 files changed

+67
-3
lines changed

osc/gitea_api/pr.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,19 +91,31 @@ def split_id(cls, pr_id: str) -> Tuple[str, str, int]:
9191
return match.group(1), match.group(2), int(match.group(3))
9292

9393
@staticmethod
94-
def get_owner_repo_number(url: str) -> Tuple[str, str, int]:
94+
def get_host_owner_repo_number(url: str) -> Tuple[str, str, str, int]:
9595
"""
9696
Parse pull request URL such as http(s)://example.com:<port>/<owner>/<repo>/pulls/<number>
97-
and return (owner, repo, number) tuple.
97+
and return (host, owner, repo, number) tuple.
98+
99+
The host is returned as the full base URL (scheme://netloc), e.g., "https://example.com:3000".
98100
"""
99101
import urllib.parse
100102

101103
parsed_url = urllib.parse.urlparse(url)
104+
host = f"{parsed_url.scheme}://{parsed_url.netloc}"
102105
path = parsed_url.path
103106
owner, repo, pulls, number = path.strip("/").split("/")
104107
if pulls not in ("pulls", "issues"):
105108
raise ValueError(f"URL doesn't point to a pull request or an issue: {url}")
106-
return owner, repo, int(number)
109+
return host, owner, repo, int(number)
110+
111+
@staticmethod
112+
def get_owner_repo_number(url: str) -> Tuple[str, str, int]:
113+
"""
114+
Parse pull request URL such as http(s)://example.com:<port>/<owner>/<repo>/pulls/<number>
115+
and return (owner, repo, number) tuple.
116+
"""
117+
_, owner, repo, number = PullRequest.get_host_owner_repo_number(url)
118+
return owner, repo, number
107119

108120
def parse_pr_references(self) -> List[Tuple[str, str, int]]:
109121
refs = re.findall(r"^PR: *(.*)$", self.body, re.M)

tests/test_gitea_api_pr.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,5 +112,57 @@ def test_object_issue(self):
112112
self.assertEqual(obj.head_ssh_url, None)
113113

114114

115+
class TestGiteaApiPullRequestUrlParsing(unittest.TestCase):
116+
def test_get_host_owner_repo_number_https_with_port(self):
117+
url = "https://git.example.com:3000/owner/repo/pulls/123"
118+
host, owner, repo, number = PullRequest.get_host_owner_repo_number(url)
119+
self.assertEqual(host, "https://git.example.com:3000")
120+
self.assertEqual(owner, "owner")
121+
self.assertEqual(repo, "repo")
122+
self.assertEqual(number, 123)
123+
124+
self.assertTupleEqual(
125+
PullRequest.get_owner_repo_number(url),
126+
(owner, repo, number),
127+
)
128+
129+
def test_get_host_owner_repo_number_https_without_port(self):
130+
url = "https://git.example.com/owner/repo/pulls/456"
131+
host, owner, repo, number = PullRequest.get_host_owner_repo_number(url)
132+
self.assertEqual(host, "https://git.example.com")
133+
self.assertEqual(owner, "owner")
134+
self.assertEqual(repo, "repo")
135+
self.assertEqual(number, 456)
136+
137+
self.assertTupleEqual(
138+
PullRequest.get_owner_repo_number(url),
139+
(owner, repo, number),
140+
)
141+
142+
def test_get_host_owner_repo_number_issues_endpoint(self):
143+
url = "https://git.example.com/owner/repo/issues/100"
144+
host, owner, repo, number = PullRequest.get_host_owner_repo_number(url)
145+
self.assertEqual(host, "https://git.example.com")
146+
self.assertEqual(owner, "owner")
147+
self.assertEqual(repo, "repo")
148+
self.assertEqual(number, 100)
149+
150+
self.assertTupleEqual(
151+
PullRequest.get_owner_repo_number(url),
152+
(owner, repo, number),
153+
)
154+
155+
def test_get_host_owner_repo_number_invalid_endpoint(self):
156+
url = "https://git.example.com/owner/repo/commits/abc123"
157+
with self.assertRaises(ValueError) as context:
158+
PullRequest.get_host_owner_repo_number(url)
159+
self.assertIn("doesn't point to a pull request or an issue", str(context.exception))
160+
161+
def test_get_host_owner_repo_number_invalid_format(self):
162+
url = "https://git.example.com/owner/repo"
163+
with self.assertRaises(ValueError):
164+
PullRequest.get_host_owner_repo_number(url)
165+
166+
115167
if __name__ == "__main__":
116168
unittest.main()

0 commit comments

Comments
 (0)