131 lines
4.1 KiB
Python
131 lines
4.1 KiB
Python
"""Configuration management for ScaffoldForge."""
|
|
|
|
import os
|
|
from pathlib import Path
|
|
from typing import Any, Optional
|
|
|
|
import yaml
|
|
|
|
|
|
class Config:
|
|
"""Configuration management class."""
|
|
|
|
_instance: Optional["Config"] = None
|
|
_config: dict[str, Any] = {}
|
|
|
|
def __new__(cls) -> "Config":
|
|
if cls._instance is None:
|
|
cls._instance = super().__new__(cls)
|
|
return cls._instance
|
|
|
|
def __init__(self):
|
|
if not self._config:
|
|
self._load_default_config()
|
|
|
|
def _load_default_config(self) -> None:
|
|
"""Load default configuration."""
|
|
self._config = {
|
|
"languages": {
|
|
"python": {
|
|
"name": "Python",
|
|
"extension": ".py",
|
|
"package_manager": "pip",
|
|
"config_files": ["pyproject.toml", "requirements.txt"],
|
|
"templates": ["main.py", "utils.py", "models.py"],
|
|
},
|
|
"javascript": {
|
|
"name": "JavaScript",
|
|
"extension": ".js",
|
|
"package_manager": "npm",
|
|
"config_files": ["package.json"],
|
|
"templates": ["index.js", "utils.js"],
|
|
},
|
|
"go": {
|
|
"name": "Go",
|
|
"extension": ".go",
|
|
"package_manager": "go",
|
|
"config_files": ["go.mod"],
|
|
"templates": ["main.go", "utils.go"],
|
|
},
|
|
"rust": {
|
|
"name": "Rust",
|
|
"extension": ".rs",
|
|
"package_manager": "cargo",
|
|
"config_files": ["Cargo.toml"],
|
|
"templates": ["main.rs", "lib.rs"],
|
|
},
|
|
},
|
|
"templates": {
|
|
"builtin_path": str(Path(__file__).parent / "templates"),
|
|
"custom_path": os.environ.get("SCAFFOLD_TEMPLATE_DIR"),
|
|
"cache_enabled": True,
|
|
"cache_ttl": 3600,
|
|
},
|
|
"github": {
|
|
"api_rate_limit_warning": 100,
|
|
"max_retries": 3,
|
|
"retry_delay": 5,
|
|
},
|
|
"output": {
|
|
"default_directory": "./generated",
|
|
"create_gitignore": True,
|
|
"create_readme": True,
|
|
"preserve_permissions": False,
|
|
},
|
|
}
|
|
|
|
def load(self, config_path: str) -> None:
|
|
"""Load configuration from YAML file."""
|
|
path = Path(config_path)
|
|
if path.exists():
|
|
with open(path) as f:
|
|
user_config = yaml.safe_load(f) or {}
|
|
self._config.update(user_config)
|
|
|
|
def get(self, key: str, default: Any | None = None) -> Any:
|
|
"""Get configuration value using dot notation."""
|
|
keys = key.split(".")
|
|
value: Any = self._config
|
|
for k in keys:
|
|
if isinstance(value, dict):
|
|
value = value.get(k)
|
|
else:
|
|
return default
|
|
if value is None:
|
|
return default
|
|
return value
|
|
|
|
def get_github_token(self) -> Optional[str]:
|
|
"""Get GitHub token from environment or config."""
|
|
return os.environ.get("GITHUB_TOKEN")
|
|
|
|
def get_template_dir(self) -> str:
|
|
"""Get template directory path."""
|
|
custom = self.get("templates.custom_path")
|
|
if custom and Path(custom).exists():
|
|
return custom
|
|
return self.get("templates.builtin_path", "")
|
|
|
|
def get_output_dir(self) -> str:
|
|
"""Get default output directory."""
|
|
env_dir = os.environ.get("SCAFFOLD_OUTPUT_DIR")
|
|
if env_dir:
|
|
return env_dir
|
|
return self.get("output.default_directory", "./generated")
|
|
|
|
def get_supported_languages(self) -> list[str]:
|
|
"""Get list of supported programming languages."""
|
|
return list(self.get("languages", {}).keys())
|
|
|
|
|
|
_config = Config()
|
|
|
|
|
|
def load_config(config_path: str) -> None:
|
|
"""Load configuration from file."""
|
|
_config.load(config_path)
|
|
|
|
|
|
def get_config() -> Config:
|
|
"""Get the global configuration instance."""
|
|
return _config |