-
Notifications
You must be signed in to change notification settings - Fork 0
Pipeline Design 1
shipwright init is the one-command bootstrap for new users. Prior to this change, the completions/ directory shipped three completion scripts (_shipwright for zsh, shipwright.bash, shipwright.fish) but nothing installed them during init. Users had to manually copy files and configure their shell rc files — a friction point that caused completions to go unused. The goal is to make tab completion work out-of-the-box as part of the standard setup flow.
Constraints from the codebase:
- All scripts must be Bash 3.2 compatible (
set -euo pipefail; nodeclare -A, noreadarray) -
sw-init.shruns in bash regardless of the user's login shell, so$BASH_VERSIONis always set —$SHELLis the only reliable signal for the user's actual shell - Init is designed to be idempotent (safe to run multiple times); rc file mutations must check before appending
- The test harness in
sw-init-test.shsandboxes$HOMEvia$TEMP_DIR/home— completion install logic must respect$HOMEto remain testable - The
completions/source directory is located relative to$REPO_DIR, not the install target path
Install completions as a discrete section in sw-init.sh immediately after the pipeline templates block (line 387), before the Claude Code settings block. Shell type is detected exclusively from $SHELL (with $ZSH_VERSION/$BASH_VERSION as last-resort fallbacks). Per-shell installation follows the XDG/conventional locations for each shell. All rc file mutations are guarded by grep -q idempotency checks. An unknown or unset shell silently warns and skips rather than failing init.
Data flow:
$SHELL env var
→ SHELL_TYPE (zsh|bash|fish|"")
→ copy completions/$SOURCE → $HOME/SHELL_SPECIFIC_PATH
→ grep -q guard → append to rc file if absent
→ print reload hint
Error handling:
-
$SHELLunset or unrecognized →warn+ skip (install_completionsstays 0) - Source file missing in
completions/→ silently skip that shell's block (inner[[ -f ]]guard) -
~/.zshrcabsent → create minimal file withfpath+compinitrather than failing
-
Detect shell via
ps/$PPID— Pros: works even when$SHELLis wrong. Cons: fragile on macOS (differentpsflags), adds subprocess overhead, Bash 3.2 incompatibility risk, harder to override in tests. Rejected in favor of$SHELL. -
System-wide completion install (e.g.,
/usr/local/share/zsh/site-functions/) — Pros: available to all users. Cons: requiressudo, not appropriate for a developer tool installer, breaks sandboxed test harness. Rejected; user-local paths are correct for this audience. -
Delegate to a separate
shipwright completions installsubcommand — Pros: composable, skippable. Cons: users must know to run a second command; defeats the "one-command setup" goal. Rejected; inline ininitis the right place. -
Overwrite rc files entirely — Pros: simpler code. Cons: destroys user customizations; catastrophic for idempotency. Rejected unconditionally.
-
Files to create: none (completion scripts already exist in
completions/) -
Files to modify:
-
scripts/sw-init.sh— Shell Completions section, lines 387–489 (already implemented on this branch) -
scripts/sw-init-test.sh— Tests 22–26 (already implemented on this branch)
-
- Dependencies: none (pure bash, no new external tools)
-
Risk areas:
-
rc file corruption under
pipefail: Thegrep -c || echo "0"anti-pattern (documented in CLAUDE.md) must not appear; current implementation usesgrep -q ... || { append; }which is safe -
$HOMEexpansion in rc lines: The bash completion source line uses$HOMEin a heredoc-style append — must be verified it resolves at write time, not at source time (current code uses literal$HOMEin the echo string, which will write the variable name, not the expanded path — this is a known edge case worth verifying) -
compinitplacement: Appendingcompinitafter user customizations in.zshrccan conflict if a user already loads it conditionally; the guardgrep -q "compinit"mitigates but cannot handle all cases -
Fish auto-discovery: Fish reads
~/.config/fish/completions/natively with no rc change needed — this is correctly leveraged; no rc mutation for fish
-
rc file corruption under
- Running
SHELL=/bin/zsh bash scripts/sw-init.shcreates~/.zsh/completions/_shipwrightand appendsfpath+=~/.zsh/completionsto~/.zshrcexactly once - Running
SHELL=/bin/bash bash scripts/sw-init.shcreates~/.local/share/bash-completion/completions/shipwright - Running
SHELL=/usr/local/bin/fish bash scripts/sw-init.shcreates~/.config/fish/completions/shipwright.fish - Running init twice with
SHELL=/bin/zshresults in exactly onefpathline in~/.zshrc(no duplicates) - Running init with
SHELL=""orSHELL=/bin/shexits 0 and prints awarnmessage, no completion files created - All 26 tests in
scripts/sw-init-test.shpass -
npm test(all 102 suites) passes with no regressions - The source line written to
~/.bashrcresolves$HOMEto the actual path at shell load time (not the literal string$HOME)