mirror of
https://github.com/openSUSE/osc.git
synced 2025-11-27 06:59: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:
|
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)
|
json.dump(submodule_diff, f, indent=4, sort_keys=True)
|
||||||
|
|
||||||
linked_prs = {}
|
referenced_pull_requests = {}
|
||||||
|
for ref_owner, ref_repo, ref_number in pr_obj.parse_pr_references():
|
||||||
# body may contain references with both https:// or without, which look indetical in UI. so we must handle both cases:
|
ref_id = f"{ref_owner}/{ref_repo}#{ref_number}"
|
||||||
for url in re.findall(r"https?://[^\s]+/pulls/\d+", pr_obj.body):
|
referenced_pr_obj = gitea_api.PullRequest.get(self.gitea_conn, ref_owner, ref_repo, ref_number)
|
||||||
if not self.gitea_conn.host in url:
|
referenced_pull_requests[ref_id] = referenced_pr_obj.dict()
|
||||||
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
|
|
||||||
|
|
||||||
with open(
|
with open(
|
||||||
os.path.join(metadata_dir, "referenced-pull-requests.json"),
|
os.path.join(metadata_dir, "referenced-pull-requests.json"),
|
||||||
"w",
|
"w",
|
||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
) as f:
|
) 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:
|
if warnings:
|
||||||
return 38
|
return 38
|
||||||
|
|||||||
@@ -10,11 +10,7 @@ from .connection import GiteaHTTPResponse
|
|||||||
from .user import User
|
from .user import User
|
||||||
|
|
||||||
|
|
||||||
class PullRequestReview:
|
class PullRequestReview(GiteaModel):
|
||||||
def __init__(self, data: dict, *, response: Optional[GiteaHTTPResponse] = None):
|
|
||||||
self._data = data
|
|
||||||
self._response = response
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def state(self) -> str:
|
def state(self) -> str:
|
||||||
return self._data["state"]
|
return self._data["state"]
|
||||||
@@ -104,9 +100,34 @@ class PullRequest(GiteaModel):
|
|||||||
parsed_url = urllib.parse.urlparse(url)
|
parsed_url = urllib.parse.urlparse(url)
|
||||||
path = parsed_url.path
|
path = parsed_url.path
|
||||||
owner, repo, pulls, number = path.strip("/").split("/")
|
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)
|
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
|
@property
|
||||||
def is_pull_request(self):
|
def is_pull_request(self):
|
||||||
# determine if we're working with a proper pull request or an issue without pull request details
|
# 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,
|
"body": description,
|
||||||
}
|
}
|
||||||
response = conn.request("POST", url, json_data=data)
|
response = conn.request("POST", url, json_data=data)
|
||||||
obj = cls(response.json(), response=response)
|
obj = cls(response.json(), response=response, conn=conn)
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -358,7 +379,7 @@ class PullRequest(GiteaModel):
|
|||||||
"""
|
"""
|
||||||
url = conn.makeurl("repos", owner, repo, "pulls", str(number))
|
url = conn.makeurl("repos", owner, repo, "pulls", str(number))
|
||||||
response = conn.request("GET", url)
|
response = conn.request("GET", url)
|
||||||
obj = cls(response.json(), response=response)
|
obj = cls(response.json(), response=response, conn=conn)
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -391,7 +412,7 @@ class PullRequest(GiteaModel):
|
|||||||
}
|
}
|
||||||
url = conn.makeurl("repos", owner, repo, "pulls", str(number))
|
url = conn.makeurl("repos", owner, repo, "pulls", str(number))
|
||||||
response = conn.request("PATCH", url, json_data=json_data)
|
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
|
return obj
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -420,7 +441,7 @@ class PullRequest(GiteaModel):
|
|||||||
}
|
}
|
||||||
url = conn.makeurl("repos", owner, repo, "pulls", query=q)
|
url = conn.makeurl("repos", owner, repo, "pulls", query=q)
|
||||||
response = conn.request("GET", url)
|
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
|
return obj_list
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -464,7 +485,7 @@ class PullRequest(GiteaModel):
|
|||||||
url = conn.makeurl("repos", "issues", "search", query=q)
|
url = conn.makeurl("repos", "issues", "search", query=q)
|
||||||
obj_list = []
|
obj_list = []
|
||||||
for response in conn.request_all_pages("GET", url):
|
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
|
return obj_list
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|||||||
Reference in New Issue
Block a user