Initial upload: Devtoolbelt v1.0.0 - unified CLI toolkit for developers
Some checks failed
CI / build (push) Has been cancelled
CI / test (push) Has been cancelled

This commit is contained in:
2026-02-01 21:45:44 +00:00
parent 1ab452d776
commit ba0c44d6c0

144
devtoolbelt/config.py Normal file
View File

@@ -0,0 +1,144 @@
"""Configuration management for Devtoolbelt."""
from pathlib import Path
from typing import Any, Dict, Optional
import yaml
class Config:
"""Configuration manager for Devtoolbelt."""
DEFAULT_CONFIG_NAME = ".devtoolbelt.yml"
CONFIG_DIR = Path.home() / ".config" / "devtoolbelt"
def __init__(self, config_path: Optional[Path] = None):
"""Initialize configuration.
Args:
config_path: Optional path to config file. If not provided,
uses default locations.
"""
if config_path:
self.config_file = Path(config_path)
else:
self.config_file = self.CONFIG_DIR / self.DEFAULT_CONFIG_NAME
self._config: Dict[str, Any] = {}
def load(self) -> Dict[str, Any]:
"""Load configuration from file.
Returns:
Dictionary containing configuration.
"""
self._config = self._read_config()
return self._config
def _read_config(self) -> Dict[str, Any]:
"""Read configuration file.
Returns:
Dictionary containing config values or empty dict.
"""
if not self.config_file.exists():
return {}
try:
with open(self.config_file, 'r') as f:
return yaml.safe_load(f) or {}
except (yaml.YAMLError, IOError) as e:
print(f"Warning: Could not read config file: {e}")
return {}
def save(self, config: Optional[Dict[str, Any]] = None) -> None:
"""Save configuration to file.
Args:
config: Configuration to save. If None, saves current config.
"""
if config:
self._config = config
self.CONFIG_DIR.mkdir(parents=True, exist_ok=True)
with open(self.config_file, 'w') as f:
yaml.dump(self._config, f, default_flow_style=False)
def get(self, key: str, default: Any = None) -> Any:
"""Get a configuration value.
Args:
key: Configuration key (supports dot notation).
default: Default value if key not found.
Returns:
Configuration value or default.
"""
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
def set(self, key: str, value: Any) -> None:
"""Set a configuration value.
Args:
key: Configuration key (supports dot notation).
value: Value to set.
"""
keys = key.split('.')
config = self._config
for k in keys[:-1]:
if k not in config:
config[k] = {}
config = config[k]
config[keys[-1]] = value
def get_database_configs(self) -> Dict[str, Dict[str, Any]]:
"""Get all database configurations.
Returns:
Dictionary of database configs by name.
"""
return self.get('databases', {})
def get_api_endpoints(self) -> Dict[str, str]:
"""Get all API endpoints.
Returns:
Dictionary of API endpoints by name.
"""
return self.get('api_endpoints', {})
def get_default_db(self) -> Optional[str]:
"""Get default database name.
Returns:
Default database name or None.
"""
return self.get('default_database')
def get_config(config_path: Optional[str] = None) -> Config:
"""Get configuration instance.
Args:
config_path: Optional path to config file.
Returns:
Config instance.
"""
config = Config(Path(config_path) if config_path else None)
config.load()
return config