Files
markitect-main/cli/issue_cli.py
tegwick 960a7c4850 feat: Complete CLI consolidation - fix redundancy and missing interfaces
🎯 MAJOR CLI ARCHITECTURE CONSOLIDATION:

 Added Missing CLI Entry Points:
• tddai = "tddai_cli:main" - TDD workflow management
• issue = "cli.issue_cli:main" - Pure issue management
• All three CLIs now properly installed: markitect, tddai, issue

🧹 Eliminated Functionality Redundancy:
• Removed issue commands from markitect/cli.py (clean separation)
• MarkiTect now focuses purely on document processing
• TDD workflow in tddai CLI, issue management in issue CLI

🏗️ Clean Architecture Implementation:
• Created cli/issue_cli.py - Dedicated pure issue management
• Enhanced cli/commands/export.py with export_issues_csv/json
• Updated cli/core.py with proper export method delegation
• Fixed pyproject.toml to include all required packages

🧪 Comprehensive Testing:
• Added tests/test_cli_consolidation.py - Prevents CLI regression
• Tests ensure all CLIs are installed and functional
• Tests verify no functionality duplication
• Regression protection against missing CLI commands

📋 Clear Separation of Concerns:
• markitect CLI - Document processing, templates, performance
• tddai CLI - TDD workflow, workspace management, coverage
• issue CLI - Pure issue operations, project management, export

🔧 Package Configuration:
• Updated pyproject.toml to include cli*, tddai*, services*, etc.
• Added py-modules for tddai_cli standalone module
• Fixed import paths and dependencies

This consolidation resolves the major redundancy identified in issues
functionality and ensures proper CLI interfaces are available and tested.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-02 23:04:57 +02:00

180 lines
6.5 KiB
Python

#!/usr/bin/env python3
"""
Pure Issue Management CLI
Dedicated CLI interface for issue management operations, providing clean
separation from document processing and TDD workflow functionality.
This CLI focuses exclusively on issue operations:
- Listing and viewing issues
- Creating and closing issues
- Project management (milestones, priorities, states)
- Issue metadata and bulk operations
Architecture: Uses the unified cli/ framework for consistent command structure.
"""
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.core import CLIFramework
from tddai import TddaiError
def create_parser() -> argparse.ArgumentParser:
"""Create argument parser for issue CLI."""
parser = argparse.ArgumentParser(
prog='issue',
description='Pure Issue Management CLI - Dedicated interface for issue operations',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
issue list # List all issues
issue list --open # List only open issues
issue show 42 # Show issue details
issue create "Bug fix" "Description" # Create new issue
issue close 42 "Fixed the problem" # Close issue with comment
issue assign 42 milestone-1 # Assign to milestone
issue priority 42 high # Set priority
issue state 42 "In Progress" # Set project state
Focus Areas:
- Issue browsing and management
- Project organization (milestones, priorities)
- Bulk operations and metadata management
- Integration with various issue tracking backends
Related Commands:
tddai - TDD workflow management with issue context
markitect - Document processing and template operations
"""
)
subparsers = parser.add_subparsers(dest='command', help='Available issue commands')
# List issues
list_parser = subparsers.add_parser('list', help='List issues')
list_parser.add_argument('--open', action='store_true', help='Show only open issues')
list_parser.add_argument('--format', choices=['table', 'json', 'csv'], default='table', help='Output format')
# Show issue details
show_parser = subparsers.add_parser('show', help='Show issue details')
show_parser.add_argument('issue_number', type=int, help='Issue number')
# Create issue
create_parser = subparsers.add_parser('create', help='Create new issue')
create_parser.add_argument('title', help='Issue title')
create_parser.add_argument('description', help='Issue description')
create_parser.add_argument('--type', choices=['bug', 'enhancement', 'feature'], default='enhancement', help='Issue type')
create_parser.add_argument('--priority', choices=['low', 'medium', 'high', 'critical'], help='Issue priority')
# Close issue
close_parser = subparsers.add_parser('close', help='Close issue')
close_parser.add_argument('issue_number', type=int, help='Issue number')
close_parser.add_argument('comment', nargs='?', default='', help='Closing comment')
# Assign to milestone
assign_parser = subparsers.add_parser('assign', help='Assign issue to milestone')
assign_parser.add_argument('issue_number', type=int, help='Issue number')
assign_parser.add_argument('milestone_id', type=int, help='Milestone ID')
# Set priority
priority_parser = subparsers.add_parser('priority', help='Set issue priority')
priority_parser.add_argument('issue_number', type=int, help='Issue number')
priority_parser.add_argument('priority', choices=['low', 'medium', 'high', 'critical'], help='Priority level')
# Set state
state_parser = subparsers.add_parser('state', help='Set issue project state')
state_parser.add_argument('issue_number', type=int, help='Issue number')
state_parser.add_argument('state', help='Project state')
# Export/bulk operations
export_parser = subparsers.add_parser('export', help='Export issues in various formats')
export_parser.add_argument('--format', choices=['csv', 'json', 'tsv'], default='csv', help='Export format')
export_parser.add_argument('--output', help='Output file (default: stdout)')
export_parser.add_argument('--filter', choices=['open', 'closed', 'all'], default='all', help='Filter issues')
# Milestones
milestone_parser = subparsers.add_parser('milestones', help='List milestones')
return parser
def main():
"""Main entry point for issue CLI."""
parser = create_parser()
args = parser.parse_args()
if not args.command:
parser.print_help()
sys.exit(1)
# Initialize CLI framework
try:
cli = CLIFramework()
except Exception as e:
print(f"Error initializing CLI framework: {e}")
sys.exit(1)
# Execute commands
try:
if args.command == 'list':
if args.open:
cli.list_open_issues()
else:
cli.list_issues()
elif args.command == 'show':
cli.show_issue(args.issue_number)
elif args.command == 'create':
kwargs = {}
if hasattr(args, 'priority') and args.priority:
kwargs['priority'] = args.priority
cli.create_issue(args.title, args.description, args.type, **kwargs)
elif args.command == 'close':
cli.close_issue(args.issue_number, args.comment)
elif args.command == 'assign':
cli.assign_issue_to_milestone(args.issue_number, args.milestone_id)
elif args.command == 'priority':
cli.set_issue_priority(args.issue_number, args.priority)
elif args.command == 'state':
cli.move_issue_to_state(args.issue_number, args.state)
elif args.command == 'export':
# Export functionality
if args.format == 'csv':
cli.export_issues_csv(args.output)
elif args.format == 'json':
cli.export_issues_json(args.output)
elif args.format == 'tsv':
cli.export_issue_index(args.output)
elif args.command == 'milestones':
cli.list_milestones()
else:
print(f"Unknown command: {args.command}")
parser.print_help()
sys.exit(1)
except TddaiError as e:
print(f"Issue CLI Error: {e}")
sys.exit(1)
except Exception as e:
print(f"Unexpected error: {e}")
sys.exit(1)
if __name__ == '__main__':
main()