diff --git a/home/.chezmoidata/packages.yaml b/home/.chezmoidata/packages.yaml index ffe4da22..33887b70 100644 --- a/home/.chezmoidata/packages.yaml +++ b/home/.chezmoidata/packages.yaml @@ -126,6 +126,7 @@ packages: - twpayne.chezmoi full: - Fastfetch-cli.Fastfetch + - jdx.mise - Microsoft.VisualStudioCode - JanDeDobbeleer.OhMyPosh - Microsoft.WSL diff --git a/home/.chezmoiscripts/linux/run_onchange_10-install-packages.sh.tmpl b/home/.chezmoiscripts/linux/run_onchange_10-install-packages.sh.tmpl index efbfadef..8482db5d 100644 --- a/home/.chezmoiscripts/linux/run_onchange_10-install-packages.sh.tmpl +++ b/home/.chezmoiscripts/linux/run_onchange_10-install-packages.sh.tmpl @@ -26,11 +26,17 @@ brew_install_quiet() { return 0 fi log_step "Installing $pkg" - if output=$(brew install "$pkg" 2>&1); then + # Redirect brew output to a temp file rather than capturing it through a + # command-substitution pipe. Homebrew's concurrent output can raise + # "Error: Broken pipe" (SIGPIPE) when its stdout is a pipe rather than a + # TTY or regular file, which was breaking installs on WSL/Debian. + brew_log=$(mktemp) + trap 'rm -f "$brew_log"' RETURN + if brew install "$pkg" >"$brew_log" 2>&1; then log_result "Installed $pkg" else log_warn "Failed to install $pkg" - printf '%s\n' "$output" | log_data WARN "brew output" + log_data WARN "brew output" <"$brew_log" fi } @@ -43,11 +49,14 @@ brew_install_cask_quiet() { return 0 fi log_step "Installing $pkg (cask)" - if output=$(brew install --cask "$pkg" 2>&1); then + # See brew_install_quiet: redirect to a file to avoid SIGPIPE/"Broken pipe". + brew_log=$(mktemp) + trap 'rm -f "$brew_log"' RETURN + if brew install --cask "$pkg" >"$brew_log" 2>&1; then log_result "Installed $pkg (cask)" else log_warn "Failed to install $pkg (cask)" - printf '%s\n' "$output" | log_data WARN "brew output" + log_data WARN "brew output" <"$brew_log" fi } @@ -66,11 +75,14 @@ mas_install_quiet() { return 0 fi log_step "Installing $app_name ($app_id)" - if output=$(mas install "$app_id" 2>&1); then + # See brew_install_quiet: redirect to a file to avoid SIGPIPE/"Broken pipe". + mas_log=$(mktemp) + trap 'rm -f "$mas_log"' RETURN + if mas install "$app_id" >"$mas_log" 2>&1; then log_result "Installed $app_name ($app_id)" else log_warn "Failed to install $app_name ($app_id)" - printf '%s\n' "$output" | log_data WARN "mas output" + log_data WARN "mas output" <"$mas_log" fi } diff --git a/tests/bash/test-chezmoi-scripts.bats b/tests/bash/test-chezmoi-scripts.bats index e7ec4b5f..61340c1c 100644 --- a/tests/bash/test-chezmoi-scripts.bats +++ b/tests/bash/test-chezmoi-scripts.bats @@ -176,6 +176,14 @@ strip_template() { grep -q 'index .packages.darwin.brew "app-store"' "$script" } +@test "chezmoi-scripts: install-packages captures brew output via temp file (avoids broken pipe)" { + local script="$LINUX_SCRIPTS_DIR/run_onchange_10-install-packages.sh.tmpl" + # Output must be redirected to a file, not captured through a + # command-substitution pipe (which triggers Homebrew "Broken pipe" on WSL). + grep -q 'brew install "\$pkg" >"\$brew_log" 2>&1' "$script" + ! grep -q 'output=\$(brew install' "$script" +} + @test "chezmoi-scripts: install-packages references nested darwin brew formulas" { local script="$LINUX_SCRIPTS_DIR/run_onchange_10-install-packages.sh.tmpl" grep -q '\.packages\.darwin\.brew\.formulas\.' "$script"