#!/usr/bin/env python3 """ TDDAi Issue Closer A dedicated module for closing issues in the selected issue tracking backend. Provides both programmatic API and CLI functionality for easy issue closure. This module integrates with the existing tddai framework and provides: - Simple programmatic interface for closing issues - Command-line utility for manual issue closure - Integration with existing issue tracking backends - Proper error handling and user feedback """ import sys import argparse from pathlib import Path from typing import Optional # Add project root to path for imports project_root = Path(__file__).parent.parent sys.path.insert(0, str(project_root)) from cli import CLIFramework from services import IssueService from tddai import TddaiError class IssueCloser: """Dedicated class for closing issues with the configured backend.""" def __init__(self): """Initialize the issue closer with CLI framework.""" self.cli = CLIFramework() self.service = IssueService() def close_issue(self, issue_number: int, comment: str = "") -> bool: """ Close an issue with optional comment. Args: issue_number: The issue number to close comment: Optional closing comment Returns: bool: True if issue was closed successfully, False otherwise """ try: self.cli.close_issue(issue_number, comment) return True except TddaiError as e: print(f"Error closing issue #{issue_number}: {e}") return False except Exception as e: print(f"Unexpected error closing issue #{issue_number}: {e}") return False def close_with_completion_message(self, issue_number: int, completed_work: str) -> bool: """ Close an issue with a standardized completion message. Args: issue_number: The issue number to close completed_work: Description of what was completed Returns: bool: True if issue was closed successfully, False otherwise """ completion_comment = f"✅ Completed: {completed_work}" return self.close_issue(issue_number, completion_comment) def close_multiple_issues(self, issue_numbers: list, comment: str = "") -> dict: """ Close multiple issues with the same comment. Args: issue_numbers: List of issue numbers to close comment: Comment to add to all issues Returns: dict: Results with 'successful' and 'failed' lists """ results = {'successful': [], 'failed': []} for issue_num in issue_numbers: if self.close_issue(issue_num, comment): results['successful'].append(issue_num) else: results['failed'].append(issue_num) return results def main(): """Command-line interface for the issue closer.""" parser = argparse.ArgumentParser( description="TDDAi Issue Closer - Close issues in the configured tracking backend", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: python3 issue_closer.py 42 # Close issue #42 python3 issue_closer.py 42 -c "Fixed the bug" # Close with comment python3 issue_closer.py 42 -w "All tests passing" # Close with completion message python3 issue_closer.py 42 43 44 # Close multiple issues python3 issue_closer.py 42 43 -c "Batch closure" # Close multiple with comment Integration with existing tddai CLI: python3 tddai_cli.py close-issue 42 --comment "Done" # Alternative method """ ) parser.add_argument( 'issue_numbers', type=int, nargs='+', help='Issue number(s) to close' ) parser.add_argument( '-c', '--comment', type=str, default='', help='Optional closing comment' ) parser.add_argument( '-w', '--work-completed', type=str, help='Description of completed work (creates standardized completion message)' ) parser.add_argument( '-v', '--verbose', action='store_true', help='Enable verbose output' ) args = parser.parse_args() # Initialize issue closer closer = IssueCloser() # Determine which closing method to use if args.work_completed: comment = f"✅ Completed: {args.work_completed}" else: comment = args.comment # Handle single or multiple issues if len(args.issue_numbers) == 1: issue_num = args.issue_numbers[0] if args.verbose: print(f"Closing issue #{issue_num}...") if comment: print(f"Comment: {comment}") success = closer.close_issue(issue_num, comment) sys.exit(0 if success else 1) else: # Multiple issues if args.verbose: print(f"Closing {len(args.issue_numbers)} issues...") if comment: print(f"Comment: {comment}") results = closer.close_multiple_issues(args.issue_numbers, comment) if results['successful']: print(f"✅ Successfully closed: {results['successful']}") if results['failed']: print(f"❌ Failed to close: {results['failed']}") sys.exit(1) print(f"✅ All {len(args.issue_numbers)} issues closed successfully!") if __name__ == '__main__': main()