diff --git a/.claude/tasks/TODO.md b/.claude/tasks/TODO.md index 3981032..32b49df 100644 --- a/.claude/tasks/TODO.md +++ b/.claude/tasks/TODO.md @@ -114,3 +114,12 @@ Branch: feature/tmux-config (off develop, "met ca dans develop" = finish into de - [x] splits: prefix i (side by side) and prefix - (stacked), h/j/k/l kept - [x] Linux: deploy_tmux_config on both OSes (gated on tmux), clipboard if-shell (pbcopy else tmux buffer + OSC 52), XDG_CACHE_HOME in bashrc-linux - [x] Verified: shellcheck/bash -n, macOS test server, Ubuntu 24.04 container (tmux 3.4) full deploy + bindings + split + plugins + libtmux + +## Feature — identity asked at install, no hardcoded USER/EMAIL in tracked rc files (2026-10-06) +Branch: feature/identity-prompt (off develop). Values were visible to anyone reading the repo. +- [x] rc templates (bashrc-linux, bashrc-osx, zshrc-osx): `export USER="@USER@"` / `export EMAIL="@EMAIL@"` +- [x] install.sh resolve_identity: existing ~/.bashrc / ~/.zshrc export wins silently → IDENTITY_USER/IDENTITY_EMAIL env → prompt (TTY) → default (id -un, empty email) +- [x] install.sh: render_identity_template (generic, replaces render_gitconfig); bashrc + zshrc rendered, gitconfig unchanged (reads the rendered bashrc) +- [x] vim/vimrc: g:_author / g:_email from $USER / $EMAIL +- [x] README, CLAUDE.md (CHANGELOG left to the release step, like the tmux work) +- [x] Verify: shellcheck, bash -n, zsh -n; temp-HOME render (env preset, existing rc reuse); vim reads the env diff --git a/CLAUDE.md b/CLAUDE.md index 81e76d6..d584a64 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -20,7 +20,8 @@ install.sh one-shot installer (OS auto-detected) vim/vimrc vim config (pathogen, molokai, syntastic, NERDTree) vim/autoload/ pathogen loader (committed) vim/colors/ molokai colorscheme (committed) -bash/bashrc-{linux,osx} OS-detected bashrc (exports USER/EMAIL identity) +bash/bashrc-{linux,osx} OS-detected bashrc; USER/EMAIL identity = @USER@/@EMAIL@ placeholders, + asked at install (reused from an existing rc), never tracked gitconfig user-scope ~/.gitconfig template, @USER@/@EMAIL@ filled at install tmux.conf tmux config (vi keys, tpm plugins) → ~/.config/tmux/tmux.conf, both OSes (tmux ≥ 3.1) zsh/{zshrc-osx,bchanot.zsh-theme} macOS zsh option: oh-my-zsh zshrc + theme porting the bash prompt diff --git a/README.md b/README.md index a56a102..17dfe26 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ What it does: 3. Moves any existing `~/.vim`, `~/.vimrc`, `~/.bashrc`, `~/.Sublivim` to `~/Oldconfig`. 4. Clones the `syntastic` and `nerdtree` vim plugins into `~/.vim/bundle/`. 5. Copies the tracked vim files into `~/.vim` and symlinks `~/.vimrc`. -6. Picks the bashrc by OS: macOS → `bashrc-osx` (falls back to `bashrc-linux` if missing), everything else → `bashrc-linux`. Copies it to `~/.bashrc`. Then renders `gitconfig` into `~/.gitconfig` with that bashrc's `USER` / `EMAIL`. A different existing `~/.gitconfig` is saved as `~/.gitconfig.backup-`; an identical one is left alone. It is the global level only: a repo's own `.git/config` still overrides it. `core.excludesfile` points at `~/.gitignore`, ignored by git when the file does not exist. Then deploys `tmux.conf` to `~/.config/tmux/tmux.conf` (both OSes, tmux ≥ 3.1: Ubuntu 22.04+, brew), clones [tpm](https://github.com/tmux-plugins/tpm) and fetches the listed plugins headlessly; details under [macOS](#macos) step 6, the step is the same. On Linux, `y` copies into tmux's buffer and the terminal clipboard through OSC 52; macOS uses `pbcopy`/`pbpaste`. +6. Picks the bashrc by OS: macOS → `bashrc-osx` (falls back to `bashrc-linux` if missing), everything else → `bashrc-linux`. Renders it into `~/.bashrc` with the identity asked at the very start: a name and an email for git commits and vim headers. An `export USER=` / `export EMAIL=` already present in `~/.bashrc` or `~/.zshrc` is reused without asking, so a re-run never prompts twice; `IDENTITY_USER` / `IDENTITY_EMAIL` preset them; with no terminal attached it falls back to the login name and an empty email. The values live only in the deployed files, never in the repo. Then renders `gitconfig` into `~/.gitconfig` with the same `USER` / `EMAIL`. A different existing `~/.gitconfig` is saved as `~/.gitconfig.backup-`; an identical one is left alone. It is the global level only: a repo's own `.git/config` still overrides it. `core.excludesfile` points at `~/.gitignore`, ignored by git when the file does not exist. Then deploys `tmux.conf` to `~/.config/tmux/tmux.conf` (both OSes, tmux ≥ 3.1: Ubuntu 22.04+, brew), clones [tpm](https://github.com/tmux-plugins/tpm) and fetches the listed plugins headlessly; details under [macOS](#macos) step 6, the step is the same. On Linux, `y` copies into tmux's buffer and the terminal clipboard through OSC 52; macOS uses `pbcopy`/`pbpaste`. 7. Installs Python CLIs via `pipx` (`PyMuPDF` → `pymupdf`, `Markdown` → `markdown_py`) — skipped if `pipx` is absent. 8. Copies the `bin/` scripts (`dt`, `dtach-router`, `claude-provider`) into `~/.local/bin`. The dtach session-resume menu ships in the deployed bashrc (both OSes), so every interactive shell offers it — including VS Code Remote-SSH terminals, which are non-login and never read `~/.profile`. The installer also strips any older dtach block left in `~/.profile` so a plain SSH login doesn't prompt twice. 9. On Linux, installs `etc/profile.d/disk-usage-warning.sh` to `/etc/profile.d/` (needs `sudo`) so each login warns when `/` or `/home` cross 85% usage. @@ -107,7 +107,7 @@ The same `./install.sh` detects macOS and replaces `apt-get` with Homebrew. It f 5. Deploys `bashrc-osx`, then appends one line to `~/.bash_profile` that sources `~/.bashrc`: macOS terminals open login shells, which never read `~/.bashrc` on their own. Done for both choices, so `bash` stays usable. 6. Deploys `tmux.conf` to `~/.config/tmux/tmux.conf` (same step on Linux), clones [tpm](https://github.com/tmux-plugins/tpm) into `~/.config/tmux/plugins/tpm` and fetches the listed plugins headlessly (resurrect + continuum restore your sessions, window-name renames windows after what runs in them). A `~/.tmux.conf` would be read instead, so one found is moved to `~/.tmux.conf.backup-`; a differing `~/.config/tmux/tmux.conf` becomes `tmux.conf.backup-`. `libtmux` (needed by window-name) goes in the python user site; brew's python blocks that by default, so the install retries with `--break-system-packages`. Both plugin steps only warn on failure: `prefix` + `I` inside tmux fetches the plugins. Prefix is `C-a`. 7. **bash** chosen: makes brew's bash 5 the login shell (adds it to `/etc/shells` with `sudo`, then `chsh`, which asks for your password). macOS ships bash 3.2, too old for the bashrc. - **zsh** chosen: installs oh-my-zsh with its official script (unattended, skipped if `~/.oh-my-zsh` exists), deploys `zsh/zshrc-osx` to `~/.zshrc` and the `bchanot` theme to `~/.oh-my-zsh/custom/themes/`, then makes `/bin/zsh` the login shell. An existing `~/.zshrc` that differs from the repo's is saved as `~/.zshrc.backup-` (outside `~/Oldconfig`, which every run wipes). Move your machine-specific lines (nvm, bun, tokens) into `~/.zshrc.local`: the deployed zshrc loads it. + **zsh** chosen: installs oh-my-zsh with its official script (unattended, skipped if `~/.oh-my-zsh` exists), renders `zsh/zshrc-osx` into `~/.zshrc` (same identity as the bashrc) and deploys the `bchanot` theme to `~/.oh-my-zsh/custom/themes/`, then makes `/bin/zsh` the login shell. An existing `~/.zshrc` that differs from the repo's is saved as `~/.zshrc.backup-` (outside `~/Oldconfig`, which every run wipes). Move your machine-specific lines (nvm, bun, tokens) into `~/.zshrc.local`: the deployed zshrc loads it. 8. Ends with the list of what the Linux install has and this one does not: `gcc` (Apple clang answers to `gcc`), `valgrind`, `dkms`, `net-tools`, `openssh-server` and the RDP desktop (both built into macOS, switched on in System Settings > Sharing), `cifs-utils`, `php-imagick`, the NVIDIA driver, the disk-usage warning, `cloudpex`, the security baseline and the two end-of-install offers. ### CLI scripts (`bin/`) diff --git a/bash/bashrc-linux b/bash/bashrc-linux index 17c3da5..a49c6e9 100644 --- a/bash/bashrc-linux +++ b/bash/bashrc-linux @@ -28,9 +28,10 @@ fi #export LANG=en_US.UTF-8 -# Identity for the vim header; install.sh also writes it into ~/.gitconfig -export USER=bchanot -export EMAIL=bchanot@gmail.fr +# Identity for git commits and vim headers. Filled by install.sh (asked once, +# reused from an existing ~/.bashrc / ~/.zshrc on re-runs), never stored here. +export USER="@USER@" +export EMAIL="@EMAIL@" ## Activate and custom bash completion #bind 'TAB:menu-complete' diff --git a/bash/bashrc-osx b/bash/bashrc-osx index 6004dcc..21c85b1 100644 --- a/bash/bashrc-osx +++ b/bash/bashrc-osx @@ -38,9 +38,10 @@ fi #export LANG=en_US.UTF-8 -# Identity for the vim header; install.sh also writes it into ~/.gitconfig -export USER=bchanot -export EMAIL=bchanot@gmail.fr +# Identity for git commits and vim headers. Filled by install.sh (asked once, +# reused from an existing ~/.bashrc / ~/.zshrc on re-runs), never stored here. +export USER="@USER@" +export EMAIL="@EMAIL@" ## Activate and custom bash completion #bind 'TAB:menu-complete' diff --git a/install.sh b/install.sh index 2ada84c..da5e97b 100755 --- a/install.sh +++ b/install.sh @@ -6,6 +6,9 @@ set -euo pipefail # Resolve the repo root so the script works from any working directory. SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +# Helpers are defined below; the identity itself is resolved right before the +# OS-specific steps, so every prompt comes before the long package installs. + # Set up Docker's official Ubuntu apt repo, then install the engine + compose plugin. # Idempotent: skips entirely if docker is already on PATH. Ubuntu-only (uses the ubuntu repo). install_docker() { @@ -392,26 +395,28 @@ install_oh_my_zsh() { # ~/.zshrc.backup-, not in ~/Oldconfig: that dir is wiped on every run, so # a second run would destroy the original (and its nvm/bun lines). deploy_zsh_config() { + local name="$1" email="$2" rendered backup local themes="$HOME/.oh-my-zsh/custom/themes" - local backup backup="$HOME/.zshrc.backup-$(date +%Y%m%d-%H%M%S)" - if [ -e "$HOME/.zshrc" ] && ! cmp -s "$HOME/.zshrc" "$SCRIPT_DIR/zsh/zshrc-osx"; then + rendered="$(render_identity_template "$SCRIPT_DIR/zsh/zshrc-osx" "$name" "$email")" + if [ -e "$HOME/.zshrc" ] && ! printf '%s\n' "$rendered" | cmp -s - "$HOME/.zshrc"; then echo "Saving the current ~/.zshrc to $backup" mv "$HOME/.zshrc" "$backup" fi - echo "Deploying zsh/zshrc-osx + bchanot theme" - cp "$SCRIPT_DIR/zsh/zshrc-osx" "$HOME/.zshrc" + echo "Deploying zsh/zshrc-osx + bchanot theme ($name <$email>)" + printf '%s\n' "$rendered" > "$HOME/.zshrc" mkdir -p "$themes" cp "$SCRIPT_DIR/zsh/bchanot.zsh-theme" "$themes/" } -# The chosen macOS shell: zsh gets oh-my-zsh + its config; bash needs brew's -# bash 5 (macOS ships 3.2, too old for the bashrc). Either way it becomes the -# login shell, so new terminals load the matching config. +# The chosen macOS shell ($1): zsh gets oh-my-zsh + its config rendered with the +# identity ($2 name, $3 email); bash needs brew's bash 5 (macOS ships 3.2, too +# old for the bashrc). Either way it becomes the login shell, so new terminals +# load the matching config. setup_macos_shell() { if [ "$1" = zsh ]; then install_oh_my_zsh - deploy_zsh_config + deploy_zsh_config "$2" "$3" set_login_shell /bin/zsh else set_login_shell "$(brew --prefix)/bin/bash" @@ -486,15 +491,36 @@ rc_export_value() { sed -n "s/^export $1=//p" "$2" | tail -n 1 | tr -d "\"'" } -# Print the repo gitconfig template with @USER@ and @EMAIL@ replaced by $1 and -# $2. Bash substitution, so the values need no sed escaping. -render_gitconfig() { - local name="$1" email="$2" line +# Print the template $1 with @USER@ and @EMAIL@ replaced by $2 and $3. Bash +# substitution, so the values need no sed escaping. +render_identity_template() { + local file="$1" name="$2" email="$3" line while IFS= read -r line || [ -n "$line" ]; do line="${line//@USER@/$name}" line="${line//@EMAIL@/$email}" printf '%s\n' "$line" - done < "$SCRIPT_DIR/gitconfig" + done < "$file" +} + +# One identity value (USER or EMAIL, $1) for git commits, vim headers and the rc +# exports. Never stored in the repo. An export already in ~/.bashrc or ~/.zshrc +# wins silently (a re-run never asks twice), else IDENTITY_ from the +# environment, else a prompt ($2 label, $3 default) when a terminal is attached, +# else the default. Prints the value. +resolve_identity() { + local var="$1" label="$2" default="$3" value="" rc envvar="IDENTITY_$1" + for rc in "$HOME/.bashrc" "$HOME/.zshrc"; do + [ -f "$rc" ] && value="$(rc_export_value "$var" "$rc")" + if [ -n "$value" ] && [ "$value" != "@$var@" ]; then + printf '%s\n' "$value" + return 0 + fi + done + value="${!envvar:-}" + if [ -z "$value" ] && [ -t 0 ]; then + read -rp "$label [$default]: " value || true + fi + printf '%s\n' "${value:-$default}" } # Install the user-scope ~/.gitconfig (a repo's own .git/config still wins). @@ -510,7 +536,7 @@ deploy_gitconfig() { echo "USER/EMAIL not exported by $rc — skipping ~/.gitconfig" >&2 return 0 fi - rendered="$(render_gitconfig "$name" "$email")" + rendered="$(render_identity_template "$SCRIPT_DIR/gitconfig" "$name" "$email")" if printf '%s\n' "$rendered" | cmp -s - "$HOME/.gitconfig"; then echo "$HOME/.gitconfig already up to date — skipping" return 0 @@ -553,6 +579,11 @@ as brew services instead of systemd units. EOF } +# Identity for git, vim and the rc exports: reused from an existing rc, else asked. +identity_name="$(resolve_identity USER "Name for git commits and vim headers" "$(id -un)")" +identity_email="$(resolve_identity EMAIL "Email for git commits and vim headers" "")" +echo "Identity: $identity_name <${identity_email:-no email}>" + # System packages: apt-get on Debian/Ubuntu, Homebrew on macOS. if command -v apt-get >/dev/null 2>&1; then sudo apt-get update @@ -649,8 +680,8 @@ if [ "$(uname -s)" = "Darwin" ] && [ -f "$SCRIPT_DIR/bash/bashrc-osx" ]; then else bashrc="bash/bashrc-linux" fi -echo "Deploying $bashrc" -cp "$SCRIPT_DIR/$bashrc" "$HOME/.bashrc" +echo "Deploying $bashrc ($identity_name <$identity_email>)" +render_identity_template "$SCRIPT_DIR/$bashrc" "$identity_name" "$identity_email" > "$HOME/.bashrc" # User-scope git config, identity taken from the bashrc just deployed. deploy_gitconfig "$SCRIPT_DIR/$bashrc" @@ -691,7 +722,7 @@ fi # Linux install has that this one does not. if [ "$(uname -s)" = "Darwin" ]; then wire_bash_profile - setup_macos_shell "${macos_shell:-bash}" + setup_macos_shell "${macos_shell:-bash}" "$identity_name" "$identity_email" print_macos_gaps fi diff --git a/vim/vimrc b/vim/vimrc index e447159..65747a3 100644 --- a/vim/vimrc +++ b/vim/vimrc @@ -1,9 +1,9 @@ " Uset compatibility with Vii set nocompatible -" add user info variable -let g:_author = "Bastien Chanot" -let g:_email = "chanot.bastien@gmail.com" +" user info from the shell identity (USER / EMAIL exported by the deployed rc) +let g:_author = $USER +let g:_email = exists('$EMAIL') ? $EMAIL : '' " Enable pathogen for plugins execute pathogen#infect() diff --git a/zsh/zshrc-osx b/zsh/zshrc-osx index 24417d4..ae430c2 100644 --- a/zsh/zshrc-osx +++ b/zsh/zshrc-osx @@ -44,9 +44,10 @@ else SAVEHIST=10000000 fi -# Identity for the vim header; install.sh also writes it into ~/.gitconfig -export USER=bchanot -export EMAIL=bchanot@gmail.fr +# Identity for git commits and vim headers. Filled by install.sh (asked once, +# reused from an existing ~/.bashrc / ~/.zshrc on re-runs), never stored here. +export USER="@USER@" +export EMAIL="@EMAIL@" # claude-dans-dtach : creer une session (claude tournant dans dtach, detache via Ctrl-\). # Usage : cd ~/projets/seo && cc seo -> session nommee "seo".