Skip to content

Commit

Permalink
Differentiate between a partial and full PR in types
Browse files Browse the repository at this point in the history
  • Loading branch information
gizmo385 committed Jun 25, 2024
1 parent ab09468 commit 998ef57
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 29 deletions.
15 changes: 10 additions & 5 deletions lazy_github/lib/github/issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from typing import Literal

from lazy_github.lib.github.client import GithubClient
from lazy_github.models.github import Issue, PullRequest, Repository, User
from lazy_github.models.github import Issue, PartialPullRequest, Repository, User

IssueStateFilter = Literal["open"] | Literal["closed"] | Literal["all"]

Expand All @@ -16,9 +16,9 @@ async def _list(client: GithubClient, repo: Repository, state: IssueStateFilter)
result: list[Issue] = []
for issue in response.json():
if "draft" in issue:
result.append(PullRequest(**issue))
result.append(PartialPullRequest(**issue, repo=repo))
else:
result.append(Issue(**issue))
result.append(Issue(**issue, repo=repo))
return result


Expand All @@ -29,6 +29,11 @@ async def _list(client: GithubClient, repo: Repository, state: IssueStateFilter)

if __name__ == "__main__":
import asyncio
import logging

logging.basicConfig(
format="%(levelname)s [%(asctime)s] %(name)s - %(message)s", datefmt="%Y-%m-%d %H:%M:%S", level=logging.DEBUG
)

from lazy_github.lib.config import Config
from lazy_github.lib.github.auth import token
Expand All @@ -40,11 +45,11 @@ async def _list(client: GithubClient, repo: Repository, state: IssueStateFilter)
default_branch="main",
private=False,
archived=False,
owner=User(login="gizmo385", id=1),
owner=User(login="gizmo385", id=1, html_url="wat"),
)
issues = asyncio.run(_list(client, repo, "all"))
for issue in issues:
if isinstance(issue, PullRequest):
if isinstance(issue, PartialPullRequest):
print(f"Pull Request #{issue.number}: '{issue.title}' by {issue.user.login}")
else:
print(f"Issue #{issue.number}: {issue.title}")
14 changes: 11 additions & 3 deletions lazy_github/lib/github/pull_requests.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
from lazy_github.lib.github.client import GithubClient
from lazy_github.lib.github.issues import list_all_issues
from lazy_github.models.github import PullRequest, Repository
from lazy_github.models.github import FullPullRequest, PartialPullRequest, Repository


async def list_for_repo(client: GithubClient, repo: Repository) -> list[PullRequest]:
async def list_for_repo(client: GithubClient, repo: Repository) -> list[PartialPullRequest]:
issues = await list_all_issues(client, repo)
return [i for i in issues if isinstance(i, PullRequest)]
return [i for i in issues if isinstance(i, PartialPullRequest)]


async def get_full_pull_request(client: GithubClient, partial_pr: PartialPullRequest) -> FullPullRequest:
user = await client.user()
url = f"/repos/{user.login}/{partial_pr.repo.name}/pulls/{partial_pr.number}"
response = await client.get(url, headers=client.headers_with_auth_accept())
response.raise_for_status()
return FullPullRequest(**response.json(), repo=partial_pr.repo)
10 changes: 5 additions & 5 deletions lazy_github/lib/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from textual.message import Message

from lazy_github.models.github import Issue, PullRequest, Repository
from lazy_github.models.github import Issue, PartialPullRequest, Repository


