Files
7000pctAUTO 7853581e1f
Some checks failed
CI / test (3.11) (push) Has been cancelled
CI / test (3.12) (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (3.10) (push) Failing after 16s
CI / build (push) Successful in 25s
Add config module
2026-02-02 17:20:01 +00:00

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",
}