Files
markitect-main/tddai/issue_fetcher.py
tegwick fd8f792f08 refactor: Factor out Gitea interfacing into clean facade pattern
- Create new gitea/ package with clean API facade
- Establish proper separation of concerns: tddai uses gitea, not vice versa
- Replace duplicate curl+subprocess patterns with unified HTTP client
- Add rich domain models with properties (issue.priority, issue.status)
- Maintain full backwards compatibility in tddai modules
- Reduce code complexity: -373 lines, +151 lines (net -222 lines)
- Improve testability and maintainability through clean interfaces

Architecture:
- gitea.client.GiteaClient - main facade with sub-clients
- gitea.api_client - high-level API with model conversion
- gitea.http_client - low-level HTTP operations
- gitea.models - rich domain objects (Issue, Milestone, Label)
- gitea.config - gitea-specific configuration
- gitea.exceptions - clean exception hierarchy

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-26 14:25:40 +02:00

64 lines
2.3 KiB
Python

"""
Issue fetching using the Gitea facade.
This module now acts as an adapter to the new gitea package,
maintaining backwards compatibility while using the cleaner API.
"""
from typing import List, Dict, Any
from gitea import GiteaClient, Issue as GiteaIssue, GiteaConfig
from .config import get_config
from .exceptions import IssueError
# Re-export Issue for backwards compatibility
Issue = GiteaIssue
class IssueFetcher:
"""Fetches issues using the Gitea facade."""
def __init__(self, config=None):
self.config = config or get_config()
# Create Gitea client from tddai config
gitea_config = GiteaConfig.from_tddai_config(self.config)
self.gitea_client = GiteaClient(gitea_config)
def fetch_issue(self, issue_number: int) -> Issue:
"""Fetch a specific issue by number."""
try:
return self.gitea_client.issues.get(issue_number)
except Exception as e:
# Convert gitea exceptions to IssueError for backwards compatibility
raise IssueError(f"Failed to fetch issue #{issue_number}: {e}")
def fetch_issues(self, state: str = "all") -> List[Issue]:
"""Fetch all issues with optional state filter."""
try:
return self.gitea_client.issues.list(state=state)
except Exception as e:
# Convert gitea exceptions to IssueError for backwards compatibility
raise IssueError(f"Failed to fetch issues: {e}")
def fetch_open_issues(self) -> List[Issue]:
"""Fetch only open issues."""
try:
return self.gitea_client.issues.list_open()
except Exception as e:
raise IssueError(f"Failed to fetch open issues: {e}")
def get_issue_data_dict(self, issue_number: int) -> Dict[str, Any]:
"""Get issue data as dictionary for workspace creation."""
issue = self.fetch_issue(issue_number)
return {
'number': issue.number,
'title': issue.title,
'body': issue.body,
'state': issue.state,
'created_at': issue.created_at.isoformat(),
'updated_at': issue.updated_at.isoformat(),
'html_url': issue.html_url,
'assignee': {'login': issue.assignee.login} if issue.assignee else None,
'labels': [{'name': label.name} for label in issue.labels]
}