Fixes tests/docs assuming XDG_* vars not used on macOS

The move to platformdirs and its current usage _does_ honor XDG_*
variables on macOS if they are set. Tests were set up to assume this to
be untrue and the docs matched that.

This commit adds tests asserting that XDG_* variables are used when they
are present on macOS, with default locations still in ~/Library.
This commit is contained in:
Hugo Wallenburg 2026-04-03 11:34:10 +02:00
parent 84fb1c9435
commit c8f8defc0f
No known key found for this signature in database
3 changed files with 24 additions and 9 deletions

View file

@ -124,7 +124,7 @@ Compatibility notes:
- use platformdirs 3.x.x instead of home-grown code. Due to that:
- XDG_*_HOME is not honoured on macOS and on Windows.
- XDG_*_HOME is not honoured on Windows.
- BORG_BASE_DIR can still be used to enforce some base dir + .config/ or .cache/.
- on macOS, the default directories move to native locations:
config/data: ``~/Library/Application Support/borg/``,

View file

@ -169,8 +169,8 @@ Directories and files:
- **Linux**: Uses XDG Base Directory Specification paths (e.g., ``~/.config/borg``,
``~/.cache/borg``, ``~/.local/share/borg``). `XDG env var`_ variables are honoured.
- **macOS**: Uses native macOS directories (e.g., ``~/Library/Application Support/borg``,
``~/Library/Caches/borg``). `XDG env var`_ variables are **not** honoured.
- **macOS**: Uses native macOS directories by default (e.g., ``~/Library/Application Support/borg``,
``~/Library/Caches/borg``). `XDG env var`_ variables are honoured if set.
- **Windows**: Uses Windows AppData directories (e.g., ``C:\Users\<user>\AppData\Roaming\borg``,
``C:\Users\<user>\AppData\Local\borg``). `XDG env var`_ variables are **not** honoured.
@ -221,26 +221,26 @@ Directories and files:
BORG_CACHE_DIR
Defaults to the platform-specific cache directory (see table above).
If ``BORG_BASE_DIR`` is set, defaults to ``$BORG_BASE_DIR/.cache/borg``.
On Linux, `XDG env var`_ ``XDG_CACHE_HOME`` is also honoured if ``BORG_BASE_DIR`` is not set.
On Linux and macOS, `XDG env var`_ ``XDG_CACHE_HOME`` is also honoured if ``BORG_BASE_DIR`` is not set.
This directory contains the local cache and might need a lot
of space for dealing with big repositories. Make sure you're aware of the associated
security aspects of the cache location: :ref:`cache_security`
BORG_CONFIG_DIR
Defaults to the platform-specific config directory (see table above).
If ``BORG_BASE_DIR`` is set, defaults to ``$BORG_BASE_DIR/.config/borg``.
On Linux, `XDG env var`_ ``XDG_CONFIG_HOME`` is also honoured if ``BORG_BASE_DIR`` is not set.
On Linux and macOS, `XDG env var`_ ``XDG_CONFIG_HOME`` is also honoured if ``BORG_BASE_DIR`` is not set.
This directory contains all borg configuration directories, see the FAQ
for a security advisory about the data in this directory: :ref:`home_config_borg`
BORG_DATA_DIR
Defaults to the platform-specific data directory (see table above).
If ``BORG_BASE_DIR`` is set, defaults to ``$BORG_BASE_DIR/.local/share/borg``.
On Linux, `XDG env var`_ ``XDG_DATA_HOME`` is also honoured if ``BORG_BASE_DIR`` is not set.
On Linux and macOS, `XDG env var`_ ``XDG_DATA_HOME`` is also honoured if ``BORG_BASE_DIR`` is not set.
This directory contains all borg data directories, see the FAQ
for a security advisory about the data in this directory: :ref:`home_data_borg`
BORG_RUNTIME_DIR
Defaults to the platform-specific runtime directory (see table above).
If ``BORG_BASE_DIR`` is set, defaults to ``$BORG_BASE_DIR/.cache/borg``.
On Linux, `XDG env var`_ ``XDG_RUNTIME_DIR`` is also honoured if ``BORG_BASE_DIR`` is not set.
On Linux and macOS, `XDG env var`_ ``XDG_RUNTIME_DIR`` is also honoured if ``BORG_BASE_DIR`` is not set.
This directory contains borg runtime files, like e.g. the socket file.
BORG_SECURITY_DIR
Defaults to ``$BORG_DATA_DIR/security``.

View file

