1
0
mirror of https://github.com/openSUSE/osc.git synced 2025-11-25 06:06:30 +01:00

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.
This commit is contained in:
2025-10-20 17:15:34 +02:00
parent 5d244c9381
commit aa3cb2c71f
2 changed files with 72 additions and 8 deletions

View File

@@ -90,20 +90,32 @@ class PullRequest(GiteaModel):
raise ValueError(f"Invalid pull request id: {pr_id}") raise ValueError(f"Invalid pull request id: {pr_id}")
return match.group(1), match.group(2), int(match.group(3)) return match.group(1), match.group(2), int(match.group(3))
@staticmethod
def get_host_owner_repo_number(url: str) -> Tuple[str, str, str, int]:
"""
Parse pull request URL such as http(s)://example.com:<port>/<owner>/<repo>/pulls/<number>
and return (host, owner, repo, number) tuple.
The host is returned as the full base URL (scheme://netloc), e.g., "https://example.com:3000".
"""
import urllib.parse
parsed_url = urllib.parse.urlparse(url)
host = f"{parsed_url.scheme}://{parsed_url.netloc}"
path = parsed_url.path
owner, repo, pulls, number = path.strip("/").split("/")
if pulls not in ("pulls", "issues"):
raise ValueError(f"URL doesn't point to a pull request or an issue: {url}")
return host, owner, repo, int(number)
@staticmethod @staticmethod
def get_owner_repo_number(url: str) -> Tuple[str, str, int]: def get_owner_repo_number(url: str) -> Tuple[str, str, int]:
""" """
Parse pull request URL such as http(s)://example.com:<port>/<owner>/<repo>/pulls/<number> Parse pull request URL such as http(s)://example.com:<port>/<owner>/<repo>/pulls/<number>
and return (owner, repo, number) tuple. and return (owner, repo, number) tuple.
""" """
import urllib.parse _, owner, repo, number = PullRequest.get_host_owner_repo_number(url)
return owner, repo, number
parsed_url = urllib.parse.urlparse(url)
path = parsed_url.path
owner, repo, pulls, number = path.strip("/").split("/")
if pulls not in ("pulls", "issues"):
raise ValueError(f"URL doesn't point to a pull request or an issue: {url}")
return owner, repo, int(number)
def parse_pr_references(self) -> List[Tuple[str, str, int]]: def parse_pr_references(self) -> List[Tuple[str, str, int]]:
refs = re.findall(r"^PR: *(.*)$", self.body, re.M) refs = re.findall(r"^PR: *(.*)$", self.body, re.M)

View File

@@ -112,5 +112,57 @@ class TestGiteaApiPullRequest(unittest.TestCase):
self.assertEqual(obj.head_ssh_url, None) self.assertEqual(obj.head_ssh_url, None)
class TestGiteaApiPullRequestUrlParsing(unittest.TestCase):
def test_get_host_owner_repo_number_https_with_port(self):
url = "https://git.example.com:3000/owner/repo/pulls/123"
host, owner, repo, number = PullRequest.get_host_owner_repo_number(url)
self.assertEqual(host, "https://git.example.com:3000")
self.assertEqual(owner, "owner")
self.assertEqual(repo, "repo")
self.assertEqual(number, 123)
self.assertTupleEqual(
PullRequest.get_owner_repo_number(url),
(owner, repo, number),
)
def test_get_host_owner_repo_number_https_without_port(self):
url = "https://git.example.com/owner/repo/pulls/456"
host, owner, repo, number = PullRequest.get_host_owner_repo_number(url)
self.assertEqual(host, "https://git.example.com")
self.assertEqual(owner, "owner")
self.assertEqual(repo, "repo")
self.assertEqual(number, 456)
self.assertTupleEqual(
PullRequest.get_owner_repo_number(url),
(owner, repo, number),
)
def test_get_host_owner_repo_number_issues_endpoint(self):
url = "https://git.example.com/owner/repo/issues/100"
host, owner, repo, number = PullRequest.get_host_owner_repo_number(url)
self.assertEqual(host, "https://git.example.com")
self.assertEqual(owner, "owner")
self.assertEqual(repo, "repo")
self.assertEqual(number, 100)
self.assertTupleEqual(
PullRequest.get_owner_repo_number(url),
(owner, repo, number),
)
def test_get_host_owner_repo_number_invalid_endpoint(self):
url = "https://git.example.com/owner/repo/commits/abc123"
with self.assertRaises(ValueError) as context:
PullRequest.get_host_owner_repo_number(url)
self.assertIn("doesn't point to a pull request or an issue", str(context.exception))
def test_get_host_owner_repo_number_invalid_format(self):
url = "https://git.example.com/owner/repo"
with self.assertRaises(ValueError):
PullRequest.get_host_owner_repo_number(url)
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()