diff --git a/config/bash/.bashrc b/config/bash/.bashrc index 80079c6..ccea4e8 100644 --- a/config/bash/.bashrc +++ b/config/bash/.bashrc @@ -5,11 +5,11 @@ export PANAMA_BASH="$PANAMA_PATH/config/bash" [ -f /etc/bashrc ] && . /etc/bashrc if [ -d ~/.bashrc.d ]; then - for rc in ~/.bashrc.d/*; do - if [ -f "$rc" ]; then - . "$rc" - fi - done + for rc in ~/.bashrc.d/*; do + if [ -f "$rc" ]; then + . "$rc" + fi + done unset rc fi @@ -18,26 +18,9 @@ if [ -d "$PANAMA_BASH" ]; then [ -f "$f" ] && . "$f" done unset f - - # Personal environment -- API keys, tokens -- lives OUTSIDE the checkout, - # where agents, backup tools and `panama update` walk, and is kept - # owner-only every time it is read: a secrets file that drifts to 644 is - # quietly re-tightened rather than trusted. (config/bash/env, its old home - # inside the repo, is still sourced by the glob above if a machine has not - # been migrated yet.) - PANAMA_ENV="${XDG_CONFIG_HOME:-$HOME/.config}/panama/env" - if [ -f "$PANAMA_ENV" ]; then - [ "$(stat -c %a "$PANAMA_ENV" 2>/dev/null)" = "600" ] || chmod 600 "$PANAMA_ENV" - . "$PANAMA_ENV" - fi - unset PANAMA_ENV else if ! [[ "$PATH" =~ "$HOME/.local/bin:$HOME/bin:" ]]; then PATH="$HOME/.local/bin:$HOME/bin:$PATH" fi export PATH fi -# rustup writes this file, and initial-packages installs rustup rather than -# running rustup-init -- so on a fresh machine it does not exist yet and an -# unguarded source made every single shell start with an error. -[ -f "$HOME/.cargo/env" ] && . "$HOME/.cargo/env" diff --git a/config/bash/shell b/config/bash/shell index 9911705..e12876a 100644 --- a/config/bash/shell +++ b/config/bash/shell @@ -1,5 +1,18 @@ #!/usr/bin/env bash +# Personal environment -- API keys, tokens -- lives OUTSIDE the checkout, +# where agents, backup tools and `panama update` walk, and is kept owner-only +# every time it is read: a secrets file that drifts to 644 is quietly +# re-tightened rather than trusted. Sourced first, because settings below +# (PANAMA_SSH_TMUX) read it. (config/bash/env, its old home inside the repo, +# is still sourced by .bashrc's glob if a machine has not been migrated yet.) +PANAMA_ENV="${XDG_CONFIG_HOME:-$HOME/.config}/panama/env" +if [ -f "$PANAMA_ENV" ]; then + [ "$(stat -c %a "$PANAMA_ENV" 2>/dev/null)" = "600" ] || chmod 600 "$PANAMA_ENV" + . "$PANAMA_ENV" +fi +unset PANAMA_ENV + # Editor used by CLI export EDITOR="nvim" export SUDO_EDITOR="$EDITOR" @@ -22,6 +35,11 @@ export DOTNETPATH="$HOME/.dotnet/tools" # Set complete path export PATH="$HOME/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PANAMA_PATH/bin:$BUN_INSTALL/bin:$CARGO_PATH/bin:$PNPM_HOME/bin:$PYENV_ROOT/bin:$HOME/.rbenv/bin:/usr/lib/ccache/bin/:$GOPATH/bin:$DOTNETPATH" +# rustup writes this file, and initial-packages installs rustup rather than +# running rustup-init -- so on a fresh machine it does not exist yet and an +# unguarded source made every single shell start with an error. +[ -f "$HOME/.cargo/env" ] && . "$HOME/.cargo/env" + # Nvm. Guarded because the file belongs to the nvm package: before that is # installed it does not exist, and an unconditional source means every shell on # a fresh machine opens with an error. @@ -42,8 +60,8 @@ export PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND; }_nvm_auto_use" # work is the point), but guarded: it must not replace the shell of someone # whose machine lacks tmux, and PANAMA_SSH_TMUX=off turns it off for people # who want a plain shell -- set it in ~/.config/panama/env. -if [[ -n "$SSH_CONNECTION" && -z "$TMUX" && $- == *i* \ - && "${PANAMA_SSH_TMUX:-on}" != "off" ]] && command -v tmux >/dev/null 2>&1; then +if [[ -n "$SSH_CONNECTION" && -z "$TMUX" && $- == *i* && + "${PANAMA_SSH_TMUX:-on}" != "off" ]] && command -v tmux >/dev/null 2>&1; then exec tmux new-session -A -s main fi diff --git a/config/dot/quickshell/scripts/panama-home-assistant b/config/dot/quickshell/scripts/panama-home-assistant index fb24ecd..f8ef0c9 100755 --- a/config/dot/quickshell/scripts/panama-home-assistant +++ b/config/dot/quickshell/scripts/panama-home-assistant @@ -44,7 +44,12 @@ GNOME_EXTENSION = ( ) GNOME_SCHEMA_DIR = GNOME_EXTENSION / "schemas" GNOME_SCHEMA = "org.gnome.shell.extensions.hass-data" -PANAMA_ENV = pathlib.Path(__file__).resolve().parents[3] / "bash/env" +# The migrated personal env (outside the checkout) wins; the in-repo file is +# only read on machines that have not migrated. See panama-home-assistant-config. +LEGACY_ENV = pathlib.Path(__file__).resolve().parents[3] / "bash/env" +_config_home = pathlib.Path(os.environ.get("XDG_CONFIG_HOME", str(pathlib.Path.home() / ".config"))) +_migrated_env = _config_home / "panama" / "env" +PANAMA_ENV = _migrated_env if _migrated_env.exists() else LEGACY_ENV Runner = Callable[..., subprocess.CompletedProcess[str]] diff --git a/config/dot/quickshell/scripts/panama-home-assistant-config b/config/dot/quickshell/scripts/panama-home-assistant-config index 08cb383..7044a3d 100755 --- a/config/dot/quickshell/scripts/panama-home-assistant-config +++ b/config/dot/quickshell/scripts/panama-home-assistant-config @@ -29,7 +29,20 @@ ASSIGNMENT = re.compile( r"^(?P\s*(?:export\s+)?)(?P[A-Za-z_][A-Za-z0-9_]*)\s*=(?P.*)$" ) ENTITY_ID = re.compile(r"^[a-z_]+\.[a-z0-9_]+$") -DEFAULT_ENV = pathlib.Path(__file__).resolve().parents[3] / "bash/env" +# Personal environment lives OUTSIDE the checkout (~/.config/panama/env), +# where agents, backup tools and `panama update` never walk. The in-repo +# config/bash/env is only the legacy location for unmigrated machines — and +# writing there once rebuilt a file the owner thought was hand-maintained. +LEGACY_ENV = pathlib.Path(__file__).resolve().parents[3] / "bash/env" + + +def default_env() -> pathlib.Path: + config_home = pathlib.Path( + os.environ.get("XDG_CONFIG_HOME", str(pathlib.Path.home() / ".config"))) + migrated = config_home / "panama" / "env" + if migrated.exists() or not LEGACY_ENV.exists(): + return migrated + return LEGACY_ENV class ConfigError(RuntimeError): @@ -38,7 +51,7 @@ class ConfigError(RuntimeError): def env_path() -> pathlib.Path: override = os.environ.get("PANAMA_HOME_ASSISTANT_ENV_FILE", "") - return pathlib.Path(override) if override else DEFAULT_ENV + return pathlib.Path(override) if override else default_env() def parse_assignment(raw: str) -> str | None: