diff --git a/README.md b/README.md index 3984183..d21c5c3 100644 --- a/README.md +++ b/README.md @@ -32,10 +32,10 @@ brew install mole ``` -**or by Script:** +**or by Script, for older macOS or latest code:** ```bash -# Append '-s latest' for latest code or '-s 1.17.0' for specific version +# Use for older macOS or latest code; add '-s latest' for newest, or '-s 1.17.0' for a fixed version. curl -fsSL https://raw.githubusercontent.com/tw93/mole/main/install.sh | bash ``` diff --git a/lib/clean/dev.sh b/lib/clean/dev.sh index f58be68..a72fb83 100644 --- a/lib/clean/dev.sh +++ b/lib/clean/dev.sh @@ -22,16 +22,18 @@ clean_dev_npm() { fi # Clean pnpm store cache local pnpm_default_store=~/Library/pnpm/store - if command -v pnpm > /dev/null 2>&1; then - clean_tool_cache "pnpm cache" pnpm store prune + # Check if pnpm is actually usable (not just Corepack shim) + if command -v pnpm > /dev/null 2>&1 && env COREPACK_ENABLE_DOWNLOAD_PROMPT=0 pnpm --version > /dev/null 2>&1; then + clean_tool_cache "pnpm cache" env COREPACK_ENABLE_DOWNLOAD_PROMPT=0 pnpm store prune local pnpm_store_path start_section_spinner "Checking store path..." - pnpm_store_path=$(run_with_timeout 2 pnpm store path 2> /dev/null) || pnpm_store_path="" + pnpm_store_path=$(run_with_timeout 2 env COREPACK_ENABLE_DOWNLOAD_PROMPT=0 pnpm store path 2> /dev/null) || pnpm_store_path="" stop_section_spinner if [[ -n "$pnpm_store_path" && "$pnpm_store_path" != "$pnpm_default_store" ]]; then safe_clean "$pnpm_default_store"/* "Orphaned pnpm store" fi else + # pnpm not installed or not usable, just clean the default store directory safe_clean "$pnpm_default_store"/* "pnpm store" fi note_activity diff --git a/lib/clean/project.sh b/lib/clean/project.sh index 4a99d6e..d0a1fb3 100644 --- a/lib/clean/project.sh +++ b/lib/clean/project.sh @@ -307,9 +307,14 @@ scan_purge_targets() { return fi if command -v fd > /dev/null 2>&1; then + # Escape regex special characters in target names for fd patterns + local escaped_targets=() + for target in "${PURGE_TARGETS[@]}"; do + escaped_targets+=("$(printf '%s' "$target" | sed -e 's/[][(){}.^$*+?|\\]/\\&/g')") + done local pattern="($( IFS='|' - echo "${PURGE_TARGETS[*]}" + echo "${escaped_targets[*]}" ))" local fd_args=( "--absolute-path" diff --git a/scripts/test.sh b/scripts/test.sh index 627b79e..d6eea56 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -50,14 +50,14 @@ if command -v bats > /dev/null 2>&1 && [ -d "tests" ]; then set -- tests fi if [[ -t 1 ]]; then - if bats -p "$@"; then + if bats -p "$@" | sed -e 's/^ok /OK /' -e 's/^not ok /FAIL /'; then printf "${GREEN}${ICON_SUCCESS} Unit tests passed${NC}\n" else printf "${RED}${ICON_ERROR} Unit tests failed${NC}\n" ((FAILED++)) fi else - if TERM="${TERM:-xterm-256color}" bats --tap "$@"; then + if TERM="${TERM:-xterm-256color}" bats --tap "$@" | sed -e 's/^ok /OK /' -e 's/^not ok /FAIL /'; then printf "${GREEN}${ICON_SUCCESS} Unit tests passed${NC}\n" else printf "${RED}${ICON_ERROR} Unit tests failed${NC}\n" diff --git a/tests/completion.bats b/tests/completion.bats index 5f131de..d586bcd 100755 --- a/tests/completion.bats +++ b/tests/completion.bats @@ -94,8 +94,8 @@ setup() { @test "completion zsh includes command descriptions" { run "$PROJECT_ROOT/bin/completion.sh" zsh [ "$status" -eq 0 ] - [[ "$output" == *"optimize:Free up disk space"* ]] - [[ "$output" == *"clean:Remove apps completely"* ]] + [[ "$output" == *"optimize:Check and maintain system"* ]] + [[ "$output" == *"clean:Free up disk space"* ]] } @test "completion fish generates valid fish script" { @@ -115,6 +115,7 @@ setup() { } @test "completion auto-install detects zsh" { + # shellcheck disable=SC2030,SC2031 export SHELL=/bin/zsh # Simulate auto-install (no interaction) @@ -131,8 +132,10 @@ setup() { } @test "completion auto-install detects already installed" { + # shellcheck disable=SC2031 export SHELL=/bin/zsh mkdir -p "$HOME" + # shellcheck disable=SC2016 echo 'eval "$(mole completion zsh)"' > "$HOME/.zshrc" run "$PROJECT_ROOT/bin/completion.sh"