check metalog for associated PR info

Reviewed By: DurhamG

Differential Revision: D39756566

fbshipit-source-id: 70a05a00974132277ccba9944e7df5c3ca7f54f8
This commit is contained in:
Michael Bolin 2022-09-27 12:37:40 -07:00 committed by Facebook GitHub Bot
parent 220814d9e5
commit c785e70967
3 changed files with 68 additions and 26 deletions

View File

@ -58,44 +58,44 @@ def github_repo(repo, ctx, templ, **args) -> bool:
return gh_repo.is_github_repo(repo)
def _get_pull_request_field(field_name: str, ctx, **args):
pull_request_data = templates.get_pull_request_data_for_rev(ctx, **args)
def _get_pull_request_field(field_name: str, repo, ctx, **args):
pull_request_data = templates.get_pull_request_data_for_rev(repo, ctx, **args)
return pull_request_data[field_name] if pull_request_data else None
@templatekeyword("github_pull_request_state")
def github_pull_request_state(repo, ctx, templ, **args) -> Optional[str]:
return _get_pull_request_field("state", ctx, **args)
return _get_pull_request_field("state", repo, ctx, **args)
@templatekeyword("github_pull_request_closed")
def github_pull_request_closed(repo, ctx, templ, **args) -> Optional[bool]:
return _get_pull_request_field("closed", ctx, **args)
return _get_pull_request_field("closed", repo, ctx, **args)
@templatekeyword("github_pull_request_merged")
def github_pull_request_merged(repo, ctx, templ, **args) -> Optional[bool]:
return _get_pull_request_field("merged", ctx, **args)
return _get_pull_request_field("merged", repo, ctx, **args)
@templatekeyword("github_pull_request_review_decision")
def github_pull_request_review_decision(repo, ctx, templ, **args) -> Optional[str]:
return _get_pull_request_field("review_decision", ctx, **args)
return _get_pull_request_field("review_decision", repo, ctx, **args)
@templatekeyword("github_pull_request_is_draft")
def github_pull_request_is_draft(repo, ctx, templ, **args) -> Optional[bool]:
return _get_pull_request_field("is_draft", ctx, **args)
return _get_pull_request_field("is_draft", repo, ctx, **args)
@templatekeyword("github_pull_request_title")
def github_pull_request_title(repo, ctx, templ, **args) -> Optional[str]:
return _get_pull_request_field("title", ctx, **args)
return _get_pull_request_field("title", repo, ctx, **args)
@templatekeyword("github_pull_request_body")
def github_pull_request_body(repo, ctx, templ, **args) -> Optional[str]:
return _get_pull_request_field("body", ctx, **args)
return _get_pull_request_field("body", repo, ctx, **args)
@templatekeyword("github_pull_request_url")
@ -103,7 +103,7 @@ def github_pull_request_url(repo, ctx, templ, **args) -> Optional[str]:
"""If the commit is associated with a GitHub pull request, returns the URL
for the pull request.
"""
pull_request = templates.get_pull_request_url_for_rev(ctx, **args)
pull_request = templates.get_pull_request_url_for_rev(repo, ctx, **args)
if pull_request:
pull_request_domain = repo.ui.config("github", "pull_request_domain")
return pull_request.as_url(domain=pull_request_domain)

View File

