141 lines
4.7 KiB
Python
141 lines
4.7 KiB
Python
"""Configuration module for i18n-guardian."""
|
|
|
|
from pathlib import Path
|
|
from typing import Any, Dict, List, Optional
|
|
|
|
import yaml
|
|
|
|
|
|
class Config:
|
|
"""Configuration for i18n-guardian."""
|
|
|
|
def __init__(
|
|
self,
|
|
path: Optional[str] = None,
|
|
i18n_library: Optional[str] = None,
|
|
i18n_functions: Optional[List[str]] = None,
|
|
exclude_patterns: Optional[List[str]] = None,
|
|
include_patterns: Optional[List[str]] = None,
|
|
min_string_length: int = 3,
|
|
key_style: str = "snake_case",
|
|
key_prefix: Optional[str] = None,
|
|
output_format: str = "text",
|
|
fail_level: str = "error",
|
|
) -> None:
|
|
self.path = path
|
|
self.i18n_library = i18n_library
|
|
self.i18n_functions = i18n_functions or []
|
|
self.exclude_patterns = exclude_patterns or []
|
|
self.include_patterns = include_patterns or ["**/*.py", "**/*.js", "**/*.ts", "**/*.jsx", "**/*.tsx"]
|
|
self.min_string_length = min_string_length
|
|
self.key_style = key_style
|
|
self.key_prefix = key_prefix
|
|
self.output_format = output_format
|
|
self.fail_level = fail_level
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: Dict[str, Any]) -> "Config":
|
|
"""Create Config from dictionary."""
|
|
return cls(
|
|
path=data.get("path"),
|
|
i18n_library=data.get("i18n_library"),
|
|
i18n_functions=data.get("i18n_functions"),
|
|
exclude_patterns=data.get("exclude_patterns"),
|
|
include_patterns=data.get("include_patterns"),
|
|
min_string_length=data.get("min_string_length", 3),
|
|
key_style=data.get("key_style", "snake_case"),
|
|
key_prefix=data.get("key_prefix"),
|
|
output_format=data.get("output_format", "text"),
|
|
fail_level=data.get("fail_level", "error"),
|
|
)
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""Convert Config to dictionary."""
|
|
return {
|
|
"path": self.path,
|
|
"i18n_library": self.i18n_library,
|
|
"i18n_functions": self.i18n_functions,
|
|
"exclude_patterns": self.exclude_patterns,
|
|
"include_patterns": self.include_patterns,
|
|
"min_string_length": self.min_string_length,
|
|
"key_style": self.key_style,
|
|
"key_prefix": self.key_prefix,
|
|
"output_format": self.output_format,
|
|
"fail_level": self.fail_level,
|
|
}
|
|
|
|
|
|
class ConfigLoader:
|
|
"""Loader for i18n-guardian configuration."""
|
|
|
|
DEFAULT_CONFIG_NAME = ".i18n-guardian.yaml"
|
|
|
|
def __init__(self) -> None:
|
|
self._config: Optional[Config] = None
|
|
|
|
def load(
|
|
self,
|
|
config_path: Optional[str],
|
|
scan_path: str,
|
|
) -> Config:
|
|
"""Load configuration from file or use defaults."""
|
|
config_data: Dict[str, Any] = {}
|
|
|
|
if config_path:
|
|
config_file = Path(config_path)
|
|
else:
|
|
config_file = Path(scan_path) / self.DEFAULT_CONFIG_NAME
|
|
if not config_file.exists():
|
|
config_file = Path.home() / self.DEFAULT_CONFIG_NAME
|
|
|
|
if config_file.exists():
|
|
try:
|
|
with open(config_file, "r", encoding="utf-8") as f:
|
|
config_data = yaml.safe_load(f) or {}
|
|
except yaml.YAMLError as e:
|
|
raise ValueError(f"Invalid YAML in config file: {e}")
|
|
|
|
if "include_patterns" not in config_data:
|
|
config_data["include_patterns"] = ["**/*.py", "**/*.js", "**/*.ts", "**/*.jsx", "**/*.tsx"]
|
|
if "exclude_patterns" not in config_data:
|
|
config_data["exclude_patterns"] = ["**/node_modules/**", "**/.git/**", "**/venv/**", "**/__pycache__/**"]
|
|
|
|
config_data["path"] = scan_path
|
|
|
|
self._config = Config.from_dict(config_data)
|
|
return self._config
|
|
|
|
def save(self, config: Config, output_path: str) -> None:
|
|
"""Save configuration to file."""
|
|
config_file = Path(output_path)
|
|
with open(config_file, "w", encoding="utf-8") as f:
|
|
yaml.dump(config.to_dict(), f, default_flow_style=False, indent=2)
|
|
|
|
|
|
def generate_default_config() -> Dict[str, Any]:
|
|
"""Generate default configuration."""
|
|
return {
|
|
"i18n_library": None,
|
|
"i18n_functions": [],
|
|
"exclude_patterns": [
|
|
"**/node_modules/**",
|
|
"**/.git/**",
|
|
"**/venv/**",
|
|
"**/__pycache__/**",
|
|
"**/dist/**",
|
|
"**/build/**",
|
|
],
|
|
"include_patterns": [
|
|
"**/*.py",
|
|
"**/*.js",
|
|
"**/*.ts",
|
|
"**/*.jsx",
|
|
"**/*.tsx",
|
|
],
|
|
"min_string_length": 3,
|
|
"key_style": "snake_case",
|
|
"key_prefix": None,
|
|
"output_format": "text",
|
|
"fail_level": "error",
|
|
}
|