diff --git a/.config/dictionary.txt b/.config/dictionary.txt index befe713..ec6a3e5 100644 --- a/.config/dictionary.txt +++ b/.config/dictionary.txt @@ -14,4 +14,6 @@ notest pycontribs pypa setuptools +tablerender +timeago typer diff --git a/src/gh_pre/__main__.py b/src/gh_pre/__main__.py index 3059ec6..945b664 100644 --- a/src/gh_pre/__main__.py +++ b/src/gh_pre/__main__.py @@ -16,20 +16,32 @@ from typer_config.decorators import use_yaml_config -app = typer.Typer() +class TyperApp(typer.Typer): + """Our App.""" + repos: list[str] -@app.command() + +app = TyperApp() +console = Console() + + +@app.callback(invoke_without_command=True) @use_yaml_config( default_value=os.path.expanduser("~/pre.yml"), param_help="Configuration file (~/pre.yml).", ) -def main(repos: Annotated[Optional[list[str]], typer.Option()] = None) -> None: - """Pre helps you chain releases on github.""" +def default(repos: Annotated[Optional[list[str]], typer.Option()] = None) -> None: + """Implicit entry point.""" if repos is None: repos = [] - console = Console() - for repo in repos: + app.repos = repos + + +@app.command() +def main() -> None: + """Pre helps you chain releases on github.""" + for repo in app.repos: repo_link = f"[markdown.link][link=https://github.com/{repo}]{repo}[/][/]" result = run( f'gh api repos/{repo}/releases --jq "[.[] | select(.draft)"]', @@ -63,6 +75,51 @@ def main(repos: Annotated[Optional[list[str]], typer.Option()] = None) -> None: console.print(md, style="dim") +@app.command() +def prs() -> None: + """List pending pull-request.""" + # for user in TEAM: + # --review-requested=@{user} + # --owner=ansible --owner=ansible-community + cmd = ( + "GH_PAGER= gh search prs --draft=false --state=open --limit=100 --sort=updated" + ) + cmd += "".join(f" --repo={repo}" for repo in app.repos) + cmd += ( + " --template '{{range .}}{{tablerow .repository.nameWithOwner (timeago .updatedAt) " + '.title (hyperlink .url (printf "#%v" .number) ) }}{{end}}{{tablerender}}\' ' + "--json title,url,repository,updatedAt,number" + ) + console.print(f"[dim]{cmd}[/]", highlight=False) + os.system(cmd) + + +@app.command() +def alerts() -> None: + """List open alerts.""" + for repo in app.repos: + cmd = "GH_PAGER= gh " + cmd += f"api /repos/{repo}/dependabot/alerts" + cmd += " --jq='.[] | select(.state!=\"fixed\") | .html_url'" + result = run( + cmd, + text=True, + shell=True, + capture_output=True, + check=False, + ) + if result.returncode: + console.print( + f"[dim]{cmd}[/dim] failed with {result.returncode}\n" + f"{result.stdout}\n\n{result.stderr}" + ) + else: + if result.stdout: + console.print(result.stdout) + if result.stderr: + console.print(result.stderr) + + if __name__ == "__main__": # execute only if run as a script app()