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:
@@ -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)
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user