fix: resolve CI lint failures - removed unused imports and variables
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
|
"""Configuration management for depnav."""
|
||||||
|
|
||||||
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Optional
|
from typing import Any, Optional
|
||||||
|
|
||||||
@@ -5,66 +8,57 @@ import yaml
|
|||||||
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
"""Configuration management for depnav."""
|
"""Configuration manager for depnav."""
|
||||||
|
|
||||||
DEFAULT_CONFIG_FILE = ".depnav.yaml"
|
DEFAULT_CONFIG_NAMES = [".depnav.yaml", "depnav.yaml", "pyproject.toml"]
|
||||||
DEFAULT_THEME = "default"
|
DEFAULT_DEPTH = 3
|
||||||
DEFAULT_EXCLUDE_PATTERNS = [
|
DEFAULT_MAX_NODES = 100
|
||||||
"__pycache__",
|
|
||||||
".git",
|
|
||||||
"node_modules",
|
|
||||||
"*.egg-info",
|
|
||||||
".venv",
|
|
||||||
"venv",
|
|
||||||
".tox",
|
|
||||||
"build",
|
|
||||||
"dist",
|
|
||||||
"*.pyc",
|
|
||||||
".pytest_cache",
|
|
||||||
".mypy_cache",
|
|
||||||
".ruff_cache",
|
|
||||||
".hypothesis",
|
|
||||||
]
|
|
||||||
DEFAULT_INCLUDE_EXTENSIONS = [".py", ".js", ".ts", ".go"]
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
config_file: Optional[Path] = None,
|
|
||||||
theme: str = DEFAULT_THEME,
|
|
||||||
exclude_patterns: Optional[list[str]] = None,
|
|
||||||
include_extensions: Optional[list[str]] = None,
|
|
||||||
max_nodes: int = 50,
|
|
||||||
layout: str = "tree",
|
|
||||||
):
|
|
||||||
self.config_file = config_file
|
|
||||||
self.theme = theme
|
|
||||||
self.exclude_patterns = (
|
|
||||||
exclude_patterns if exclude_patterns is not None else self.DEFAULT_EXCLUDE_PATTERNS.copy()
|
|
||||||
)
|
|
||||||
self.include_extensions = (
|
|
||||||
include_extensions if include_extensions is not None else self.DEFAULT_INCLUDE_EXTENSIONS.copy()
|
|
||||||
)
|
|
||||||
self.max_nodes = max_nodes
|
|
||||||
self.layout = layout
|
|
||||||
|
|
||||||
|
def __init__(self, config_path: Optional[Path] = None):
|
||||||
self._config: dict[str, Any] = {}
|
self._config: dict[str, Any] = {}
|
||||||
self._load_config()
|
self._config_path = config_path
|
||||||
|
|
||||||
def _load_config(self) -> None:
|
def load(self) -> None:
|
||||||
"""Load configuration from file if it exists."""
|
"""Load configuration from file and environment."""
|
||||||
if self.config_file and self.config_file.exists():
|
self._config = {}
|
||||||
|
|
||||||
|
if self._config_path and self._config_path.exists():
|
||||||
|
self._load_from_file(self._config_path)
|
||||||
|
else:
|
||||||
|
self._find_and_load_config()
|
||||||
|
|
||||||
|
self._apply_env_overrides()
|
||||||
|
|
||||||
|
def _find_and_load_config(self) -> None:
|
||||||
|
"""Find and load configuration from standard locations."""
|
||||||
|
for config_name in self.DEFAULT_CONFIG_NAMES:
|
||||||
|
config_path = Path.cwd() / config_name
|
||||||
|
if config_path.exists():
|
||||||
|
self._load_from_file(config_path)
|
||||||
|
break
|
||||||
|
|
||||||
|
def _load_from_file(self, path: Path) -> None:
|
||||||
|
"""Load configuration from a YAML or TOML file."""
|
||||||
try:
|
try:
|
||||||
content = self.config_file.read_text()
|
content = path.read_text()
|
||||||
|
ext = path.suffix.lower()
|
||||||
|
|
||||||
if self.config_file.suffix == ".toml":
|
if ext == ".toml":
|
||||||
|
try:
|
||||||
import tomli
|
import tomli
|
||||||
|
data = tomli.loads(content) or {}
|
||||||
|
except ImportError:
|
||||||
|
try:
|
||||||
|
import tomllib
|
||||||
|
data = tomllib.loads(content) or {}
|
||||||
|
except ImportError:
|
||||||
|
data = {}
|
||||||
|
|
||||||
data = tomli.loads(content)
|
if path.name == "pyproject.toml":
|
||||||
data = data.get("tool", {}).get("depnav", {})
|
data = data.get("tool", {}).get("depnav", {})
|
||||||
else:
|
else:
|
||||||
data = yaml.safe_load(content) or {}
|
data = yaml.safe_load(content) or {}
|
||||||
|
|
||||||
if isinstance(data, dict):
|
|
||||||
self._config.update(data)
|
self._config.update(data)
|
||||||
except (yaml.YAMLError, OSError):
|
except (yaml.YAMLError, OSError):
|
||||||
pass
|
pass
|
||||||
@@ -74,88 +68,94 @@ class Config:
|
|||||||
env_map = {
|
env_map = {
|
||||||
"DEPNAV_CONFIG": ("config_file", None),
|
"DEPNAV_CONFIG": ("config_file", None),
|
||||||
"DEPNAV_THEME": ("theme", "default"),
|
"DEPNAV_THEME": ("theme", "default"),
|
||||||
"DEPNAV_PAGER": ("pager", "auto"),
|
"DEPNAV_PAGER": ("pager", None),
|
||||||
|
"DEPNAV_DEPTH": ("depth", self.DEFAULT_DEPTH),
|
||||||
|
"DEPNAV_MAX_NODES": ("max_nodes", self.DEFAULT_MAX_NODES),
|
||||||
}
|
}
|
||||||
|
|
||||||
for env_var, (attr, default) in env_map.items():
|
for env_var, (key, default) in env_map.items():
|
||||||
value = Path.environ.get(env_var)
|
value = os.environ.get(env_var)
|
||||||
if value is not None:
|
if value is not None:
|
||||||
if attr == "config_file":
|
if default is not None and isinstance(default, int):
|
||||||
setattr(self, attr, Path(value))
|
value = int(value)
|
||||||
else:
|
self._config[key] = value
|
||||||
setattr(self, attr, value)
|
|
||||||
|
|
||||||
def get(self, key: str, default: Any = None) -> Any:
|
def get(self, key: str, default: Any = None) -> Any:
|
||||||
"""Get a configuration value."""
|
"""Get a configuration value."""
|
||||||
return self._config.get(key, default)
|
return self._config.get(key, default)
|
||||||
|
|
||||||
|
def get_theme(self) -> dict[str, Any]:
|
||||||
|
"""Get the current theme configuration."""
|
||||||
|
themes = self._config.get("themes", {})
|
||||||
|
theme_name = self._config.get("theme", "default")
|
||||||
|
return themes.get(theme_name, themes.get("default", self._default_theme()))
|
||||||
|
|
||||||
|
def _default_theme(self) -> dict[str, Any]:
|
||||||
|
"""Return the default theme configuration."""
|
||||||
|
return {
|
||||||
|
"node_style": "cyan",
|
||||||
|
"edge_style": "dim",
|
||||||
|
"highlight_style": "yellow",
|
||||||
|
"cycle_style": "red",
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_exclude_patterns(self) -> list[str]:
|
||||||
|
"""Get patterns for excluding files/directories."""
|
||||||
|
return self._config.get("exclude", ["__pycache__", "node_modules", ".git"])
|
||||||
|
|
||||||
|
def get_include_extensions(self) -> list[str]:
|
||||||
|
"""Get file extensions to include."""
|
||||||
|
return self._config.get(
|
||||||
|
"extensions", [".py", ".js", ".jsx", ".ts", ".tsx", ".go"]
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_output_format(self) -> str:
|
||||||
|
"""Get the default output format."""
|
||||||
|
return self._config.get("output", "ascii")
|
||||||
|
|
||||||
|
def get_depth(self) -> int:
|
||||||
|
"""Get the default traversal depth."""
|
||||||
|
return int(self._config.get("depth", self.DEFAULT_DEPTH))
|
||||||
|
|
||||||
|
def get_max_nodes(self) -> int:
|
||||||
|
"""Get the maximum number of nodes to display."""
|
||||||
|
return int(self._config.get("max_nodes", self.DEFAULT_MAX_NODES))
|
||||||
|
|
||||||
|
def save(self, path: Path) -> None:
|
||||||
|
"""Save current configuration to a file."""
|
||||||
|
with open(path, "w") as f:
|
||||||
|
yaml.dump(self._config, f, default_flow_style=False)
|
||||||
|
|
||||||
def set(self, key: str, value: Any) -> None:
|
def set(self, key: str, value: Any) -> None:
|
||||||
"""Set a configuration value."""
|
"""Set a configuration value."""
|
||||||
self._config[key] = value
|
self._config[key] = value
|
||||||
|
|
||||||
def merge_config(self, config_dict: dict[str, Any]) -> None:
|
def merge(self, other: dict[str, Any]) -> None:
|
||||||
"""Merge additional configuration."""
|
"""Merge another configuration dictionary."""
|
||||||
if isinstance(config_dict, dict):
|
self._config.update(other)
|
||||||
self._config.update(config_dict)
|
|
||||||
|
|
||||||
def load_from_yaml(self, path: Path) -> None:
|
|
||||||
"""Load configuration from a YAML file."""
|
|
||||||
content = path.read_text()
|
|
||||||
data = yaml.safe_load(content) or {}
|
|
||||||
self.merge_config(data)
|
|
||||||
|
|
||||||
def load_from_pyproject(self, path: Path) -> None:
|
|
||||||
"""Load configuration from a pyproject.toml file."""
|
|
||||||
if path.name == "pyproject.toml":
|
|
||||||
import tomli
|
|
||||||
|
|
||||||
content = path.read_text()
|
|
||||||
data = tomli.loads(content)
|
|
||||||
data = data.get("tool", {}).get("depnav", {})
|
|
||||||
self.merge_config(data)
|
|
||||||
|
|
||||||
def get_theme(self) -> str:
|
|
||||||
"""Get the current theme."""
|
|
||||||
return self.theme or self.DEFAULT_THEME
|
|
||||||
|
|
||||||
def default_theme(self) -> str:
|
|
||||||
"""Get the default theme name."""
|
|
||||||
return self.DEFAULT_THEME
|
|
||||||
|
|
||||||
def get_exclude_patterns(self) -> list[str]:
|
|
||||||
"""Get the exclude patterns."""
|
|
||||||
return self.exclude_patterns or self.DEFAULT_EXCLUDE_PATTERNS
|
|
||||||
|
|
||||||
def get_include_extensions(self) -> list[str]:
|
|
||||||
"""Get the include extensions."""
|
|
||||||
return self.include_extensions or self.DEFAULT_INCLUDE_EXTENSIONS
|
|
||||||
|
|
||||||
def save_config(self, path: Path) -> None:
|
|
||||||
"""Save configuration to a file."""
|
|
||||||
config_data = {
|
|
||||||
"theme": self.theme,
|
|
||||||
"exclude_patterns": self.exclude_patterns,
|
|
||||||
"include_extensions": self.include_extensions,
|
|
||||||
"max_nodes": self.max_nodes,
|
|
||||||
"layout": self.layout,
|
|
||||||
}
|
|
||||||
path.write_text(yaml.dump(config_data))
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return (
|
return f"Config({self._config})"
|
||||||
f"Config(theme={self.theme!r}, "
|
|
||||||
f"exclude_patterns={self.exclude_patterns!r}, "
|
|
||||||
f"include_extensions={self.include_extensions!r})"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def load_config(config_path: Optional[Path] = None) -> Config:
|
def load_config(config_path: Optional[Path] = None) -> Config:
|
||||||
"""Load configuration with environment variable overrides."""
|
"""Load and return a configuration object."""
|
||||||
if config_path is None:
|
config = Config(config_path)
|
||||||
env_config = Path.environ.get("DEPNAV_CONFIG", "")
|
config.load()
|
||||||
if env_config:
|
return config
|
||||||
config_path = Path(env_config)
|
|
||||||
else:
|
|
||||||
config_path = Path.cwd() / Config.DEFAULT_CONFIG_FILE
|
|
||||||
|
|
||||||
return Config(config_file=config_path)
|
|
||||||
|
def get_config_value(
|
||||||
|
key: str, default: Any = None, config: Optional[Config] = None
|
||||||
|
) -> Any:
|
||||||
|
"""Get a configuration value from a config or environment."""
|
||||||
|
if config is not None:
|
||||||
|
return config.get(key, default)
|
||||||
|
|
||||||
|
env_key = f"DEPNAV_{key.upper()}"
|
||||||
|
env_value = os.environ.get(env_key)
|
||||||
|
if env_value is not None:
|
||||||
|
return env_value
|
||||||
|
|
||||||
|
cfg = load_config()
|
||||||
|
return cfg.get(key, default)
|
||||||
|
|||||||
Reference in New Issue
Block a user