From 8379ecefaa68862b1e60a6ee9fca6bbcdf126fea Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Fri, 3 Feb 2023 20:36:43 +0100 Subject: [PATCH] deal with BORG_BASE_DIR --- src/borg/helpers/__init__.py | 2 +- src/borg/helpers/fs.py | 39 ++++++++++++++++++++++++----------- src/borg/testsuite/helpers.py | 11 ++++++++++ 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/src/borg/helpers/__init__.py b/src/borg/helpers/__init__.py index 82cd027a5..e42d78415 100644 --- a/src/borg/helpers/__init__.py +++ b/src/borg/helpers/__init__.py @@ -11,7 +11,7 @@ from ..constants import * # NOQA from .checks import check_extension_modules, check_python from .datastruct import StableDict, Buffer, EfficientCollectionQueue from .errors import Error, ErrorWithTraceback, IntegrityError, DecompressionError -from .fs import ensure_dir, get_security_dir, get_keys_dir, get_base_dir, get_cache_dir, get_config_dir +from .fs import ensure_dir, get_security_dir, get_keys_dir, get_base_dir, join_base_dir, get_cache_dir, get_config_dir from .fs import dir_is_tagged, dir_is_cachedir, make_path_safe, scandir_inorder from .fs import secure_erase, safe_unlink, dash_open, os_open, os_stat, umount from .fs import O_, flags_root, flags_dir, flags_special_follow, flags_special, flags_base, flags_normal, flags_noatime diff --git a/src/borg/helpers/fs.py b/src/borg/helpers/fs.py index ef135877c..ee2ae1aaa 100644 --- a/src/borg/helpers/fs.py +++ b/src/borg/helpers/fs.py @@ -42,7 +42,7 @@ def ensure_dir(path, mode=stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO, pretty_dea raise -def get_base_dir(): +def get_base_dir(legacy=True): """Get home directory / base directory for borg: - BORG_BASE_DIR, if set @@ -50,16 +50,27 @@ def get_base_dir(): - ~$USER, if USER is set - ~ """ - base_dir = os.environ.get("BORG_BASE_DIR") or os.environ.get("HOME") - # os.path.expanduser() behaves differently for '~' and '~someuser' as - # parameters: when called with an explicit username, the possibly set - # environment variable HOME is no longer respected. So we have to check if - # it is set and only expand the user's home directory if HOME is unset. - if not base_dir: - base_dir = os.path.expanduser("~%s" % os.environ.get("USER", "")) + if legacy: + base_dir = os.environ.get("BORG_BASE_DIR") or os.environ.get("HOME") + # os.path.expanduser() behaves differently for '~' and '~someuser' as + # parameters: when called with an explicit username, the possibly set + # environment variable HOME is no longer respected. So we have to check if + # it is set and only expand the user's home directory if HOME is unset. + if not base_dir: + base_dir = os.path.expanduser("~%s" % os.environ.get("USER", "")) + else: + # we only care for BORG_BASE_DIR here, as it can be used to override the base dir + # and not use any more or less platform specific way to determine the base dir. + base_dir = os.environ.get("BORG_BASE_DIR") return base_dir +def join_base_dir(*paths, **kw): + legacy = kw.get("legacy", True) + base_dir = get_base_dir(legacy=legacy) + return None if base_dir is None else os.path.join(base_dir, *paths) + + def get_keys_dir(legacy=True): """Determine where to repository keys and cache""" keys_dir = os.environ.get("BORG_KEYS_DIR") @@ -87,14 +98,16 @@ def get_cache_dir(legacy=True): if legacy: # Get cache home path - cache_home = os.path.join(get_base_dir(), ".cache") + cache_home = join_base_dir(".cache", legacy=legacy) # Try to use XDG_CACHE_HOME instead if BORG_BASE_DIR isn't explicitly set if not os.environ.get("BORG_BASE_DIR"): cache_home = os.environ.get("XDG_CACHE_HOME", cache_home) # Use BORG_CACHE_DIR if set, otherwise assemble final path from cache home path cache_dir = os.environ.get("BORG_CACHE_DIR", os.path.join(cache_home, "borg")) else: - cache_dir = os.environ.get("BORG_CACHE_DIR", platformdirs.user_cache_dir("borg")) + cache_dir = os.environ.get( + "BORG_CACHE_DIR", join_base_dir(".cache", legacy=legacy) or platformdirs.user_cache_dir("borg") + ) # Create path if it doesn't exist yet ensure_dir(cache_dir) @@ -122,14 +135,16 @@ def get_config_dir(legacy=True): # Get config home path if legacy: - config_home = os.path.join(get_base_dir(), ".config") + config_home = join_base_dir(".config", legacy=legacy) # Try to use XDG_CONFIG_HOME instead if BORG_BASE_DIR isn't explicitly set if not os.environ.get("BORG_BASE_DIR"): config_home = os.environ.get("XDG_CONFIG_HOME", config_home) # Use BORG_CONFIG_DIR if set, otherwise assemble final path from config home path config_dir = os.environ.get("BORG_CONFIG_DIR", os.path.join(config_home, "borg")) else: - config_dir = os.environ.get("BORG_CONFIG_DIR", platformdirs.user_config_dir("borg")) + config_dir = os.environ.get( + "BORG_CONFIG_DIR", join_base_dir(".config", legacy=legacy) or platformdirs.user_config_dir("borg") + ) # Create path if it doesn't exist yet ensure_dir(config_dir) diff --git a/src/borg/testsuite/helpers.py b/src/borg/testsuite/helpers.py index ca10d9980..8a4fb6cc2 100644 --- a/src/borg/testsuite/helpers.py +++ b/src/borg/testsuite/helpers.py @@ -593,6 +593,17 @@ def test_get_base_dir(monkeypatch): assert get_base_dir() == "/var/tmp/base" +def test_get_base_dir_compat(monkeypatch): + """test that it works the same for legacy and for non-legacy implementation""" + monkeypatch.delenv("BORG_BASE_DIR", raising=False) + # old way: if BORG_BASE_DIR is not set, make something up with HOME/USER/~ + # new way: if BORG_BASE_DIR is not set, return None and let caller deal with it. + assert get_base_dir(legacy=False) is None + # new and old way: BORG_BASE_DIR overrides all other "base path determination". + monkeypatch.setenv("BORG_BASE_DIR", "/var/tmp/base") + assert get_base_dir(legacy=False) == get_base_dir(legacy=True) + + def test_get_config_dir(monkeypatch): """test that get_config_dir respects environment""" monkeypatch.delenv("BORG_CONFIG_DIR", raising=False)