diff --git a/dzgui/app_init.py b/dzgui/app_init.py index 078f1f3..3ed89d2 100644 --- a/dzgui/app_init.py +++ b/dzgui/app_init.py @@ -1,9 +1,10 @@ import logging import os +import shutil from typing import TYPE_CHECKING -from dzgui.const.constants import APP_NAME +from dzgui.const.constants import APP_NAME, APP_NAME_LOWER from dzgui.const.enum import Preferences from dzgui.config.query import lookup from dzgui.config.userprefs import UserPrefs @@ -50,6 +51,46 @@ def setup_logger(log_path: "Path") -> None: logger.addHandler(fh) +def copy_bare_configs(config: "Path", resolution: "Path") -> tuple[bool, bool]: + # NOTE: temporary workaround for #375 + conf = "config.json" + state = [ + "dzg.history", + "dzg.versions", + "dzg.res.json", + "dzg.filters.json", + "dzg.columns.json", + "dzg.notes.json", + "ips.csv", + ".month", + ] + config_changed = False + state_changed = False + if config.parent.exists() is False: + new_file = config + old_file = config.parent.parent / conf + if old_file.is_file(): + try: + make_parents(new_file) + shutil.copy(old_file, new_file) + config_changed = True + except Exception as e: + logger.critical(e) + if resolution.parent.exists() is False: + state_path = resolution.parent + for state_file in state: + old_file = state_path.parent / state_file + if old_file.is_file(): + try: + new_file = state_path / state_file + make_parents(new_file) + shutil.copy(old_file, new_file) + state_changed = True + except Exception as e: + logger.critical(e) + return (config_changed, state_changed) + + def load_gui(version: str, is_debug: bool) -> None: lock = lock_acquire() # noqa @@ -58,6 +99,8 @@ def load_gui(version: str, is_debug: bool) -> None: xdg_paths = get_xdg_paths() XDG = parse_filepaths(xdg_paths) + copy_bare_configs(XDG.config, XDG.resolution) + if XDG.resolution.parent.is_dir() is False: make_parents(XDG.resolution) diff --git a/dzgui/config/xdg.py b/dzgui/config/xdg.py index 2748c8f..5b78423 100644 --- a/dzgui/config/xdg.py +++ b/dzgui/config/xdg.py @@ -29,9 +29,9 @@ def is_writeable(path_str: str) -> bool: if not path.exists(): try: path.mkdir(parents=True) + path.unlink() except OSError: return False - path.unlink() return True try: @@ -55,11 +55,12 @@ def get_xdg_paths() -> dict: resolved_paths = {} for path in xdg_paths: - rp = os.environ.get(path) - if rp is not None and is_writeable(rp): - resolved_paths[path] = Path(rp) + real_path = os.environ.get(path) + if real_path is not None and is_writeable(real_path): + new_path = Path(real_path) else: - resolved_paths[path] = xdg_paths[path] / APP_NAME_LOWER + new_path = xdg_paths[path] + resolved_paths[path] = new_path / APP_NAME_LOWER return resolved_paths diff --git a/tests/test_bare_conf_files.py b/tests/test_bare_conf_files.py new file mode 100644 index 0000000..9235390 --- /dev/null +++ b/tests/test_bare_conf_files.py @@ -0,0 +1,87 @@ +import pytest +import tempfile +import os + +from dzgui.app_init import copy_bare_configs +from dzgui.config.xdg import get_xdg_paths, parse_filepaths +from pathlib import Path + + +CONF_STRING = "DZGUI_CONF\n" +STATE_STRING = "DZGUI_STATE\n" + + +@pytest.fixture +def state_files(): + state = [ + "dzg.history", + "dzg.versions", + "dzg.res.json", + "dzg.filters.json", + "dzg.columns.json", + "dzg.notes.json", + "ips.csv", + ".month", + ] + return state + + +@pytest.fixture +def xdg_paths(): + paths = [] + routes = { + "XDG_CONFIG_HOME": "", + "XDG_STATE_HOME": "", + "XDG_DATA_HOME": "", + "XDG_CACHE_HOME": "", + } + for route in routes: + tmp = tempfile.TemporaryDirectory(delete=False) + routes[route] = tmp.name + for k, v in routes.items(): + os.environ[k] = v + env = get_xdg_paths() + return parse_filepaths(env) + + +@pytest.mark.mods +def test_config_file_import(xdg_paths, state_files): + + # NOTE: write bare files in root + tmp_conf = xdg_paths.config.parent.parent + tmp_conf_file = tmp_conf / xdg_paths.config.name + tmp_conf_file.write_text(CONF_STRING) + + tmp_state = xdg_paths.resolution.parent.parent + for file in state_files: + tmp_state.joinpath(file).write_text(STATE_STRING) + # NOTE: function should move files into "dzgui" subdirectory + config_changed, state_changed = copy_bare_configs( + xdg_paths.config, xdg_paths.resolution + ) + + assert xdg_paths.config.read_text() == CONF_STRING + for file in state_files: + expected = xdg_paths.resolution.parent.joinpath(file) + assert expected.read_text() == STATE_STRING + + assert config_changed is True + assert state_changed is True + + +@pytest.mark.mods +def test_config_file_no_import(xdg_paths, state_files): + for subdir in xdg_paths.config.parent, xdg_paths.resolution.parent: + subdir.mkdir() + + tmp_conf_file = xdg_paths.config + tmp_conf_file.write_text(CONF_STRING) + + for file in state_files: + xdg_paths.resolution.parent.joinpath(file).write_text(STATE_STRING) + + config_changed, state_changed = copy_bare_configs( + xdg_paths.config, xdg_paths.resolution + ) + assert config_changed is False + assert state_changed is False