Files
markitect-main/tddai/issue_closer.py
tegwick bf84f206fe feat: Complete Issue #79 - Provide tddai issue_closer.py
Add dedicated issue closing functionality for easier issue management:

📄 New Module: tddai/issue_closer.py
• Dedicated IssueCloser class with programmatic API
• Command-line interface for manual and batch issue closure
• Enhanced functionality beyond existing tddai_cli.py close-issue
• Support for standardized completion messages
• Batch closure capability for multiple issues

🔧 Makefile Integration:
• close-issue-enhanced - Enhanced single issue closure with work completion
• close-issues-batch - Batch closure for multiple issues
• Proper help documentation and .PHONY declarations

 Key Features:
• Simple programmatic interface: IssueCloser().close_issue(42, "comment")
• CLI with multiple closure modes: comment, work-completed, batch
• Integration with existing tddai framework and issue tracking backends
• Comprehensive error handling and user feedback
• Verbose mode for detailed operation tracking

📋 Usage Examples:
• python3 tddai/issue_closer.py 42 -w "All tests passing"
• python3 tddai/issue_closer.py 42 43 44 -c "Batch closure"
• make close-issue-enhanced NUM=42 WORK="Implementation complete"
• make close-issues-batch NUMS="42 43 44" COMMENT="Sprint completion"

Provides the missing tddai function to close issues more easily with the selected issue tracking backend.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-02 22:30:53 +02:00

180 lines
5.4 KiB
Python

#!/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()