Compare commits
2 Commits
5c73d55d91
...
f81bf8c4df
Author | SHA1 | Date | |
---|---|---|---|
f81bf8c4df | |||
3064d0231c |
@ -1,7 +1,6 @@
|
|||||||
import typer
|
import typer
|
||||||
import json
|
import json
|
||||||
from typing import Annotated
|
from typing import Annotated
|
||||||
from rich.console import Console
|
|
||||||
from nixprstatus.pr import pr_merge_status
|
from nixprstatus.pr import pr_merge_status
|
||||||
from nixprstatus.pr import commits_since
|
from nixprstatus.pr import commits_since
|
||||||
from nixprstatus.watchlist import Watchlist
|
from nixprstatus.watchlist import Watchlist
|
||||||
@ -24,26 +23,17 @@ def pr(
|
|||||||
branches: Annotated[
|
branches: Annotated[
|
||||||
list[str] | None, typer.Option(help="Check specific branch")
|
list[str] | None, typer.Option(help="Check specific branch")
|
||||||
] = None,
|
] = None,
|
||||||
|
format: Annotated[
|
||||||
|
OutputFormat, typer.Option(help="Output format")
|
||||||
|
] = OutputFormat.CONSOLE,
|
||||||
):
|
):
|
||||||
"""Get merge status of pull request."""
|
"""Get merge status of pull request."""
|
||||||
console = Console()
|
|
||||||
|
|
||||||
if branches:
|
if branches:
|
||||||
status = pr_merge_status(pr, branches)
|
status = pr_merge_status(pr, branches)
|
||||||
else:
|
else:
|
||||||
status = pr_merge_status(pr)
|
status = pr_merge_status(pr)
|
||||||
|
|
||||||
console.print(f"{status.title}\n", highlight=False)
|
status.print(format=format)
|
||||||
merged = ":white_check_mark: merged" if status.merged else ":x: merged"
|
|
||||||
console.print(merged, highlight=False)
|
|
||||||
|
|
||||||
for branch in status.branches:
|
|
||||||
output = (
|
|
||||||
f":white_check_mark: {branch}"
|
|
||||||
if status.branches[branch]
|
|
||||||
else f":x: {branch}"
|
|
||||||
)
|
|
||||||
console.print(output, highlight=False)
|
|
||||||
|
|
||||||
|
|
||||||
@app.command()
|
@app.command()
|
||||||
@ -69,17 +59,16 @@ def since(
|
|||||||
@watchlist_app.command()
|
@watchlist_app.command()
|
||||||
def list(watchlist: str | None = None, format: OutputFormat = OutputFormat.CONSOLE):
|
def list(watchlist: str | None = None, format: OutputFormat = OutputFormat.CONSOLE):
|
||||||
"""List PRs in watchlist."""
|
"""List PRs in watchlist."""
|
||||||
wl = Watchlist.from_file()
|
wl = Watchlist.from_file(path=watchlist)
|
||||||
wl.print(format=format)
|
wl.print(format=format)
|
||||||
|
|
||||||
|
|
||||||
@watchlist_app.command()
|
@watchlist_app.command()
|
||||||
def add(pr: int):
|
def add(pr: int, watchlist: str | None = None):
|
||||||
"""Add PR to watchlist."""
|
"""Add PR to watchlist."""
|
||||||
wl = Watchlist.from_file()
|
wl = Watchlist.from_file(path=watchlist)
|
||||||
wl.add_pr(pr)
|
info = wl.add_pr(pr)
|
||||||
wl.to_file()
|
wl.to_file(path=watchlist)
|
||||||
info = wl.pr(pr)
|
|
||||||
print(f"Added #{info.pr}: {info.title} to watchlist.")
|
print(f"Added #{info.pr}: {info.title} to watchlist.")
|
||||||
|
|
||||||
|
|
||||||
@ -87,6 +76,9 @@ def add(pr: int):
|
|||||||
def remove(pr: int):
|
def remove(pr: int):
|
||||||
"""Remove PR from watchlist."""
|
"""Remove PR from watchlist."""
|
||||||
wl = Watchlist.from_file()
|
wl = Watchlist.from_file()
|
||||||
|
if pr not in wl:
|
||||||
|
print(f"#{pr} not in watchlist.")
|
||||||
|
return
|
||||||
wl.remove(pr)
|
wl.remove(pr)
|
||||||
wl.to_file()
|
wl.to_file()
|
||||||
print(f"Removed #{pr} from watchlist.")
|
print(f"Removed #{pr} from watchlist.")
|
||||||
|
6
nixprstatus/output.py
Normal file
6
nixprstatus/output.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
class OutputFormat(str, Enum):
|
||||||
|
CONSOLE = "console"
|
||||||
|
JSON = "json"
|
@ -1,5 +1,8 @@
|
|||||||
import requests
|
import requests
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
from rich.console import Console
|
||||||
|
|
||||||
|
from nixprstatus.output import OutputFormat
|
||||||
|
|
||||||
DEFAULT_HEADERS = {
|
DEFAULT_HEADERS = {
|
||||||
"Accept": "application/vnd.github.text+json",
|
"Accept": "application/vnd.github.text+json",
|
||||||
@ -13,6 +16,26 @@ class PRStatus(BaseModel):
|
|||||||
merged: bool
|
merged: bool
|
||||||
branches: dict[str, bool]
|
branches: dict[str, bool]
|
||||||
|
|
||||||
|
def print(self, format: OutputFormat = OutputFormat.CONSOLE):
|
||||||
|
match format:
|
||||||
|
case OutputFormat.JSON:
|
||||||
|
print(self.model_dump_json())
|
||||||
|
case OutputFormat.CONSOLE:
|
||||||
|
console = Console(highlight=False)
|
||||||
|
console.print(f"{self.title}\n")
|
||||||
|
merged = ":white_check_mark: merged" if self.merged else ":x: merged"
|
||||||
|
console.print(merged)
|
||||||
|
|
||||||
|
for branch in self.branches:
|
||||||
|
output = (
|
||||||
|
f":white_check_mark: {branch}"
|
||||||
|
if self.branches[branch]
|
||||||
|
else f":x: {branch}"
|
||||||
|
)
|
||||||
|
console.print(output)
|
||||||
|
case _:
|
||||||
|
raise ValueError(f"Unknown format: {format}")
|
||||||
|
|
||||||
|
|
||||||
def commit_in_branch(commit_sha: str, branch: str) -> bool:
|
def commit_in_branch(commit_sha: str, branch: str) -> bool:
|
||||||
url = f"https://api.github.com/repos/NixOS/nixpkgs/compare/{branch}...{commit_sha}"
|
url = f"https://api.github.com/repos/NixOS/nixpkgs/compare/{branch}...{commit_sha}"
|
||||||
|
@ -1,16 +1,11 @@
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
from enum import Enum
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
|
|
||||||
from nixprstatus.pr import get_pr
|
from nixprstatus.pr import get_pr
|
||||||
|
from nixprstatus.output import OutputFormat
|
||||||
|
|
||||||
class OutputFormat(str, Enum):
|
|
||||||
CONSOLE = "console"
|
|
||||||
JSON = "json"
|
|
||||||
|
|
||||||
|
|
||||||
class PRInfo(BaseModel):
|
class PRInfo(BaseModel):
|
||||||
@ -45,12 +40,14 @@ class Watchlist(BaseModel):
|
|||||||
with open(p, "w") as f:
|
with open(p, "w") as f:
|
||||||
f.write(self.model_dump_json())
|
f.write(self.model_dump_json())
|
||||||
|
|
||||||
def add_pr(self, pr: int):
|
def add_pr(self, pr: int) -> PRInfo:
|
||||||
# Lookup PR info
|
# Lookup PR info
|
||||||
info = get_pr(pr)
|
info = get_pr(pr)
|
||||||
|
|
||||||
title = info["title"]
|
title = info["title"]
|
||||||
self.prs.append(PRInfo(pr=pr, title=title))
|
info = PRInfo(pr=pr, title=title)
|
||||||
|
self.prs.append(info)
|
||||||
|
return info
|
||||||
|
|
||||||
def remove(self, pr: int):
|
def remove(self, pr: int):
|
||||||
self.prs = [p for p in self.prs if p.pr != pr]
|
self.prs = [p for p in self.prs if p.pr != pr]
|
||||||
@ -72,6 +69,13 @@ class Watchlist(BaseModel):
|
|||||||
return p
|
return p
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def __contains__(self, item: PRInfo | int):
|
||||||
|
match item:
|
||||||
|
case PRInfo():
|
||||||
|
return any([x == item for x in self.prs])
|
||||||
|
case int():
|
||||||
|
return any([x.pr == item for x in self.prs])
|
||||||
|
|
||||||
|
|
||||||
def _default_path() -> str:
|
def _default_path() -> str:
|
||||||
if "XDG_STATE_HOME" in os.environ:
|
if "XDG_STATE_HOME" in os.environ:
|
||||||
@ -79,6 +83,6 @@ def _default_path() -> str:
|
|||||||
return "~/.config/nixprstatus/watchlist.json"
|
return "~/.config/nixprstatus/watchlist.json"
|
||||||
|
|
||||||
|
|
||||||
def _ensure_default_path() -> str:
|
def _ensure_default_path():
|
||||||
p = Path(_default_path()).expanduser()
|
p = Path(_default_path()).expanduser()
|
||||||
p.parent.mkdir(parents=True, exist_ok=True)
|
p.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "nixprstatus"
|
name = "nixprstatus"
|
||||||
version = "0.1.4"
|
version = "0.1.5"
|
||||||
description = "Nixpkgs PR status checker"
|
description = "Nixpkgs PR status checker"
|
||||||
authors = ["Torjus Håkestad <torjus@usit.uio.no>"]
|
authors = ["Torjus Håkestad <torjus@usit.uio.no>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
@ -32,3 +32,9 @@ class TestWatchlist(unittest.TestCase):
|
|||||||
w = Watchlist(prs=[PRInfo(pr=1, title="PR 1")])
|
w = Watchlist(prs=[PRInfo(pr=1, title="PR 1")])
|
||||||
self.assertEqual(w.pr(1), PRInfo(pr=1, title="PR 1"))
|
self.assertEqual(w.pr(1), PRInfo(pr=1, title="PR 1"))
|
||||||
self.assertEqual(w.pr(2), None)
|
self.assertEqual(w.pr(2), None)
|
||||||
|
|
||||||
|
def test_contains(self):
|
||||||
|
w = Watchlist(prs=[PRInfo(pr=1, title="PR 1")])
|
||||||
|
self.assertIn(PRInfo(pr=1, title="PR 1"), w)
|
||||||
|
self.assertIn(1, w)
|
||||||
|
self.assertNotIn(2, w)
|
||||||
|
Loading…
Reference in New Issue
Block a user