diff --git a/.gitignore b/.gitignore index ab3e8ce..850957d 100644 --- a/.gitignore +++ b/.gitignore @@ -162,3 +162,5 @@ cython_debug/ # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ +.python-version +uv.lock diff --git a/main.py b/main.py new file mode 100644 index 0000000..953e626 --- /dev/null +++ b/main.py @@ -0,0 +1,21 @@ +import typer +from rich import print as pprint +from src.config.configuration_manager import ConMan + +def main(): + wf = typer.Typer(help='Eternal return of the same - replicate your configuration') + config_wf = typer.Typer() + + wf.add_typer(config_wf, name='config', help='Config file utilities') + + @config_wf.command('show', help='Display the full configuration') + def show(): + conf: dict = ConMan().get_all() + pprint(conf) + + wf() + + + +if __name__ == "__main__": + main() diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..eccae31 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,11 @@ +[project] +name = "wiederkunft" +version = "0.1.0" +description = "Replicate your dotfiles, projects, everything" +readme = "README.md" +requires-python = ">=3.13" +dependencies = [ + "pyyaml>=6.0.2", + "rich>=14.0.0", + "typer>=0.15.2", +] diff --git a/src/config/configuration_manager.py b/src/config/configuration_manager.py new file mode 100644 index 0000000..bfdbd52 --- /dev/null +++ b/src/config/configuration_manager.py @@ -0,0 +1,47 @@ +import yaml +from pathlib import Path +from typing import Dict, Any, Optional + +class ConMan: + def __init__(self, file_path: str = None) -> None: + if file_path is None: + self.file_path = Path.home() / '.config' / 'wiederkunft' / 'config.yaml' + else: + self.file_path = Path(file_path) + + self.config: Dict[str, Any] = {} + self.load_config() + + def load_config(self) -> None: + if not self.file_path.exists(): + raise FileNotFoundError(f"Config file not found: {self.file_path}") + + with open(self.file_path, 'r') as f: + self.config = yaml.safe_load(f) or {} + + def get(self, key: str, default: Optional[Any] = None) -> Any: + keys = key.split('.') + value = self.config + + try: + for k in keys: + value = value[k] + return value + except (KeyError, TypeError): + return default + + def __getitem__(self, key: str) -> Any: + return self.get(key) + + def __contains__(self, key: str) -> bool: + try: + self.get(key) + return True + except KeyError: + return False + + def reload(self) -> None: + self.load_config() + + def get_all(self) -> Dict[str, Any]: + return self.config