feat: Implement unified configuration management system

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>
This commit is contained in:
2025-09-26 17:45:56 +02:00
parent 82f6ef794e
commit a7a7960ef6
7 changed files with 1090 additions and 4 deletions

View File

@@ -1,6 +1,9 @@
"""
Configuration management for tddai.
DEPRECATED: This module is kept for backward compatibility only.
New code should use the unified configuration system in the `config` module.
The tddai framework is project-agnostic and can be configured per project
via environment variables:
@@ -25,9 +28,19 @@ from dataclasses import dataclass
from .exceptions import ConfigurationError
# Import unified configuration system
try:
from config import get_tddai_config as _get_unified_tddai_config
_UNIFIED_CONFIG_AVAILABLE = True
except ImportError:
_UNIFIED_CONFIG_AVAILABLE = False
def load_dotenv_file(env_file: Path) -> None:
"""Load environment variables from a .env file."""
"""Load environment variables from a .env file.
DEPRECATED: Use config.loaders.load_env_file() instead.
"""
if not env_file.exists():
return
@@ -41,7 +54,10 @@ def load_dotenv_file(env_file: Path) -> None:
@dataclass
class TddaiConfig:
"""Configuration settings for tddai."""
"""Configuration settings for tddai.
DEPRECATED: Use config.TddaiConfigCompat instead.
"""
# Workspace settings
workspace_dir: Path = Path(".tddai_workspace")
@@ -114,16 +130,42 @@ _config: Optional[TddaiConfig] = None
def get_config() -> TddaiConfig:
"""Get the global configuration instance."""
"""Get the global configuration instance.
DEPRECATED: Use config.get_tddai_config() instead for new code.
This function maintains backward compatibility.
"""
global _config
if _config is None:
if _UNIFIED_CONFIG_AVAILABLE:
# Use unified configuration system if available
try:
unified_config = _get_unified_tddai_config()
_config = TddaiConfig(
workspace_dir=unified_config.workspace_dir,
gitea_url=unified_config.gitea_url,
repo_owner=unified_config.repo_owner,
repo_name=unified_config.repo_name,
tests_dir=unified_config.tests_dir,
test_file_pattern=unified_config.test_file_pattern,
claude_code_command=unified_config.claude_code_command
)
return _config
except Exception:
# Fall back to legacy behavior if unified config fails
pass
# Legacy fallback
_config = TddaiConfig.from_environment()
_config.validate()
return _config
def set_config(config: TddaiConfig) -> None:
"""Set the global configuration instance."""
"""Set the global configuration instance.
DEPRECATED: Use the unified configuration system instead.
"""
global _config
config.validate()
_config = config