From 9cf33f1216ab7579346b15abe0c44cf2b650af04 Mon Sep 17 00:00:00 2001 From: arthurcai Date: Fri, 19 Sep 2025 19:42:36 +0800 Subject: [PATCH] feat: add app command for closing issues --- joint_teapot/app.py | 51 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/joint_teapot/app.py b/joint_teapot/app.py index e83b014..139e709 100644 --- a/joint_teapot/app.py +++ b/joint_teapot/app.py @@ -167,6 +167,57 @@ def close_all_issues() -> None: tea.pot.gitea.close_all_issues() +@app.command( + "close-issues", + help="close specific issues in a repository: joint-teapot close-issues REPO_NAME ISSUE_NUMBER [ISSUE_NUMBER ...]", +) +def close_issues( + repo_name: str, + issue_numbers: List[int] = Argument(..., help="One or more issue numbers to close"), + dry_run: bool = Option(False, "--dry-run/--no-dry-run", help="Enable dry run (no changes will be made)"), +) -> None: + tea.pot.gitea.close_issues(repo_name, issue_numbers, dry_run) + + +@app.command( + "label-issues", + help="add a label to specific issues in a repository: joint-teapot label-issues TAG_NAME REPO_NAME ISSUE_NUMBER [ISSUE_NUMBER ...]", +) +def label_issues( + label_name: str, + repo_name: str, + issue_numbers: List[int] = Argument(..., help="One or more issue numbers to label"), + issue_color: Optional[str] = Option(None, "--color", help="Color for newly created label (hex without # or with #)"), + dry_run: bool = Option(False, "--dry-run/--no-dry-run", help="Dry run: show what would be labeled without making changes"), +) -> None: + if dry_run: + logger.info(f"Dry run: would add label '{label_name}' to {repo_name} issues: {issue_numbers}") + return + tea.pot.gitea.label_issues(repo_name, label_name, issue_numbers, color=issue_color) + + +@app.command( + "delete-label", + help="remove a label from specific issues or delete the repository label: joint-teapot delete-label TAG_NAME REPO_NAME [ISSUE_NUMBER ...]", +) +def delete_label( + label_name: str, + repo_name: str, + issue_numbers: List[int] = Argument(None, help="Zero or more issue numbers to remove the label from (if empty and --repo is set, delete repo label)"), + repo: bool = Option(False, "--repo", help="Delete the repo-level label when set and issue_numbers is empty"), + dry_run: bool = Option(False, "--dry-run/--no-dry-run", help="Dry run: show what would be removed without making changes"), +) -> None: + if dry_run: + if issue_numbers: + logger.info(f"Dry run: would remove label '{label_name}' from {repo_name} issues: {issue_numbers}") + elif repo: + logger.info(f"Dry run: would delete repo label '{label_name}' from {repo_name}") + else: + logger.info("Dry run: no action specified (provide issue numbers or --repo to delete repo label)") + return + tea.pot.gitea.delete_label(repo_name, label_name, issue_numbers if issue_numbers else None, delete_repo_label=repo) + + @app.command( "archive-repos", help="archive repos in gitea organization according to regex" )