diff --git a/README.md b/README.md index b33464b..e71aa58 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ If you want to get up and running with Code Review Manager immediately, run: ```bash +# your github username +export GITHUB_USER="your-github-username" # your personal github token used for interacting with the API export GITHUB_TOKEN="your-github-token" # comma seperated list of org/repo diff --git a/reviews/config.py b/reviews/config.py index f19fe09..b55df94 100644 --- a/reviews/config.py +++ b/reviews/config.py @@ -5,6 +5,7 @@ # Github Config GITHUB_TOKEN = config("GITHUB_TOKEN", cast=str, default="") +GITHUB_USER = config("GITHUB_USER", cast=str, default="") DEFAULT_PAGE_SIZE = config("DEFAULT_PAGE_SIZE", cast=int, default=100) # Database Config diff --git a/reviews/controller.py b/reviews/controller.py index bfd7334..f2713cb 100644 --- a/reviews/controller.py +++ b/reviews/controller.py @@ -1,7 +1,9 @@ -from typing import List, Union +from typing import Dict, List, Union +from github.PullRequest import PullRequest as ghPullRequest from rich.table import Table +from reviews import config from reviews.datasource import Label, PullRequest from reviews.layout import render_pull_request_table from reviews.source_control import GithubAPI @@ -23,20 +25,49 @@ def retrieve_pull_requests(self, org: str, repository: str) -> Union[Table, None return None return render_pull_request_table( - title=title, pull_requests=pull_requests, org=org, repository=repository + title=title, + pull_requests=pull_requests, + org=org, + repository=repository, ) def update_pull_requests(self, org: str, repository: str) -> List[PullRequest]: """Updates repository models.""" - pull_requests = self.client.get_pull_requests(org=org, repo=repository) + def _get_reviews(pull_request: ghPullRequest) -> Dict[str, str]: + """Inner function to retrieve reviews for a pull request""" + reviews = sorted( + pull_request.get_reviews(), + key=lambda r: r.submitted_at, + reverse=True, + ) + res, seen = {}, [] + for review in reviews: + if review.user.login in seen or review.state == "COMMENTED": + continue + res[review.user.login] = review.state + seen.append(review.user.login) + return res + + pull_requests = self.client.get_pull_requests(org=org, repo=repository) return [ PullRequest( number=pull_request.number, title=pull_request.title, created_at=pull_request.created_at, updated_at=pull_request.updated_at, - approved=any(pull_request.get_reviews()), # NOQA: R1721 + approved=_get_reviews(pull_request=pull_request).get( + config.GITHUB_USER, "" + ), # NOQA: R1721 + approved_by_others=any( + [ + True + for user, status in _get_reviews( + pull_request=pull_request + ).items() + if user != config.GITHUB_USER and status == "APPROVED" + ] + ), labels=[ Label(name=label.name) for label in pull_request.get_labels() diff --git a/reviews/datasource/managers/pull_requests.py b/reviews/datasource/managers/pull_requests.py index 66a6f4b..cf605c3 100644 --- a/reviews/datasource/managers/pull_requests.py +++ b/reviews/datasource/managers/pull_requests.py @@ -24,7 +24,8 @@ def create_table(self): title text NOT NULL, created_at text NOT NULL, updated_at text NOT NULL, - approved INTEGER DEFAULT 0 + approved text DEFAULT NULL, + approved_by_others BOOL DEFAULT FALSE ); """ return self.client.query(sql=sql) @@ -71,9 +72,10 @@ def insert(self, model): created_at, updated_at, approved, + approved_by_others, number ) - VALUES (?,?,?,?,?); + VALUES (?,?,?,?,?,?); """ return self.client.insert( @@ -83,6 +85,7 @@ def insert(self, model): model.created_at, model.updated_at, model.approved, + model.approved_by_others, model.number, ), ) @@ -96,6 +99,7 @@ def update(self, row_id: int, model: PullRequest): created_at = ?, updated_at = ?, approved = ?, + approved_by_others=?, number = ? WHERE id = ?; """ @@ -107,6 +111,7 @@ def update(self, row_id: int, model: PullRequest): model.created_at, model.updated_at, model.approved, + model.approved_by_others, model.number, row_id, ), diff --git a/reviews/datasource/models.py b/reviews/datasource/models.py index 935b548..4037fe5 100644 --- a/reviews/datasource/models.py +++ b/reviews/datasource/models.py @@ -18,5 +18,6 @@ class PullRequest: title: str created_at: datetime updated_at: datetime - approved: bool + approved: str + approved_by_others: bool labels: List[Label] = field(default_factory=list) diff --git a/reviews/layout/helpers.py b/reviews/layout/helpers.py index 49f5e5e..34057c7 100644 --- a/reviews/layout/helpers.py +++ b/reviews/layout/helpers.py @@ -22,12 +22,20 @@ def render_pull_request_table( table.add_column(title, width=60) table.add_column("Labels", width=40) table.add_column("Activity", width=15) - table.add_column("Status", width=10) + table.add_column("Approved", width=15) + table.add_column("Ready To Release", width=10) pull_requests = sorted(pull_requests, key=lambda x: x.updated_at, reverse=True) for pr in pull_requests: - approved = "[green]Approved" if pr.approved else "" + approved = "" + if pr.approved == "APPROVED": + approved = "[green]Approved" + elif pr.approved == "CHANGES_REQUESTED": + approved = "[yellow]Changes Requested" + + approved_by_others = "[green]Ready" if pr.approved_by_others else "" + updated_at = humanize.naturaltime(pr.updated_at) colour = "" @@ -47,6 +55,7 @@ def render_pull_request_table( f"{labels}", f"{updated_at}", f"{approved}", + f"{approved_by_others}", ) return table @@ -62,8 +71,8 @@ def generate_layout() -> Layout: Layout(name="footer", size=7), ) layout["main"].split_row( - Layout(name="left_side"), - Layout(name="body", ratio=2, minimum_size=60), + Layout(name="left_side", size=50), + Layout(name="body", ratio=2, minimum_size=80), ) layout["left_side"].split(Layout(name="configuration"), Layout(name="log")) return layout @@ -113,7 +122,10 @@ def generate_progress_tracker(): border_style="blue", ), Panel( - progress, title="[b]Next fetch for:", border_style="blue", padding=(1, 2) + progress, + title="[b]Next fetch for:", + border_style="blue", + padding=(1, 2), ), ) diff --git a/tests/datasource/test_client.py b/tests/datasource/test_client.py index 76f0c20..219dc21 100644 --- a/tests/datasource/test_client.py +++ b/tests/datasource/test_client.py @@ -25,7 +25,8 @@ def pull_request(): title="[1] Initial Commit", created_at=datetime.now(), updated_at=datetime.now(), - approved=False, + approved=None, + approved_by_others=False, labels=[Label(name="Python")], ) @@ -62,7 +63,8 @@ def test_bulk_insert(manager): title="[1] Initial Commit", created_at=datetime.now(), updated_at=datetime.now(), - approved=False, + approved=None, + approved_by_others=False, labels=[Label(name="Python")], ), PullRequest( @@ -70,7 +72,8 @@ def test_bulk_insert(manager): title="[2] Adds README", created_at=datetime.now(), updated_at=datetime.now(), - approved=False, + approved=None, + approved_by_others=False, labels=[Label(name="Python")], ), ] @@ -83,6 +86,7 @@ def test_update(manager, pull_request): last_row_id = manager.insert(model=pull_request) pull_request.title = "[1] Initial setup of repository" + pull_request.approved_by_others = True manager.update(row_id=last_row_id, model=pull_request) assert len(manager.all()) == 1 @@ -93,7 +97,8 @@ def test_update(manager, pull_request): "[1] Initial setup of repository", "2020-01-01 00:00:00", "2020-01-01 00:00:00", - 0, + None, + 1, ) ]