Source code for xonsh.webconfig.file_writes
"""functions to update rc files"""
import os
import re
import typing as tp
from xonsh.environ import get_home_xonshrc_path
[docs]
def write_value(value: str, _) -> str:
return f"{value!r}"
[docs]
def append_to_list(value: list[str], existing: str) -> str:
vals = set(existing.split(" ")) if existing else set()
vals.update(value)
return " ".join(vals)
RENDERERS: dict[str, tuple[str, tp.Callable[[tp.Any, str], str]]] = {
"$PROMPT = ": ("prompt", write_value),
"$XONSH_COLOR_STYLE = ": ("color", write_value),
"xontrib load ": ("xontribs", append_to_list),
}
[docs]
def config_to_xonsh(
config: dict,
prefix="# XONSH WEBCONFIG START",
current_lines: "tp.Iterable[str]" = (),
suffix="# XONSH WEBCONFIG END",
):
"""Turns config dict into xonsh code (str)."""
yield prefix
renderers = set(RENDERERS)
for existing in current_lines:
if start := next(filter(lambda x: existing.startswith(x), renderers), None):
renderers.remove(start)
key, func = RENDERERS[start]
if value := config.get(key):
yield start + func(value, existing[len(start) :])
else:
yield existing
else:
yield existing
for start in renderers:
key, func = RENDERERS[start]
if value := config.get(key):
yield start + func(value, "")
yield suffix
RC_FILE = get_home_xonshrc_path()
[docs]
def insert_into_xonshrc(
config: dict,
xonshrc=None,
prefix="# XONSH WEBCONFIG START",
suffix="# XONSH WEBCONFIG END",
):
"""Places a config dict into the xonshrc."""
if xonshrc is None:
xonshrc = RC_FILE
current_lines = []
# get current contents
fname = os.path.expanduser(xonshrc)
if os.path.isfile(fname):
with open(fname) as f:
s = f.read()
before, _, s = s.partition(prefix)
current, _, after = s.partition(suffix)
current_lines = current.strip().splitlines(keepends=False)
else:
before = after = ""
dname = os.path.dirname(fname)
if dname:
os.makedirs(dname, exist_ok=True)
# compute new values
lines = config_to_xonsh(
config,
prefix=prefix,
current_lines=current_lines,
suffix=suffix,
)
# write out the file
with open(fname, "w", encoding="utf-8") as f:
f.write(before + re.sub(r"\r", "", "\n".join(lines)) + after)
return fname