Skip to content

Commit

Permalink
Refactor configuration and improve error messaging
Browse files Browse the repository at this point in the history
  • Loading branch information
djcopley committed May 10, 2024
1 parent 5c90d96 commit 5b9da8a
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 20 deletions.
2 changes: 2 additions & 0 deletions src/shelloracle/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import logging
from importlib.metadata import version

from shelloracle.config import initialize_config
from . import shelloracle
from .settings import Settings

Expand Down Expand Up @@ -42,6 +43,7 @@ def main() -> None:
if action := getattr(args, "action", None):
action()
exit(0)
initialize_config()

shelloracle.cli()

Expand Down
4 changes: 2 additions & 2 deletions src/shelloracle/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from prompt_toolkit.formatted_text import FormattedText
from prompt_toolkit.shortcuts import confirm

from .config import Configuration
from .config import get_config
from .providers import Provider, Setting, list_providers, get_provider


Expand Down Expand Up @@ -118,7 +118,7 @@ def write_shelloracle_config(provider: type[Provider], settings: dict[str, Any])
provider_configuration_table.add(setting, value)
provider_table.add(provider.name, provider_configuration_table)

with Configuration.filepath.open("w") as config_file:
with get_config().filepath.open("w") as config_file:
tomlkit.dump(config, config_file)


Expand Down
49 changes: 31 additions & 18 deletions src/shelloracle/config.py
Original file line number Diff line number Diff line change
@@ -1,40 +1,36 @@
from __future__ import annotations

import logging
import os
import sys
from collections.abc import Mapping, Iterator
from pathlib import Path
from typing import Any

from yaspin.spinners import SPINNERS_DATA

from shelloracle.settings import Settings

if sys.version_info < (3, 11):
import tomli as tomllib
else:
import tomllib

from .settings import Settings

logger = logging.getLogger(__name__)


class Configuration(Mapping):
"""ShellOracle application configuration

The configuration is loaded at program startup, and persisted for the life of the application. Any changes made
to the configuration while the application is running, will have no effect.
"""
if "SHELLORACLE_CONFIG" in os.environ:
filepath = Path(os.environ["SHELLORACLE_CONFIG"]).absolute()
else:
filepath = Settings.shelloracle_home / "config.toml"
def __init__(self, filepath: Path) -> None:
"""ShellOracle application configuration
def __init__(self) -> None:
with self.filepath.open("rb") as config_file:
:param filepath: Path to the configuration file
:raises FileNotFoundError: if the configuration file does not exist
"""
self.filepath = filepath
with filepath.open("rb") as config_file:
self._config = tomllib.load(config_file)

def __getitem__(self, key) -> Any:
def __getitem__(self, key: str) -> Any:
return self._config[key]

def __len__(self) -> int:
Expand All @@ -43,6 +39,12 @@ def __len__(self) -> int:
def __iter__(self) -> Iterator[Any]:
return iter(self._config)

def __str__(self):
return f"Configuration({self._config})"

def __repr__(self) -> str:
return str(self)

@property
def provider(self) -> str:
return self["shelloracle"]["provider"]
Expand All @@ -61,14 +63,25 @@ def spinner_style(self) -> str | None:
_config: Configuration | None = None


def initialize_config() -> None:
"""Initialize the configuration file
:raises RuntimeError: if the config is already initialized
:raises FileNotFoundError: if the config file is not found
"""
global _config
if _config:
raise RuntimeError("Configuration already initialized")
filepath = Settings.shelloracle_home / "config.toml"
_config = Configuration(filepath)


def get_config() -> Configuration:
"""Returns the global configuration object.
Creates global configuration from the configuration toml the first time the function is called.
:return: the global configuration
:raises RuntimeError: if the configuration is not initialized
"""
global _config
if _config is None:
_config = Configuration()
raise RuntimeError("Configuration not initialized")
return _config

0 comments on commit 5b9da8a

Please sign in to comment.