feat(environ): allow XONSH_*_DIR to be configurable (#5783)

* feat(environ): allow XONSH_*_DIR to be configurable

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* test(env): add env var test

* fix(test): move test to test_environ

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update test_environ.py

* Update configurable-xonsh-dirs.rst

---------

Co-authored-by: Artur Manuel <balkenix@outlook.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Andy Kipp <anki-code@users.noreply.github.com>
This commit is contained in:
Artur Manuel 2025-01-29 16:14:02 +00:00 committed by GitHub
parent e7426ce709
commit 0292b43e64
Failed to generate hash of commit
5 changed files with 64 additions and 23 deletions

4
.gitignore vendored
View file

@ -100,3 +100,7 @@ pdm.lock
# asv benchmarks # asv benchmarks
.asv/ .asv/
# nix symlinks
result
repl-result-out

View file

@ -0,0 +1,23 @@
**Added:**
* env: Added XONSH_CONFIG_DIR, XONSH_DATA_DIR and XONSH_CACHE_DIR.
**Changed:**
* <news item>
**Deprecated:**
* <news item>
**Removed:**
* <news item>
**Fixed:**
* <news item>
**Security:**
* <news item>

View file

@ -20,6 +20,9 @@ from xonsh.environ import (
default_value, default_value,
locate_binary, locate_binary,
make_args_env, make_args_env,
xonsh_cache_dir,
xonsh_config_dir,
xonsh_data_dir,
) )
from xonsh.pytest.tools import skip_if_on_unix from xonsh.pytest.tools import skip_if_on_unix
from xonsh.tools import DefaultNotGiven, always_true from xonsh.tools import DefaultNotGiven, always_true
@ -648,3 +651,12 @@ def test_thread_local_dict_multiple():
t.join() t.join()
assert thread_values == [i**2 for i in range(num_threads)] assert thread_values == [i**2 for i in range(num_threads)]
def test_xonsh_dir_vars():
env = Env(
XONSH_CONFIG_DIR="/config", XONSH_CACHE_DIR="/cache", XONSH_DATA_DIR="/data"
)
assert xonsh_config_dir(env), "/config"
assert xonsh_cache_dir(env), "/cache"
assert xonsh_data_dir(env), "/data"

View file

@ -1515,7 +1515,10 @@ def test_xonshrc(tmpdir, cmd, exp):
(script_xsh := home / "script.xsh").write_text("echo SCRIPT_XSH", encoding="utf8") (script_xsh := home / "script.xsh").write_text("echo SCRIPT_XSH", encoding="utf8")
# Construct $XONSHRC and $XONSHRC_DIR. # Construct $XONSHRC and $XONSHRC_DIR.
xonshrc_files = [str(home_config_xonsh_rc_xsh), str(home_xonsh_rc_path)] xonshrc_files = [
str(home_config_xonsh_rc_xsh),
str(home_xonsh_rc_path),
]
xonshrc_dir = [str(home_config_xonsh_rcd)] xonshrc_dir = [str(home_config_xonsh_rcd)]
args = [ args = [
@ -1535,7 +1538,6 @@ def test_xonshrc(tmpdir, cmd, exp):
env=env, env=env,
) )
exp = exp
assert re.match( assert re.match(
exp, exp,
out, out,

View file

@ -569,7 +569,9 @@ DEFAULT_TITLE = "{current_job:{} | }{user}@{hostname}: {cwd} | xonsh"
@default_value @default_value
def xonsh_data_dir(env): def xonsh_data_dir(env):
"""Ensures and returns the $XONSH_DATA_DIR""" """Ensures and returns the $XONSH_DATA_DIR"""
xdd = os.path.expanduser(os.path.join(env.get("XDG_DATA_HOME"), "xonsh")) xdd = os.path.expanduser(
os.getenv("XONSH_DATA_DIR") or os.path.join(env.get("XDG_DATA_HOME"), "xonsh")
)
os.makedirs(xdd, exist_ok=True) os.makedirs(xdd, exist_ok=True)
return xdd return xdd
@ -577,7 +579,9 @@ def xonsh_data_dir(env):
@default_value @default_value
def xonsh_cache_dir(env): def xonsh_cache_dir(env):
"""Ensures and returns the $XONSH_CACHE_DIR""" """Ensures and returns the $XONSH_CACHE_DIR"""
xdd = os.path.expanduser(os.path.join(env.get("XDG_CACHE_HOME"), "xonsh")) xdd = os.path.expanduser(
os.getenv("XONSH_CACHE_DIR") or os.path.join(env.get("XDG_CACHE_HOME"), "xonsh")
)
os.makedirs(xdd, exist_ok=True) os.makedirs(xdd, exist_ok=True)
return xdd return xdd
@ -585,7 +589,10 @@ def xonsh_cache_dir(env):
@default_value @default_value
def xonsh_config_dir(env): def xonsh_config_dir(env):
"""``$XDG_CONFIG_HOME/xonsh``""" """``$XDG_CONFIG_HOME/xonsh``"""
xcd = os.path.expanduser(os.path.join(env.get("XDG_CONFIG_HOME"), "xonsh")) xcd = os.path.expanduser(
os.getenv("XONSH_CONFIG_DIR")
or os.path.join(env.get("XDG_CONFIG_HOME"), "xonsh")
)
os.makedirs(xcd, exist_ok=True) os.makedirs(xcd, exist_ok=True)
return xcd return xcd
@ -967,6 +974,17 @@ class GeneralSetting(Xettings):
"A list of directories where system level data files are stored.", "A list of directories where system level data files are stored.",
type_str="env_path", type_str="env_path",
) )
XONSH_CONFIG_DIR = Var.with_default(
xonsh_config_dir,
"This is the location where xonsh user-level configuration information is stored.",
type_str="str",
)
XONSH_SYS_CONFIG_DIR = Var.with_default(
xonsh_sys_config_dir,
"This is the location where xonsh system-level configuration information is stored.",
is_configurable=False,
type_str="str",
)
XONSHRC = Var.with_default( XONSHRC = Var.with_default(
default_xonshrc, default_xonshrc,
"A list of the locations of run control files, if they exist. User " "A list of the locations of run control files, if they exist. User "
@ -982,26 +1000,12 @@ class GeneralSetting(Xettings):
"are loaded after any files in XONSHRC.", "are loaded after any files in XONSHRC.",
type_str="env_path", type_str="env_path",
) )
XONSH_CONFIG_DIR = Var.with_default(
xonsh_config_dir,
"This is the location where xonsh user-level configuration information is stored.",
is_configurable=False,
type_str="str",
)
XONSH_SYS_CONFIG_DIR = Var.with_default(
xonsh_sys_config_dir,
"This is the location where xonsh system-level configuration information is stored.",
is_configurable=False,
type_str="str",
)
XONSH_COLOR_STYLE = Var.with_default( XONSH_COLOR_STYLE = Var.with_default(
"default", "default",
"Sets the color style for xonsh colors. This is a style name, not " "Sets the color style for xonsh colors. This is a style name, not "
"a color map. Run ``xonfig styles`` to see the available styles.", "a color map. Run ``xonfig styles`` to see the available styles.",
type_str="str", type_str="str",
) )
XONSH_DEBUG = Var( XONSH_DEBUG = Var(
always_false, always_false,
to_debug, to_debug,
@ -1019,7 +1023,6 @@ class GeneralSetting(Xettings):
doc_default="``$XDG_DATA_HOME/xonsh``", doc_default="``$XDG_DATA_HOME/xonsh``",
type_str="str", type_str="str",
) )
XONSH_ENCODING = Var.with_default( XONSH_ENCODING = Var.with_default(
DEFAULT_ENCODING, DEFAULT_ENCODING,
"This is the encoding that xonsh should use for subprocess operations.", "This is the encoding that xonsh should use for subprocess operations.",
@ -1048,7 +1051,6 @@ class GeneralSetting(Xettings):
"``True`` if xonsh is running as a login shell, and ``False`` otherwise.", "``True`` if xonsh is running as a login shell, and ``False`` otherwise.",
is_configurable=False, is_configurable=False,
) )
XONSH_MODE = Var.with_default( XONSH_MODE = Var.with_default(
default="interactive", # In sync with ``main.py``. default="interactive", # In sync with ``main.py``.
doc="A string value representing the current xonsh execution mode: " doc="A string value representing the current xonsh execution mode: "
@ -1058,7 +1060,6 @@ class GeneralSetting(Xettings):
"you plan to ``source``, use ``$XONSH_INTERACTIVE`` as the flag instead.", "you plan to ``source``, use ``$XONSH_INTERACTIVE`` as the flag instead.",
type_str="str", type_str="str",
) )
XONSH_SOURCE = Var.with_default( XONSH_SOURCE = Var.with_default(
"", "",
"When running a xonsh script, this variable contains the absolute path " "When running a xonsh script, this variable contains the absolute path "
@ -1082,7 +1083,6 @@ class GeneralSetting(Xettings):
" - ptk style name (string) - ``$XONSH_STYLE_OVERRIDES['pygments.keyword'] = '#ff0000'``\n\n" " - ptk style name (string) - ``$XONSH_STYLE_OVERRIDES['pygments.keyword'] = '#ff0000'``\n\n"
"(The rules above are all have the same effect.)", "(The rules above are all have the same effect.)",
) )
STAR_PATH = Var.no_default("env_path", pattern=re.compile(r"\w*PATH$")) STAR_PATH = Var.no_default("env_path", pattern=re.compile(r"\w*PATH$"))
STAR_DIRS = Var.no_default("env_path", pattern=re.compile(r"\w*DIRS$")) STAR_DIRS = Var.no_default("env_path", pattern=re.compile(r"\w*DIRS$"))