@ -69,8 +69,11 @@ def test_get_config_dir(monkeypatch):
monkeypatch.setenv("BORG_CONFIG_DIR", home_dir)
assert get_config_dir(create=False) == home_dir
elif is_darwin:
monkeypatch.delenv("XDG_CONFIG_HOME", raising=False)
monkeypatch.delenv("BORG_CONFIG_DIR", raising=False)
assert get_config_dir(create=False) == os.path.join(home_dir, "Library", "Application Support", "borg")
monkeypatch.setenv("XDG_CONFIG_HOME", "/var/tmp/.config")
assert get_config_dir(create=False) == os.path.join("/var/tmp/.config", "borg")
monkeypatch.setenv("BORG_CONFIG_DIR", "/var/tmp")
assert get_config_dir(create=False) == "/var/tmp"
else:
@ -92,8 +95,8 @@ def test_get_config_dir_compat(monkeypatch):
# fails on macOS: assert '/Users/tw/Library/Application Support/borg' == '/Users/tw/.config/borg'
# fails on win32 MSYS2 (but we do not need legacy compat there).
assert get_config_dir(legacy=False, create=False) == get_config_dir(legacy=True, create=False)
if not is_win32:
monkeypatch.setenv("XDG_CONFIG_HOME", "/var/tmp/xdg.config.d")
# fails on macOS: assert '/Users/tw/Library/Application Support/borg' == '/var/tmp/xdg.config.d'
# fails on win32 MSYS2 (but we do not need legacy compat there).
assert get_config_dir(legacy=False, create=False) == get_config_dir(legacy=True, create=False)
monkeypatch.setenv("BORG_BASE_DIR", "/var/tmp/base")
@ -112,8 +115,11 @@ def test_get_cache_dir(monkeypatch):
monkeypatch.setenv("BORG_CACHE_DIR", home_dir)
assert get_cache_dir(create=False) == home_dir
elif is_darwin:
monkeypatch.delenv("XDG_CACHE_HOME", raising=False)
monkeypatch.delenv("BORG_CACHE_DIR", raising=False)
assert get_cache_dir(create=False) == os.path.join(home_dir, "Library", "Caches", "borg")
monkeypatch.setenv("XDG_CACHE_HOME", "/var/tmp/.cache")
assert get_cache_dir(create=False) == os.path.join("/var/tmp/.cache", "borg")
monkeypatch.setenv("BORG_CACHE_DIR", "/var/tmp")
assert get_cache_dir(create=False) == "/var/tmp"
else:
@ -135,7 +141,7 @@ def test_get_cache_dir_compat(monkeypatch):
# fails on macOS: assert '/Users/tw/Library/Caches/borg' == '/Users/tw/.cache/borg'
# fails on win32 MSYS2 (but we do not need legacy compat there).
assert get_cache_dir(legacy=False, create=False) == get_cache_dir(legacy=True, create=False)
# fails on macOS: assert '/Users/tw/Library/Caches/borg' == '/var/tmp/xdg.cache.d'
if not is_win32:
# fails on win32 MSYS2 (but we do not need legacy compat there).
monkeypatch.setenv("XDG_CACHE_HOME", "/var/tmp/xdg.cache.d")
assert get_cache_dir(legacy=False, create=False) == get_cache_dir(legacy=True, create=False)
@ -155,8 +161,11 @@ def test_get_keys_dir(monkeypatch):
monkeypatch.setenv("BORG_KEYS_DIR", home_dir)
assert get_keys_dir(create=False) == home_dir
elif is_darwin:
monkeypatch.delenv("XDG_CONFIG_HOME", raising=False)
monkeypatch.delenv("BORG_KEYS_DIR", raising=False)
assert get_keys_dir(create=False) == os.path.join(home_dir, "Library", "Application Support", "borg", "keys")
monkeypatch.setenv("XDG_CONFIG_HOME", "/var/tmp/.config")
assert get_keys_dir(create=False) == os.path.join("/var/tmp/.config", "borg", "keys")
monkeypatch.setenv("BORG_KEYS_DIR", "/var/tmp")
assert get_keys_dir(create=False) == "/var/tmp"
else:
@ -182,6 +191,7 @@ def test_get_security_dir(monkeypatch):
monkeypatch.setenv("BORG_SECURITY_DIR", home_dir)
assert get_security_dir(create=False) == home_dir
elif is_darwin:
monkeypatch.delenv("XDG_DATA_HOME", raising=False)
monkeypatch.delenv("BORG_SECURITY_DIR", raising=False)
assert get_security_dir(create=False) == os.path.join(
home_dir, "Library", "Application Support", "borg", "security"
@ -189,6 +199,8 @@ def test_get_security_dir(monkeypatch):
assert get_security_dir(repository_id="1234", create=False) == os.path.join(
home_dir, "Library", "Application Support", "borg", "security", "1234"
)
monkeypatch.setenv("XDG_DATA_HOME", "/var/tmp/.config")
assert get_security_dir(create=False) == os.path.join("/var/tmp/.config", "borg", "security")
monkeypatch.setenv("BORG_SECURITY_DIR", "/var/tmp")
assert get_security_dir(create=False) == "/var/tmp"
else:
@ -214,8 +226,11 @@ def test_get_runtime_dir(monkeypatch):
monkeypatch.setenv("BORG_RUNTIME_DIR", home_dir)
assert get_runtime_dir(create=False) == home_dir
elif is_darwin:
monkeypatch.delenv("XDG_RUNTIME_DIR", raising=False)
monkeypatch.delenv("BORG_RUNTIME_DIR", raising=False)
assert get_runtime_dir(create=False) == os.path.join(home_dir, "Library", "Caches", "TemporaryItems", "borg")
monkeypatch.setenv("XDG_RUNTIME_DIR", "/var/tmp/.cache")
assert get_runtime_dir(create=False) == os.path.join("/var/tmp/.cache", "borg")
monkeypatch.setenv("BORG_RUNTIME_DIR", "/var/tmp")
assert get_runtime_dir(create=False) == "/var/tmp"
else: