Add core source files: main, models, config
This commit is contained in:
97
src/codexchange/config.py
Normal file
97
src/codexchange/config.py
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
"""Configuration management for CodeXchange CLI."""
|
||||||
|
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
import yaml
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigSettings(BaseModel):
|
||||||
|
"""Configuration settings for CodeXchange CLI."""
|
||||||
|
|
||||||
|
ollama_host: str = "http://localhost:11434"
|
||||||
|
default_model: str = "codellama"
|
||||||
|
timeout: int = 300
|
||||||
|
verbose: bool = False
|
||||||
|
|
||||||
|
model_config = {
|
||||||
|
"populate_by_name": True
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_config_path() -> Path:
|
||||||
|
"""Get the path to the configuration file."""
|
||||||
|
return Path.home() / ".codexchange.yaml"
|
||||||
|
|
||||||
|
|
||||||
|
def load_config(config_path: Optional[Path] = None) -> ConfigSettings:
|
||||||
|
"""Load configuration from file.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
config_path: Optional path to config file. If not provided, uses default location.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
ConfigSettings object with loaded configuration.
|
||||||
|
"""
|
||||||
|
if config_path is None:
|
||||||
|
config_path = get_config_path()
|
||||||
|
|
||||||
|
config = ConfigSettings()
|
||||||
|
|
||||||
|
if config_path.exists():
|
||||||
|
try:
|
||||||
|
with open(config_path, "r") as f:
|
||||||
|
config_data = yaml.safe_load(f) or {}
|
||||||
|
config = ConfigSettings(**config_data)
|
||||||
|
except (yaml.YAMLError, IOError) as e:
|
||||||
|
print(f"Warning: Failed to load config file: {e}")
|
||||||
|
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
def save_config(config: ConfigSettings, config_path: Optional[Path] = None) -> None:
|
||||||
|
"""Save configuration to file.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
config: ConfigSettings object to save.
|
||||||
|
config_path: Optional path to config file. If not provided, uses default location.
|
||||||
|
"""
|
||||||
|
if config_path is None:
|
||||||
|
config_path = get_config_path()
|
||||||
|
|
||||||
|
config_dict = config.model_dump(exclude_none=True)
|
||||||
|
|
||||||
|
config_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
with open(config_path, "w") as f:
|
||||||
|
yaml.dump(config_dict, f, default_flow_style=False)
|
||||||
|
|
||||||
|
|
||||||
|
def get_config() -> ConfigSettings:
|
||||||
|
"""Get configuration with environment variable overrides.
|
||||||
|
|
||||||
|
Environment variables:
|
||||||
|
CODEXCHANGE_OLLAMA_HOST: Ollama host URL
|
||||||
|
CODEXCHANGE_DEFAULT_MODEL: Default model name
|
||||||
|
CODEXCHANGE_TIMEOUT: Request timeout in seconds
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
ConfigSettings object with merged configuration.
|
||||||
|
"""
|
||||||
|
config = load_config()
|
||||||
|
|
||||||
|
if os.getenv("CODEXCHANGE_OLLAMA_HOST"):
|
||||||
|
config.ollama_host = os.getenv("CODEXCHANGE_OLLAMA_HOST", "")
|
||||||
|
|
||||||
|
if os.getenv("CODEXCHANGE_DEFAULT_MODEL"):
|
||||||
|
config.default_model = os.getenv("CODEXCHANGE_DEFAULT_MODEL", "")
|
||||||
|
|
||||||
|
if os.getenv("CODEXCHANGE_TIMEOUT"):
|
||||||
|
try:
|
||||||
|
config.timeout = int(os.getenv("CODEXCHANGE_TIMEOUT") or "300")
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return config
|
||||||
Reference in New Issue
Block a user