mirror of
https://github.com/openSUSE/osc.git
synced 2025-11-26 22:49:49 +01:00
Another take on parsing pull request references
Parse only references that start with 'PR:'. Parse both owner/repo#number and gitea_url/owner/repo/pulls/number
This commit is contained in:
@@ -309,47 +309,18 @@ class PullRequestDumpCommand(osc.commandline_git.GitObsCommand):
|
||||
with open(os.path.join(metadata_dir, "submodules-diff.json"), "w", encoding="utf-8") as f:
|
||||
json.dump(submodule_diff, f, indent=4, sort_keys=True)
|
||||
|
||||
linked_prs = {}
|
||||
|
||||
# body may contain references with both https:// or without, which look indetical in UI. so we must handle both cases:
|
||||
for url in re.findall(r"https?://[^\s]+/pulls/\d+", pr_obj.body):
|
||||
if not self.gitea_conn.host in url:
|
||||
print(f"ignoring PR {url}")
|
||||
linked_prs[url] = None
|
||||
continue
|
||||
|
||||
print(f"Linking PR {url}...")
|
||||
_, _, linked_id = url.partition(self.gitea_conn.host + "/")
|
||||
|
||||
try:
|
||||
linked_owner, linked_repo, linked_number = gitea_api.PullRequest.split_id(linked_id)
|
||||
linked_pr_obj = gitea_api.PullRequest.get(self.gitea_conn, linked_owner, linked_repo, linked_number)
|
||||
if linked_pr_obj is None:
|
||||
linked_prs[url] = None
|
||||
else:
|
||||
linked_prs[url] = linked_pr_obj.to_light_dict()
|
||||
except:
|
||||
linked_prs[url] = None
|
||||
|
||||
for m in re.findall(r"([^\s\/]+)\/([^\s\/]+)\#(\d+)", pr_obj.body):
|
||||
uri = f"{m[0]}/{m[1]}#{m[2]}"
|
||||
print(f"Linking PR {uri}...")
|
||||
|
||||
try:
|
||||
linked_pr_obj = gitea_api.PullRequest.get(self.gitea_conn, m[0], m[1], m[2])
|
||||
if linked_pr_obj is None:
|
||||
linked_prs[uri] = None
|
||||
else:
|
||||
linked_prs[uri] = linked_pr_obj.to_light_dict()
|
||||
except:
|
||||
linked_prs[uri] = None
|
||||
referenced_pull_requests = {}
|
||||
for ref_owner, ref_repo, ref_number in pr_obj.parse_pr_references():
|
||||
ref_id = f"{ref_owner}/{ref_repo}#{ref_number}"
|
||||
referenced_pr_obj = gitea_api.PullRequest.get(self.gitea_conn, ref_owner, ref_repo, ref_number)
|
||||
referenced_pull_requests[ref_id] = referenced_pr_obj.dict()
|
||||
|
||||
with open(
|
||||
os.path.join(metadata_dir, "referenced-pull-requests.json"),
|
||||
"w",
|
||||
encoding="utf-8",
|
||||
) as f:
|
||||
json.dump(linked_prs, f, indent=4, sort_keys=True)
|
||||
json.dump(referenced_pull_requests, f, indent=4, sort_keys=True)
|
||||
|
||||
if warnings:
|
||||
return 38
|
||||
|
||||
@@ -10,11 +10,7 @@ from .connection import GiteaHTTPResponse
|
||||
from .user import User
|
||||
|
||||
|
||||
class PullRequestReview:
|
||||
def __init__(self, data: dict, *, response: Optional[GiteaHTTPResponse] = None):
|
||||
self._data = data
|
||||
self._response = response
|
||||
|
||||
class PullRequestReview(GiteaModel):
|
||||
@property
|
||||
def state(self) -> str:
|
||||
return self._data["state"]
|
||||
@@ -104,9 +100,34 @@ class PullRequest(GiteaModel):
|
||||
parsed_url = urllib.parse.urlparse(url)
|
||||
path = parsed_url.path
|
||||
owner, repo, pulls, number = path.strip("/").split("/")
|
||||
assert pulls in ("pulls", "issues")
|
||||
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]]:
|
||||
refs = re.findall(r"^PR: *(.*)$", self.body, re.M)
|
||||
result = []
|
||||
|
||||
for ref in refs:
|
||||
# try owner/repo#number first
|
||||
try:
|
||||
result.append(PullRequest.split_id(ref))
|
||||
continue
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
# parse owner, repo, number from a pull request url
|
||||
if ref.startswith(f"{self._conn.login.url.rstrip('/')}/"):
|
||||
try:
|
||||
result.append(PullRequest.get_owner_repo_number(ref))
|
||||
continue
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
raise ValueError(f"Unable to parse pull request reference: {ref}")
|
||||
|
||||
return result
|
||||
|
||||
@property
|
||||
def is_pull_request(self):
|
||||
# determine if we're working with a proper pull request or an issue without pull request details
|
||||
@@ -337,7 +358,7 @@ class PullRequest(GiteaModel):
|
||||
"body": description,
|
||||
}
|
||||
response = conn.request("POST", url, json_data=data)
|
||||
obj = cls(response.json(), response=response)
|
||||
obj = cls(response.json(), response=response, conn=conn)
|
||||
return obj
|
||||
|
||||
@classmethod
|
||||
@@ -358,7 +379,7 @@ class PullRequest(GiteaModel):
|
||||
"""
|
||||
url = conn.makeurl("repos", owner, repo, "pulls", str(number))
|
||||
response = conn.request("GET", url)
|
||||
obj = cls(response.json(), response=response)
|
||||
obj = cls(response.json(), response=response, conn=conn)
|
||||
return obj
|
||||
|
||||
@classmethod
|
||||
@@ -391,7 +412,7 @@ class PullRequest(GiteaModel):
|
||||
}
|
||||
url = conn.makeurl("repos", owner, repo, "pulls", str(number))
|
||||
response = conn.request("PATCH", url, json_data=json_data)
|
||||
obj = cls(response.json(), response=response)
|
||||
obj = cls(response.json(), response=response, conn=conn)
|
||||
return obj
|
||||
|
||||
@classmethod
|
||||
@@ -420,7 +441,7 @@ class PullRequest(GiteaModel):
|
||||
}
|
||||
url = conn.makeurl("repos", owner, repo, "pulls", query=q)
|
||||
response = conn.request("GET", url)
|
||||
obj_list = [cls(i, response=response) for i in response.json()]
|
||||
obj_list = [cls(i, response=response, conn=conn) for i in response.json()]
|
||||
return obj_list
|
||||
|
||||
@classmethod
|
||||
@@ -464,7 +485,7 @@ class PullRequest(GiteaModel):
|
||||
url = conn.makeurl("repos", "issues", "search", query=q)
|
||||
obj_list = []
|
||||
for response in conn.request_all_pages("GET", url):
|
||||
obj_list.extend([cls(i, response=response) for i in response.json()])
|
||||
obj_list.extend([cls(i, response=response, conn=conn) for i in response.json()])
|
||||
return obj_list
|
||||
|
||||
@classmethod
|
||||
|
||||
Reference in New Issue
Block a user