"""Configuration system for depcheck.""" import fnmatch import os from dataclasses import dataclass, field from pathlib import Path from typing import Optional import yaml from depcheck.models import Severity @dataclass class Config: """Configuration for depcheck.""" ignore_patterns: list[str] = field(default_factory=list) ignore_packages: list[str] = field(default_factory=list) fail_level: Severity = Severity.MEDIUM output_format: str = "terminal" verbose: bool = False quiet: bool = False include_dev: bool = True package_managers: list[str] = field(default_factory=list) def load_config(config_path: Optional[Path] = None) -> Config: """Load configuration from file.""" config = Config() if config_path is None: config_path = _find_config_file() if config_path and config_path.exists(): try: content = config_path.read_text() data = yaml.safe_load(content) or {} except (yaml.YAMLError, OSError): return config else: return config if "ignore_patterns" in data: config.ignore_patterns = data["ignore_patterns"] if "ignore_packages" in data: config.ignore_packages = data["ignore_packages"] if "fail_level" in data: try: config.fail_level = Severity(data["fail_level"]) except ValueError: pass if "output" in data: output = data["output"] if "format" in output: config.output_format = output["format"] if "verbose" in output: config.verbose = output["verbose"] if "quiet" in output: config.quiet = output["quiet"] if "include_dev" in data: config.include_dev = data["include_dev"] if "package_managers" in data: config.package_managers = data["package_managers"] return config def _find_config_file() -> Optional[Path]: """Find config file in current dir or XDG locations.""" current_dir = Path.cwd() config_path = current_dir / ".depcheck.yaml" if config_path.exists(): return config_path xdg_config = os.environ.get("XDG_CONFIG_HOME", str(Path.home() / ".config")) xdg_config_path = Path(xdg_config) / "depcheck" / ".depcheck.yaml" if xdg_config_path.exists(): return xdg_config_path return None def should_ignore_package(config: Config, package_name: str) -> bool: """Check if a package should be ignored.""" for pattern in config.ignore_packages: if fnmatch.fnmatch(package_name, pattern): return True return False def should_ignore_file(config: Config, file_path: Path) -> bool: """Check if a file should be ignored.""" for pattern in config.ignore_patterns: if pattern in str(file_path): return True return False