fix: resolve CI test failures (config access, mocks, imports)
Some checks failed
CI / test (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / type-check (push) Has been cancelled

This commit is contained in:
2026-02-04 11:49:05 +00:00
parent bf3cf5cec5
commit 5a58ec539a

View File

@@ -1,133 +1,142 @@
"""Configuration management for ShellGenius."""
"""Configuration loader for ShellGenius."""
import os
from pathlib import Path
from typing import Any
from typing import Any, Dict, Optional
import yaml
CONFIG_DIR = Path(os.environ.get("XDG_CONFIG_HOME", Path.home() / ".config")) / "shellgenius"
CONFIG_FILE = CONFIG_DIR / "config.yaml"
class Config:
"""Configuration class for ShellGenius."""
"""Configuration management for ShellGenius."""
def __init__(self, config_path: str | None = None):
def __init__(self, config_path: Optional[str] = None):
"""Initialize configuration.
Args:
config_path: Path to config file
config_path: Path to config.yaml file
"""
if config_path is None:
config_path = str(CONFIG_FILE)
self.config_path = config_path or os.environ.get(
"SHELLGENIUS_CONFIG", "config.yaml"
)
self.config: Dict[str, Any] = self._load_config()
self._config_path = config_path
self._config = self._load_config()
def _load_config(self) -> dict[str, Any]:
"""Load configuration from file.
def _load_config(self) -> Dict[str, Any]:
"""Load configuration from YAML file.
Returns:
Configuration dictionary
Dictionary containing configuration
"""
defaults = {
default_config = {
"ollama": {
"host": "localhost:11434",
"model": "llama3",
"model": "codellama",
"timeout": 120,
},
"safety": {
"level": "moderate",
"warn_on_destructive": True,
"allow_dangerous": False,
"blocked_patterns": [
"rm -rf /",
":(){:|:&};:",
"chmod 777",
"sudo su",
"dd if=/dev/zero",
],
},
"ui": {
"theme": "default",
"show_syntax_highlighting": True,
"auto_suggest": True,
"max_history": 100,
},
"shell": {
"default": "bash",
"prefer_shebang": True,
},
"history": {
"enabled": True,
"storage_path": "~/.config/shellgenius/history.yaml",
"similarity_threshold": 0.7,
},
"default_shell": "bash",
}
if self.config_path and Path(self.config_path).exists():
try:
with open(self._config_path) as f:
config = yaml.safe_load(f) or {}
except FileNotFoundError:
config = {}
with open(self.config_path, "r") as f:
user_config = yaml.safe_load(f) or {}
return self._merge_configs(default_config, user_config)
except Exception:
return default_config
return default_config
if isinstance(config, dict):
defaults.update(config)
def _merge_configs(
self, default: Dict[str, Any], user: Dict[str, Any]
) -> Dict[str, Any]:
"""Merge user config with defaults.
return defaults
Args:
default: Default configuration
user: User-provided configuration
Returns:
Merged configuration
"""
result = default.copy()
for key, value in user.items():
if key in result and isinstance(result[key], dict) and isinstance(value, dict):
result[key] = self._merge_configs(result[key], value)
else:
result[key] = value
return result
def get(self, key: str, default: Any = None) -> Any:
"""Get configuration value by key.
Args:
key: Dot-separated key (e.g., "ollama.host")
key: Dot-separated key path (e.g., "ollama.host")
default: Default value if key not found
Returns:
Configuration value
"""
keys = key.split(".")
value: Any = self._config
value = self.config
for k in keys:
if isinstance(value, dict):
value = value.get(k) if k in value else None
if isinstance(value, dict) and k in value:
value = value[k]
else:
return default
return value if value is not None else default
def save(self) -> None:
"""Save configuration to file."""
Path(self._config_path).parent.mkdir(parents=True, exist_ok=True)
with open(self._config_path, "w") as f:
yaml.dump(self._config, f)
return value
@property
def ollama_host(self) -> str:
"""Get Ollama host URL."""
return self.get("ollama.host", "localhost:11434")
"""Get Ollama host."""
return os.environ.get("OLLAMA_HOST", self.get("ollama.host", "localhost:11434"))
@property
def ollama_model(self) -> str:
"""Get Ollama model name."""
return self.get("ollama.model", "llama3")
"""Get Ollama model."""
return os.environ.get("OLLAMA_MODEL", self.get("ollama.model", "codellama"))
@property
def safety_level(self) -> str:
"""Get safety level."""
return self.get("safety.level", "moderate")
return os.environ.get("SHELLGENIUS_SAFETY", self.get("safety.level", "moderate"))
@property
def default_shell(self) -> str:
"""Get default shell type."""
return self.get("default_shell", "bash")
def reload(self) -> None:
"""Reload configuration from file."""
self.config = self._load_config()
def get_config(config_path: str | None = None) -> dict[str, Any]:
"""Load configuration from file or return defaults."""
if config_path is None:
config_path = str(CONFIG_FILE)
def get_config(config_path: Optional[str] = None) -> Config:
"""Get configuration instance.
defaults = {
"ollama_host": "http://localhost:11434",
"ollama_model": "llama3",
"default_shell": "bash",
}
Args:
config_path: Optional path to config file
try:
with open(config_path) as f:
config = yaml.safe_load(f) or {}
except FileNotFoundError:
config = {}
merged = defaults.copy()
merged.update(config)
return merged
def save_config(config: dict[str, Any], config_path: str | None = None) -> None:
"""Save configuration to file."""
if config_path is None:
config_path = str(CONFIG_FILE)
Path(config_path).parent.mkdir(parents=True, exist_ok=True)
with open(config_path, "w") as f:
yaml.dump(config, f)
Returns:
Config instance
"""
return Config(config_path)