@ -11,43 +11,44 @@ from typing import Optional
from . import graphql
from .graphql import GitHubPullRequest
from .pullrequeststore import PullRequestStore
def github_pull_request_repo_owner(repo, ctx, **args) -> Optional[str]:
r"""Returns the repo owner for a pull request associated with a commit based
on the contents of the commit message, if appropriate.
>>> from .testutil import FakeContext, fake_args
>>> from .testutil import FakeContext, FakeRepo, fake_args
>>> descr = 'foo\nPull Request resolved: https://github.com/bolinfest/ghstack-testing/pull/71\nbar'
>>> github_pull_request_repo_owner(None, FakeContext(descr), **fake_args())
>>> github_pull_request_repo_owner(FakeRepo(), FakeContext(descr), **fake_args())
'bolinfest'
"""
pull_request = get_pull_request_url_for_rev(ctx, **args)
pull_request = get_pull_request_url_for_rev(repo, ctx, **args)
return pull_request.repo_owner if pull_request else None
def github_pull_request_repo_name(repo, ctx, **args) -> Optional[str]:
r"""Returns the repo name for a pull request associated with a commit based
on the contents of the commit message, if appropriate.
>>> from .testutil import FakeContext, fake_args
>>> from .testutil import FakeContext, FakeRepo, fake_args
>>> descr = 'foo\nPull Request resolved: https://github.com/bolinfest/ghstack-testing/pull/71\nbar'
>>> ctx = FakeContext(descr)
>>> github_pull_request_repo_name(None, FakeContext(descr), **fake_args())
>>> github_pull_request_repo_name(FakeRepo(), FakeContext(descr), **fake_args())
'ghstack-testing'
"""
pull_request = get_pull_request_url_for_rev(ctx, **args)
pull_request = get_pull_request_url_for_rev(repo, ctx, **args)
return pull_request.repo_name if pull_request else None
def github_pull_request_number(repo, ctx, **args) -> Optional[int]:
r"""Returns the number for a pull request associated with a commit based
on the contents of the commit message, if appropriate.
>>> from .testutil import FakeContext, fake_args
>>> from .testutil import FakeContext, FakeRepo, fake_args
>>> descr = 'foo\nPull Request resolved: https://github.com/bolinfest/ghstack-testing/pull/71\nbar'
>>> ctx = FakeContext(descr)
>>> github_pull_request_number(None, FakeContext(descr), **fake_args())
>>> github_pull_request_number(FakeRepo(), FakeContext(descr), **fake_args())
71
"""
pull_request = get_pull_request_url_for_rev(ctx, **args)
pull_request = get_pull_request_url_for_rev(repo, ctx, **args)
return pull_request.number if pull_request else None
@ -82,18 +83,32 @@ _NO_ENTRY = {}
_GITHUB_OAUTH_TOKEN_CACHE_KEY = "github_token"
_GITHUB_PULL_REQUEST_URL_REVCACHE_KEY = "github_pr_url"
_GITHUB_PULL_REQUEST_DATA_REVCACHE_KEY = "github_pr_data"
_GITHUB_PULL_REQUEST_STORE_KEY = "github_pr_store"
def get_pull_request_url_for_rev(ctx, **args) -> Optional[GitHubPullRequest]:
def get_pull_request_url_for_rev(repo, ctx, **args) -> Optional[GitHubPullRequest]:
revcache = args["revcache"]
pull_request_url = revcache.get(_GITHUB_PULL_REQUEST_URL_REVCACHE_KEY, _NO_ENTRY)
if pull_request_url is _NO_ENTRY:
pull_request_url = parse_github_pull_request_url(ctx.description())
revcache[_GITHUB_PULL_REQUEST_URL_REVCACHE_KEY] = pull_request_url
if pull_request_url is not _NO_ENTRY:
return pull_request_url
# Check the metalog first. If not in the metalog, look for special patterns
# in the commit message.
store = get_pull_request_store(repo, args["cache"])
pr = store.find_pull_request(ctx.node())
pull_request_url = (
GitHubPullRequest(repo_owner=pr.owner, repo_name=pr.name, number=int(pr.number))
if pr
else parse_github_pull_request_url(ctx.description())
)
revcache[_GITHUB_PULL_REQUEST_URL_REVCACHE_KEY] = (
pull_request_url if pull_request_url is not None else _NO_ENTRY
)
return pull_request_url
def get_pull_request_data_for_rev(ctx, **args):
def get_pull_request_data_for_rev(repo, ctx, **args):
revcache = args["revcache"]
pull_request_data = revcache.get(_GITHUB_PULL_REQUEST_DATA_REVCACHE_KEY, _NO_ENTRY)
@ -103,7 +118,7 @@ def get_pull_request_data_for_rev(ctx, **args):
pull_request_data = None
token = get_github_oauth_token(**args)
if token:
pull_request = get_pull_request_url_for_rev(ctx, **args)
pull_request = get_pull_request_url_for_rev(repo, ctx, **args)
if pull_request:
pull_request_data = graphql.get_pull_request_data(token, pull_request)
revcache[_GITHUB_PULL_REQUEST_DATA_REVCACHE_KEY] = pull_request_data
@ -118,3 +133,13 @@ def get_github_oauth_token(**args) -> Optional[str]:
token = graphql.get_github_oauth_token()
cache[_GITHUB_OAUTH_TOKEN_CACHE_KEY] = token
return token
def get_pull_request_store(repo, cache) -> PullRequestStore:
store = cache.get(_GITHUB_PULL_REQUEST_STORE_KEY)
if store:
return store
store = PullRequestStore(repo)
cache[_GITHUB_PULL_REQUEST_STORE_KEY] = store
return store

View File

@ -7,6 +7,18 @@
"""
class FakeRepo:
pass
class FakePullRequestStore:
def find_pull_request(self, node: bytes):
return None
fake_pull_request_store_singleton = FakePullRequestStore()
class FakeContext:
def __init__(self, desc: str):
self._desc = desc
@ -14,9 +26,14 @@ class FakeContext:
def description(self) -> str:
return self._desc
def node(self) -> bytes:
return b"\x0d\x0e\x0a\x0d\x0b\x0e\x0e\x0f" * 5
def fake_args():
return {
"cache": {},
"cache": {
"github_pr_store": fake_pull_request_store_singleton,
},
"revcache": {},
}