From 172742b0d5bafcf8e6b7d76b5a662d1eecd36e92 Mon Sep 17 00:00:00 2001 From: tw93 Date: Sun, 1 Mar 2026 19:56:33 +0800 Subject: [PATCH] fix(version): avoid SIGPIPE in Homebrew install detection Cache Homebrew formula output and use shell string matching to prevent pipefail SIGPIPE races that could misreport script installs as manual. Closes #513. --- mole | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/mole b/mole index de0063a..d6db5ea 100755 --- a/mole +++ b/mole @@ -38,14 +38,26 @@ get_latest_version_from_github() { } # Install detection (Homebrew vs manual). +# Uses variable capture + string matching to avoid SIGPIPE under pipefail. is_homebrew_install() { - local mole_path + local mole_path link_target brew_list="" has_brew=false mole_path=$(command -v mole 2> /dev/null) || return 1 - if [[ -L "$mole_path" ]] && readlink "$mole_path" | grep -q "Cellar/mole"; then - if command -v brew > /dev/null 2>&1; then - brew list --formula 2> /dev/null | grep -q "^mole$" && return 0 - else + # Cache brew list once if brew is available + if command -v brew > /dev/null 2>&1; then + has_brew=true + brew_list=$(brew list --formula 2> /dev/null) || true + fi + + # Helper to check if mole is in brew list + _mole_in_brew_list() { + [[ -n "$brew_list" ]] && [[ $'\n'"$brew_list"$'\n' == *$'\n'"mole"$'\n'* ]] + } + + if [[ -L "$mole_path" ]]; then + link_target=$(readlink "$mole_path" 2> /dev/null) || true + if [[ "$link_target" == *"Cellar/mole"* ]]; then + $has_brew && _mole_in_brew_list && return 0 return 1 fi fi @@ -54,8 +66,8 @@ is_homebrew_install() { case "$mole_path" in /opt/homebrew/bin/mole | /usr/local/bin/mole) if [[ -d /opt/homebrew/Cellar/mole ]] || [[ -d /usr/local/Cellar/mole ]]; then - if command -v brew > /dev/null 2>&1; then - brew list --formula 2> /dev/null | grep -q "^mole$" && return 0 + if $has_brew; then + _mole_in_brew_list && return 0 else return 0 # Cellar exists, probably Homebrew install fi @@ -64,11 +76,11 @@ is_homebrew_install() { esac fi - if command -v brew > /dev/null 2>&1; then + if $has_brew; then local brew_prefix brew_prefix=$(brew --prefix 2> /dev/null) if [[ -n "$brew_prefix" && "$mole_path" == "$brew_prefix/bin/mole" && -d "$brew_prefix/Cellar/mole" ]]; then - brew list --formula 2> /dev/null | grep -q "^mole$" && return 0 + _mole_in_brew_list && return 0 fi fi