from __future__ import annotations import os from pathlib import Path from typing import Any import yaml class Config: def __init__(self, config_path: Path | None = None): self.config_path = config_path or self._find_config() self._config: dict[str, Any] = {} self._load_config() def _find_config(self) -> Path | None: possible_paths = [ Path(".depauditrc"), Path("depaudit.config.yaml"), Path(os.environ.get("DEPAUDIT_CONFIG_FILE", "")), Path.home() / ".depauditrc", ] for path in possible_paths: if path.exists() and path.stat().st_size > 0: return path return None def _load_config(self) -> None: if self.config_path and self.config_path.exists(): with open(self.config_path, "r") as f: self._config = yaml.safe_load(f) or {} else: self._config = {} def get(self, key: str, default: Any = None) -> Any: keys = key.split(".") value = 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 @property def output_format(self) -> str: return self.get("output.format", "table") @property def use_color(self) -> bool: color = self.get("output.color", True) if color is None: return True return color @property def verbosity(self) -> str: return self.get("output.verbosity", "info") @property def vulnerabilities_enabled(self) -> bool: return self.get("vulnerabilities.enabled", True) @property def severity_filter(self) -> str: return self.get("vulnerabilities.severity_filter", "all") @property def outdated_enabled(self) -> bool: return self.get("outdated.enabled", True) @property def licenses_enabled(self) -> bool: return self.get("licenses.enabled", True) @property def license_allowlist(self) -> list[str]: return self.get("licenses.allowlist", [ "MIT", "Apache-2.0", "BSD-2-Clause", "BSD-3-Clause", "ISC", "MPL-2.0" ]) @property def license_blocklist(self) -> list[str]: return self.get("licenses.blocklist", [ "GPL-1.0", "GPL-2.0", "GPL-3.0", "AGPL-1.0", "AGPL-3.0" ]) @property def unused_enabled(self) -> bool: return self.get("unused.enabled", True) @property def cache_enabled(self) -> bool: return self.get("cache.enabled", True) @property def cache_directory(self) -> Path: cache_dir = self.get("cache.directory", "~/.cache/depaudit") return Path(cache_dir).expanduser() @property def cache_ttl(self) -> int: return self.get("cache.ttl", 604800) @property def network_timeout(self) -> int: return self.get("network.timeout", 30) @property def cicd_fail_on(self) -> list[str]: return self.get("cicd.fail_on", ["critical", "high"]) def reload(self) -> None: self._load_config() config = Config()