- Replace walrus operator (:=) with traditional assignment in config.py - Replace datetime.fromisoformat() with strptime() for Python 3.6 - Replace subprocess capture_output and text params with PIPE and universal_newlines - All tests now pass on Python 3.6.9 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
96 lines
2.6 KiB
Python
96 lines
2.6 KiB
Python
"""
|
|
Configuration management for tddai.
|
|
"""
|
|
|
|
import os
|
|
from pathlib import Path
|
|
from typing import Optional
|
|
from dataclasses import dataclass
|
|
|
|
from .exceptions import ConfigurationError
|
|
|
|
|
|
@dataclass
|
|
class TddaiConfig:
|
|
"""Configuration settings for tddai."""
|
|
|
|
# Workspace settings
|
|
workspace_dir: Path = Path(".markitect_workspace")
|
|
current_issue_file: str = "current_issue.json"
|
|
|
|
# Git repository settings
|
|
gitea_url: str = "http://92.205.130.254:32166"
|
|
repo_owner: str = "coulomb"
|
|
repo_name: str = "markitect_project"
|
|
|
|
# Test settings
|
|
tests_dir: Path = Path("tests")
|
|
test_file_pattern: str = "test_issue_{issue_num}_{scenario}.py"
|
|
|
|
# AI settings
|
|
claude_code_command: str = "claude"
|
|
|
|
@property
|
|
def issues_api_url(self) -> str:
|
|
"""Get the full issues API URL."""
|
|
return f"{self.gitea_url}/api/v1/repos/{self.repo_owner}/{self.repo_name}/issues"
|
|
|
|
@property
|
|
def current_issue_path(self) -> Path:
|
|
"""Get the path to current issue file."""
|
|
return self.workspace_dir / self.current_issue_file
|
|
|
|
@classmethod
|
|
def from_environment(cls) -> "TddaiConfig":
|
|
"""Create config from environment variables."""
|
|
config = cls()
|
|
|
|
# Override with environment variables if present
|
|
gitea_url = os.getenv("TDDAI_GITEA_URL")
|
|
if gitea_url:
|
|
config.gitea_url = gitea_url
|
|
|
|
repo_owner = os.getenv("TDDAI_REPO_OWNER")
|
|
if repo_owner:
|
|
config.repo_owner = repo_owner
|
|
|
|
repo_name = os.getenv("TDDAI_REPO_NAME")
|
|
if repo_name:
|
|
config.repo_name = repo_name
|
|
|
|
workspace_dir = os.getenv("TDDAI_WORKSPACE_DIR")
|
|
if workspace_dir:
|
|
config.workspace_dir = Path(workspace_dir)
|
|
|
|
return config
|
|
|
|
def validate(self) -> None:
|
|
"""Validate configuration settings."""
|
|
if not self.gitea_url:
|
|
raise ConfigurationError("gitea_url cannot be empty")
|
|
|
|
if not self.repo_owner:
|
|
raise ConfigurationError("repo_owner cannot be empty")
|
|
|
|
if not self.repo_name:
|
|
raise ConfigurationError("repo_name cannot be empty")
|
|
|
|
|
|
# Global config instance
|
|
_config: Optional[TddaiConfig] = None
|
|
|
|
|
|
def get_config() -> TddaiConfig:
|
|
"""Get the global configuration instance."""
|
|
global _config
|
|
if _config is None:
|
|
_config = TddaiConfig.from_environment()
|
|
_config.validate()
|
|
return _config
|
|
|
|
|
|
def set_config(config: TddaiConfig) -> None:
|
|
"""Set the global configuration instance."""
|
|
global _config
|
|
config.validate()
|
|
_config = config |