class RepoSelected(Message):
Expand All @@ -23,7 +23,7 @@ class PullRequestSelected(Message):
A message indicating that the user is looking for additional information on a particular pull request.
"""

def __init__(self, pr: PullRequest) -> None:
def __init__(self, pr: PartialPullRequest) -> None:
self.pr = pr
super().__init__()

Expand All @@ -39,13 +39,13 @@ def __init__(self, issues_and_pull_requests: list[Issue]) -> None:
super().__init__()

@cached_property
def pull_requests(self) -> list[PullRequest]:
return [pr for pr in self.issues_and_pull_requests if isinstance(pr, PullRequest)]
def pull_requests(self) -> list[PartialPullRequest]:
return [pr for pr in self.issues_and_pull_requests if isinstance(pr, PartialPullRequest)]

@cached_property
def issues(self) -> list[Issue]:
return [
issue
for issue in self.issues_and_pull_requests
if isinstance(issue, Issue) and not isinstance(issue, PullRequest)
if isinstance(issue, Issue) and not isinstance(issue, PartialPullRequest)
]
30 changes: 29 additions & 1 deletion lazy_github/models/github.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from datetime import datetime
from enum import StrEnum

from pydantic import BaseModel
Expand All @@ -7,6 +8,7 @@ class User(BaseModel):
login: str
id: int
name: str | None = None
html_url: str
followers: int | None = None
following: int | None = None

Expand Down Expand Up @@ -44,10 +46,36 @@ class Issue(BaseModel):
title: str
body: str | None = None
user: User
created_at: datetime
updated_at: datetime
closed_at: datetime | None = None
closed_by: User | None = None
assignee: User | None = None
assignees: list[User] | None
repo: Repository


class PullRequest(Issue):
class Ref(BaseModel):
user: User
ref: str


class PartialPullRequest(Issue):
"""
A pull request that may be included in the response to a list issues API call and is missing some information
"""

draft: bool


class FullPullRequest(PartialPullRequest):
"""More comprehensive details on a pull request from the API"""

additions: int
deletions: int
changed_files: int
commits: int
head: Ref
base: Ref
html_url: str
merged_at: datetime | None
11 changes: 7 additions & 4 deletions lazy_github/ui/screens/primary.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from lazy_github.lib.github.client import GithubClient
from lazy_github.lib.github.issues import list_all_issues
from lazy_github.lib.github.pull_requests import get_full_pull_request
from lazy_github.lib.messages import IssuesAndPullRequestsFetched, PullRequestSelected, RepoSelected
from lazy_github.ui.widgets.actions import ActionsContainer
from lazy_github.ui.widgets.command_log import CommandLogSection
Expand Down Expand Up @@ -149,13 +150,15 @@ def compose(self) -> ComposeResult:
yield SelectionsPane(self.client)
yield SelectionDetailsPane(self.client)

def on_pull_request_selected(self, message: PullRequestSelected) -> None:
async def on_pull_request_selected(self, message: PullRequestSelected) -> None:
log(f"PR = {message.pr}")
full_pr = await get_full_pull_request(self.client, message.pr)
log(f"Full PR = {full_pr}")
tabbed_content = self.query_one("#selection_detail_tabs", TabbedContent)
tabbed_content.clear_panes()
tabbed_content.add_pane(PrOverviewTabPane(message.pr))
tabbed_content.add_pane(PrDiffTabPane(message.pr))
tabbed_content.add_pane(PrConversationTabPane(message.pr))
tabbed_content.add_pane(PrOverviewTabPane(full_pr))
tabbed_content.add_pane(PrDiffTabPane(full_pr))
tabbed_content.add_pane(PrConversationTabPane(full_pr))
tabbed_content.focus()


Expand Down
26 changes: 15 additions & 11 deletions lazy_github/ui/widgets/pull_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@
from textual.coordinate import Coordinate
from textual.widgets import Label, ListView, Markdown, RichLog, Rule, TabPane

import lazy_github.lib.github.pull_requests as pr_api
from lazy_github.lib.github.client import GithubClient
from lazy_github.lib.messages import IssuesAndPullRequestsFetched, PullRequestSelected
from lazy_github.lib.string_utils import bold, link, pluralize
from lazy_github.models.github import PullRequest
from lazy_github.models.github import FullPullRequest, PartialPullRequest
from lazy_github.ui.widgets.command_log import log_event
from lazy_github.ui.widgets.common import LazyGithubContainer, LazyGithubDataTable

Expand All @@ -22,7 +21,7 @@ class PullRequestsContainer(LazyGithubContainer):

def __init__(self, client: GithubClient, *args, **kwargs) -> None:
self.client = client
self.pull_requests: Dict[int, PullRequest] = {}
self.pull_requests: Dict[int, PartialPullRequest] = {}
self.status_column_index = -1
self.number_column_index = -1
self.title_column_index = -1
Expand Down Expand Up @@ -58,9 +57,10 @@ async def on_issues_and_pull_requests_fetched(self, message: IssuesAndPullReques
rows.append((pr.state, pr.number, pr.user.login, pr.title))
self.table.add_rows(rows)

async def get_selected_pr(self) -> PullRequest:
async def get_selected_pr(self) -> PartialPullRequest:
pr_number_coord = Coordinate(self.table.cursor_row, self.number_column_index)
number = self.table.get_cell_at(pr_number_coord)
# full_pr = pr_api.get_pull_request(self.client, number)
return self.pull_requests[number]

@on(LazyGithubDataTable.RowSelected, "#pull_requests_table")
Expand All @@ -77,15 +77,19 @@ class PrOverviewTabPane(TabPane):
}
"""

def __init__(self, pr: PullRequest) -> None:
def __init__(self, pr: FullPullRequest) -> None:
super().__init__("Overview", id="overview_pane")
self.pr = pr

def _old_compose(self) -> ComposeResult:
def compose(self) -> ComposeResult:
pr_link = link(f"(#{self.pr.number})", self.pr.html_url)
user_link = link(self.pr.user.login, self.pr.user.html_url)
merge_from = bold(f"{self.pr.head.user.login}:{self.pr.head.ref}")
merge_to = bold(f"{self.pr.base.user.login}:{self.pr.base.ref}")
merge_from = None
if self.pr.head:
merge_from = bold(f"{self.pr.head.user.login}:{self.pr.head.ref}")
merge_to = None
if self.pr.base:
merge_to = bold(f"{self.pr.base.user.login}:{self.pr.base.ref}")

change_summary = " • ".join(
[
Expand Down Expand Up @@ -117,11 +121,11 @@ def _old_compose(self) -> ComposeResult:


class PrDiffTabPane(TabPane):
def __init__(self, pr: PullRequest) -> None:
def __init__(self, pr: FullPullRequest) -> None:
super().__init__("Diff", id="diff_pane")
self.pr = pr

def _old_compose(self) -> ComposeResult:
def compose(self) -> ComposeResult:
with ScrollableContainer():
yield RichLog(id="diff_contents", highlight=True)

Expand All @@ -140,7 +144,7 @@ def on_mount(self) -> None:


class PrConversationTabPane(TabPane):
def __init__(self, pr: PullRequest) -> None:
def __init__(self, pr: FullPullRequest) -> None:
super().__init__("Conversation", id="conversation_pane")
self.pr = pr

Expand Down

0 comments on commit 998ef57

Please sign in to comment.