Consolidates scattered configuration patterns across TDDAI, Gitea, and MarkiTect into a unified, maintainable system addressing issue #22. Key improvements: - Created centralized config/ module with base classes and utilities - Eliminated duplicate load_dotenv_file() functions - Standardized environment variables with MARKITECT_ prefix - Implemented comprehensive validation with helpful error messages - Maintained full backward compatibility with existing TDDAI config Architecture: - BaseConfig: Abstract base with common functionality - MarkitectConfig: Main configuration class with legacy support - Compatibility layer: TddaiConfigCompat and GiteaConfigCompat wrappers - Unified error handling: ConfigurationError hierarchy All existing tests pass without modification, ensuring seamless transition. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
169 lines
5.3 KiB
Python
169 lines
5.3 KiB
Python
"""
|
|
Backward compatibility layer for existing configuration systems.
|
|
|
|
Provides compatibility shims that allow existing TDDAI and Gitea
|
|
configuration code to work with the unified configuration system.
|
|
"""
|
|
|
|
from dataclasses import dataclass
|
|
from pathlib import Path
|
|
from typing import Dict, Any, Optional
|
|
|
|
from .manager import get_unified_config
|
|
from .exceptions import ConfigurationError
|
|
|
|
|
|
@dataclass
|
|
class TddaiConfigCompat:
|
|
"""TDDAI configuration compatibility layer.
|
|
|
|
Provides the same interface as the original TddaiConfig but
|
|
backed by the unified configuration system.
|
|
"""
|
|
|
|
workspace_dir: Path
|
|
current_issue_file: str = "current_issue.json"
|
|
gitea_url: str = ""
|
|
repo_owner: str = ""
|
|
repo_name: str = ""
|
|
tests_dir: Path = Path("tests")
|
|
test_file_pattern: str = "test_issue_{issue_num}_{scenario}.py"
|
|
claude_code_command: str = "claude"
|
|
|
|
def __init__(self, **kwargs):
|
|
"""Initialize from unified configuration."""
|
|
unified = get_unified_config()
|
|
|
|
# Map unified config to TDDAI format
|
|
self.workspace_dir = unified.workspace_dir
|
|
self.gitea_url = unified.gitea_url
|
|
self.repo_owner = unified.repo_owner
|
|
self.repo_name = unified.repo_name
|
|
self.tests_dir = unified.tests_dir
|
|
self.test_file_pattern = unified.test_file_pattern
|
|
self.claude_code_command = unified.claude_code_command
|
|
|
|
# Apply any explicit overrides
|
|
for key, value in kwargs.items():
|
|
if hasattr(self, key):
|
|
setattr(self, key, value)
|
|
|
|
def validate(self) -> None:
|
|
"""Validate configuration (for compatibility)."""
|
|
if not self.gitea_url or not self.gitea_url.strip():
|
|
raise ConfigurationError("gitea_url cannot be empty")
|
|
|
|
if not self.repo_owner or not self.repo_owner.strip():
|
|
raise ConfigurationError("repo_owner cannot be empty")
|
|
|
|
if not self.repo_name or not self.repo_name.strip():
|
|
raise ConfigurationError("repo_name cannot be empty")
|
|
|
|
@property
|
|
def issues_api_url(self) -> str:
|
|
"""Get issues API URL (for compatibility)."""
|
|
return f"{self.gitea_url}/api/v1/repos/{self.repo_owner}/{self.repo_name}/issues"
|
|
|
|
@property
|
|
def issues_base_url(self) -> str:
|
|
"""Get issues base URL (for compatibility)."""
|
|
return f"{self.gitea_url}/{self.repo_owner}/{self.repo_name}/issues"
|
|
|
|
|
|
@dataclass
|
|
class GiteaConfigCompat:
|
|
"""Gitea configuration compatibility layer.
|
|
|
|
Provides the same interface as the original GiteaConfig but
|
|
backed by the unified configuration system.
|
|
"""
|
|
|
|
base_url: str
|
|
repo_owner: str
|
|
repo_name: str
|
|
auth_token: str = ""
|
|
api_version: str = "v1"
|
|
|
|
def __init__(self, **kwargs):
|
|
"""Initialize from unified configuration."""
|
|
unified = get_unified_config()
|
|
|
|
# Map unified config to Gitea format
|
|
self.base_url = unified.gitea_url
|
|
self.repo_owner = unified.repo_owner
|
|
self.repo_name = unified.repo_name
|
|
self.auth_token = unified.api_token
|
|
|
|
# Apply any explicit overrides
|
|
for key, value in kwargs.items():
|
|
if hasattr(self, key):
|
|
setattr(self, key, value)
|
|
|
|
@classmethod
|
|
def from_tddai_config(cls, tddai_config) -> 'GiteaConfigCompat':
|
|
"""Create from TDDAI config (for compatibility)."""
|
|
return cls(
|
|
base_url=tddai_config.gitea_url,
|
|
repo_owner=tddai_config.repo_owner,
|
|
repo_name=tddai_config.repo_name
|
|
)
|
|
|
|
def validate(self) -> None:
|
|
"""Validate configuration (for compatibility)."""
|
|
if not self.base_url or not self.base_url.strip():
|
|
raise ConfigurationError("base_url cannot be empty")
|
|
|
|
if not self.repo_owner or not self.repo_owner.strip():
|
|
raise ConfigurationError("repo_owner cannot be empty")
|
|
|
|
if not self.repo_name or not self.repo_name.strip():
|
|
raise ConfigurationError("repo_name cannot be empty")
|
|
|
|
# URL validation
|
|
if not (self.base_url.startswith('http://') or self.base_url.startswith('https://')):
|
|
raise ConfigurationError("base_url must start with http:// or https://")
|
|
|
|
@property
|
|
def api_base_url(self) -> str:
|
|
"""Get API base URL."""
|
|
return f"{self.base_url}/api/{self.api_version}"
|
|
|
|
@property
|
|
def repo_api_url(self) -> str:
|
|
"""Get repository API URL."""
|
|
return f"{self.api_base_url}/repos/{self.repo_owner}/{self.repo_name}"
|
|
|
|
@property
|
|
def issues_api_url(self) -> str:
|
|
"""Get issues API URL."""
|
|
return f"{self.repo_api_url}/issues"
|
|
|
|
|
|
def get_tddai_config(**kwargs) -> TddaiConfigCompat:
|
|
"""Get TDDAI-compatible configuration.
|
|
|
|
This function can be used as a drop-in replacement for the original
|
|
get_config() function in tddai/config.py.
|
|
|
|
Args:
|
|
**kwargs: Override values for configuration fields
|
|
|
|
Returns:
|
|
TDDAI-compatible configuration object
|
|
"""
|
|
return TddaiConfigCompat(**kwargs)
|
|
|
|
|
|
def get_gitea_config(**kwargs) -> GiteaConfigCompat:
|
|
"""Get Gitea-compatible configuration.
|
|
|
|
This function can be used as a drop-in replacement for the original
|
|
GiteaConfig creation.
|
|
|
|
Args:
|
|
**kwargs: Override values for configuration fields
|
|
|
|
Returns:
|
|
Gitea-compatible configuration object
|
|
"""
|
|
return GiteaConfigCompat(**kwargs) |