Source code for uv_start.config

"""User configuration management for uv-start.

Provides a fallback chain for author info: config file -> git config -> defaults.
Config is stored at ~/.config/uv-start/config.toml.
"""

import os
import subprocess
import tomllib
from dataclasses import dataclass
from pathlib import Path

from rich import print as rprint
from rich.panel import Panel

CONFIG_DIR = Path.home() / ".config" / "uv-start"
CONFIG_FILE = CONFIG_DIR / "config.toml"


_ENV_ALLOWLIST = {
    "PATH",
    "HOME",
    "USER",
    "LOGNAME",
    "SHELL",
    "LANG",
    "LC_ALL",
    "LC_CTYPE",
    "TMPDIR",
    "TEMP",
    "TMP",
    "XDG_CACHE_HOME",
    "XDG_CONFIG_HOME",
    "XDG_DATA_HOME",
    "USERPROFILE",  # Windows
    "APPDATA",  # Windows
    "SYSTEMROOT",  # Windows
}


[docs] def clean_env() -> dict[str, str]: """Return a minimal environment safe for uv/git subprocesses. Only passes through variables needed for process execution, explicitly excluding secrets and tokens that may be exported in the shell session. """ return {k: v for k, v in os.environ.items() if k in _ENV_ALLOWLIST}
[docs] @dataclass class UserConfig: """User configuration for project scaffolding.""" author_name: str author_email: str
[docs] def load_config() -> UserConfig: """Load user config with fallback chain: config file -> git -> defaults.""" # 1. Try config file if CONFIG_FILE.exists(): with CONFIG_FILE.open("rb") as f: data = tomllib.load(f) user = data.get("user", {}) name = user.get("name") email = user.get("email") if name and email: return UserConfig(author_name=name, author_email=email) # 2. Try git config name = _git_config("user.name") email = _git_config("user.email") if name and email: return UserConfig(author_name=name, author_email=email) # 3. Defaults return UserConfig( author_name=name or "Unknown", author_email=email or "unknown@example.com", )
def _git_config(key: str) -> str | None: """Read a value from git global config.""" try: result = subprocess.run( ["git", "config", "--global", key], capture_output=True, text=True, check=False, ) value = result.stdout.strip() return value if value else None except FileNotFoundError: return None
[docs] def save_config(name: str, email: str) -> None: """Write user config to ~/.config/uv-start/config.toml.""" CONFIG_DIR.mkdir(parents=True, exist_ok=True) content = f'[user]\nname = "{name}"\nemail = "{email}"\n' CONFIG_FILE.write_text(content) rprint( Panel( f"[green]Configuration saved:[/green]\n" f" Name: {name}\n" f" Email: {email}\n\n" f" Stored in: {CONFIG_FILE}", title="uv-start Config", border_style="green", ) )