diff --git a/src/badger/__main__.py b/src/badger/__main__.py index a6b397f9..a2d27c61 100644 --- a/src/badger/__main__.py +++ b/src/badger/__main__.py @@ -31,6 +31,13 @@ def main(): nargs="?", help="change the log level", ) + parser.add_argument( + "-cf", + "--config_filepath", + type=str, + default=None, + help="Path to the config file", + ) parser.set_defaults(func=show_info) subparsers = parser.add_subparsers(help="Badger commands help") diff --git a/src/badger/actions/__init__.py b/src/badger/actions/__init__.py index a87ccd8b..1478e78c 100644 --- a/src/badger/actions/__init__.py +++ b/src/badger/actions/__init__.py @@ -7,12 +7,16 @@ def show_info(args): # Change log level for all existed loggers set_log_level(args.log) + config_path = None + + if args.config_filepath: + config_path = args.config_filepath if args.gui: - if check_n_config_paths(): + if check_n_config_paths(args.config_filepath): from badger.gui.default import launch_gui - launch_gui() + launch_gui(config_path) return @@ -20,7 +24,7 @@ def show_info(args): if check_n_config_paths(): from badger.gui.default import launch_gui - launch_gui() + launch_gui(config_path) return diff --git a/src/badger/actions/doctor.py b/src/badger/actions/doctor.py index 02946d6f..48e3e8fd 100644 --- a/src/badger/actions/doctor.py +++ b/src/badger/actions/doctor.py @@ -5,6 +5,7 @@ def self_check(args): config = init_settings() # Reset Badger + if args.reset: while True: _res = input( @@ -30,8 +31,11 @@ def self_check(args): print("Badger is healthy!") -def check_n_config_paths(): - config = init_settings() +def check_n_config_paths(config_filepath=None): + if config_filepath is not None: + config = init_settings(config_filepath) + else: + config = init_settings() good = True issue_list = [] @@ -80,6 +84,7 @@ def check_n_config_paths(): try: print("") _config_path_var(pname) + # TODO potential keyError here except KeyboardInterrupt: pass diff --git a/src/badger/errors.py b/src/badger/errors.py index adba60d4..a13fcb66 100644 --- a/src/badger/errors.py +++ b/src/badger/errors.py @@ -90,7 +90,8 @@ class BadgerLogbookError(Exception): class BadgerLoadConfigError(Exception): - pass + def __init__(self, message="Config Error!"): + super().__init__(message) class BadgerRoutineError(Exception): diff --git a/src/badger/gui/default/__init__.py b/src/badger/gui/default/__init__.py index d62924de..04332547 100644 --- a/src/badger/gui/default/__init__.py +++ b/src/badger/gui/default/__init__.py @@ -78,10 +78,16 @@ def error_handler( raise BadgerError(error_title, error_msg) -def launch_gui(): +def launch_gui(config_path=None): sys.excepthook = error_handler + app = QApplication(sys.argv) - config_singleton = init_settings() + + if config_path is not None: + config_singleton = init_settings(config_path) + else: + config_singleton = init_settings() + # Set app metainfo app.setApplicationName("Badger") icon_ref = resources.files(__name__) / "images/icon.png" diff --git a/src/badger/settings.py b/src/badger/settings.py index 1b894d88..1a77adcd 100644 --- a/src/badger/settings.py +++ b/src/badger/settings.py @@ -6,6 +6,7 @@ from badger.utils import get_datadir from pydantic import BaseModel, Field, ValidationError from typing import Any, Dict, Optional, Union +from badger.errors import BadgerLoadConfigError class Setting(BaseModel): @@ -106,15 +107,16 @@ class BadgerConfig(BaseModel): class ConfigSingleton: _instance = None - def __new__(cls, config_path: str = None): + def __new__(cls, config_path: str = None, user_flag: bool = False): if cls._instance is None: cls._instance = super(ConfigSingleton, cls).__new__(cls) + cls._instance.user_flag = user_flag cls._instance._config = cls.load_or_create_config(config_path) cls._instance.config_path = config_path return cls._instance - @staticmethod - def load_or_create_config(config_path: str) -> BadgerConfig: + @classmethod + def load_or_create_config(cls, config_path: str) -> BadgerConfig: """ Loads the config file from a given yaml file if it exists, otherwise creates an instance of BadgerConfig with default settings. @@ -162,6 +164,10 @@ def load_or_create_config(config_path: str) -> BadgerConfig: print(f"Error validating config file: {e}") raise else: + if cls._instance.user_flag: + err_msg = f"Error loading config {config_path}: invalid path." + raise BadgerLoadConfigError(err_msg) + return BadgerConfig() @property @@ -348,20 +354,31 @@ def reset_settings(self) -> None: ) -def init_settings() -> ConfigSingleton: +def init_settings(config_arg: bool = None) -> ConfigSingleton: """ Builds and returns an instance of the ConfigSingleton class. + Parameters + ---------- + config_arg: bool + a path to a config file passed through the --config__filepath argument + Returns ------- config_singleton: ConfigSingleton an instance of the ConfigSingleton class """ + user_flag = False + + if config_arg is None: + config_path = get_user_config_folder() + file_name = "config.yaml" + file_path = os.path.join(config_path, file_name) + else: + file_path = config_arg + user_flag = True - config_path = get_user_config_folder() - file_name = "config.yaml" - file_path = os.path.join(config_path, file_name) - config_singleton = ConfigSingleton(file_path) + config_singleton = ConfigSingleton(file_path, user_flag) return config_singleton diff --git a/src/badger/tests/test_settings.py b/src/badger/tests/test_settings.py index a6189002..f3f09953 100644 --- a/src/badger/tests/test_settings.py +++ b/src/badger/tests/test_settings.py @@ -109,7 +109,7 @@ def test_init_settings(self): ) as mock_config_cls: config_singleton = init_settings() mock_config_cls.assert_called_once_with( - "/mock/config/folder/config.yaml" + "/mock/config/folder/config.yaml", False ) assert config_singleton == mock_config_singleton