1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
|
"""Handle configuration files."""
from pathlib import Path
from typing import (
Any,
Dict,
IO,
Optional,
)
import yaml
from .profile import Profile
def yaml_dump(data: Dict, fh: Optional[IO] = None):
"""Dump data in YAML format with sane defaults for readability."""
return yaml.safe_dump(
data, fh, default_flow_style=False, allow_unicode=True
)
class Config:
"""Handle configuration file loading/saving."""
CONFIG_KEYS = frozenset(["executable", "extra-options"])
def __init__(self, path: Path):
self._config_file = path / "config.yaml"
self._profiles_file = path / "profiles.yaml"
self._reset()
def load(self):
"""Load configuration from file."""
self._reset()
self._config = self._load_yaml_file(self._config_file)
profiles = self._load_yaml_file(self._profiles_file)
for name, conf in profiles.items():
self._profiles[name] = Profile.from_config(conf)
def save(self):
"""Save profiles configuration to file."""
config = {
name: profile.config() for name, profile in self._profiles.items()
}
self._profiles_file.write_text(yaml_dump(config))
def add_profile(self, name: str, profile: Profile):
"""Add a profile to the configuration."""
if name in self._profiles:
raise KeyError(name)
self._profiles[name] = profile
def remove_profile(self, name: str):
"""Add the given profile to the configuration."""
del self._profiles[name]
@property
def profiles(self) -> Dict[str, Profile]:
"""Return a dict with profiles, using names as key."""
return self._profiles.copy()
@property
def config(self) -> Dict[str, Any]:
"""Return a dict with the configuration."""
return {
key: value
for key, value in self._config.items()
if key in self.CONFIG_KEYS
}
def _reset(self) -> None:
"""Reset default empty config."""
self._profiles: Dict[str, Profile] = {}
self._config = {}
def _load_yaml_file(self, path: Path) -> Dict[str, Any]:
"""Load the specified YAML file."""
if not path.exists():
return {}
return yaml.safe_load(path.read_text()) or {}
|