From ab83bd1ed91e0305339068414529ce77b97893c4 Mon Sep 17 00:00:00 2001 From: Michael Aristarco <75532968+mickyyy68@users.noreply.github.com> Date: Mon, 16 Feb 2026 08:40:13 +0100 Subject: [PATCH 1/2] fix: deep clean npm residual caches (#457) Fixes #454 --- lib/clean/dev.sh | 25 +++++++++++ tests/clean_dev_caches.bats | 83 +++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/lib/clean/dev.sh b/lib/clean/dev.sh index 3ea2a68..8ea47d6 100644 --- a/lib/clean/dev.sh +++ b/lib/clean/dev.sh @@ -17,10 +17,35 @@ clean_tool_cache() { } # npm/pnpm/yarn/bun caches. clean_dev_npm() { + local npm_default_cache="$HOME/.npm" + local npm_cache_path="$npm_default_cache" + if command -v npm > /dev/null 2>&1; then clean_tool_cache "npm cache" npm cache clean --force + + start_section_spinner "Checking npm cache path..." + npm_cache_path=$(run_with_timeout 2 npm config get cache 2> /dev/null) || npm_cache_path="" + stop_section_spinner + + if [[ -z "$npm_cache_path" || "$npm_cache_path" != /* ]]; then + npm_cache_path="$npm_default_cache" + fi + note_activity fi + + safe_clean "$npm_default_cache"/_cacache/* "npm cache directory" + safe_clean "$npm_default_cache"/_npx/* "npm npx cache" + safe_clean "$npm_default_cache"/_logs/* "npm logs" + safe_clean "$npm_default_cache"/_prebuilds/* "npm prebuilds" + + if [[ "$npm_cache_path" != "$npm_default_cache" ]]; then + safe_clean "$npm_cache_path"/_cacache/* "npm cache directory (custom path)" + safe_clean "$npm_cache_path"/_npx/* "npm npx cache (custom path)" + safe_clean "$npm_cache_path"/_logs/* "npm logs (custom path)" + safe_clean "$npm_cache_path"/_prebuilds/* "npm prebuilds (custom path)" + fi + # Clean pnpm store cache local pnpm_default_store=~/Library/pnpm/store # Check if pnpm is actually usable (not just Corepack shim) diff --git a/tests/clean_dev_caches.bats b/tests/clean_dev_caches.bats index c15ede5..bbe3d6d 100644 --- a/tests/clean_dev_caches.bats +++ b/tests/clean_dev_caches.bats @@ -50,6 +50,89 @@ EOF [[ "$output" == *"Orphaned pnpm store"* ]] } +@test "clean_dev_npm cleans default npm residual directories" { + run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF' +set -euo pipefail +source "$PROJECT_ROOT/lib/core/common.sh" +source "$PROJECT_ROOT/lib/clean/dev.sh" +start_section_spinner() { :; } +stop_section_spinner() { :; } +clean_tool_cache() { :; } +safe_clean() { echo "$2|$1"; } +note_activity() { :; } +run_with_timeout() { shift; "$@"; } +npm() { + if [[ "$1" == "config" && "$2" == "get" && "$3" == "cache" ]]; then + echo "$HOME/.npm" + return 0 + fi + return 0 +} +clean_dev_npm +EOF + + [ "$status" -eq 0 ] + [[ "$output" == *"npm cache directory|$HOME/.npm/_cacache/*"* ]] + [[ "$output" == *"npm npx cache|$HOME/.npm/_npx/*"* ]] + [[ "$output" == *"npm logs|$HOME/.npm/_logs/*"* ]] + [[ "$output" == *"npm prebuilds|$HOME/.npm/_prebuilds/*"* ]] +} + +@test "clean_dev_npm cleans custom npm cache path when detected" { + run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF' +set -euo pipefail +source "$PROJECT_ROOT/lib/core/common.sh" +source "$PROJECT_ROOT/lib/clean/dev.sh" +start_section_spinner() { :; } +stop_section_spinner() { :; } +clean_tool_cache() { :; } +safe_clean() { echo "$2|$1"; } +note_activity() { :; } +run_with_timeout() { shift; "$@"; } +npm() { + if [[ "$1" == "config" && "$2" == "get" && "$3" == "cache" ]]; then + echo "/tmp/mole-custom-npm-cache" + return 0 + fi + return 0 +} +clean_dev_npm +EOF + + [ "$status" -eq 0 ] + [[ "$output" == *"npm cache directory|$HOME/.npm/_cacache/*"* ]] + [[ "$output" == *"npm cache directory (custom path)|/tmp/mole-custom-npm-cache/_cacache/*"* ]] + [[ "$output" == *"npm npx cache (custom path)|/tmp/mole-custom-npm-cache/_npx/*"* ]] + [[ "$output" == *"npm logs (custom path)|/tmp/mole-custom-npm-cache/_logs/*"* ]] + [[ "$output" == *"npm prebuilds (custom path)|/tmp/mole-custom-npm-cache/_prebuilds/*"* ]] +} + +@test "clean_dev_npm falls back to default cache when npm path is invalid" { + run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF' +set -euo pipefail +source "$PROJECT_ROOT/lib/core/common.sh" +source "$PROJECT_ROOT/lib/clean/dev.sh" +start_section_spinner() { :; } +stop_section_spinner() { :; } +clean_tool_cache() { :; } +safe_clean() { echo "$2|$1"; } +note_activity() { :; } +run_with_timeout() { shift; "$@"; } +npm() { + if [[ "$1" == "config" && "$2" == "get" && "$3" == "cache" ]]; then + echo "relative-cache" + return 0 + fi + return 0 +} +clean_dev_npm +EOF + + [ "$status" -eq 0 ] + [[ "$output" == *"npm cache directory|$HOME/.npm/_cacache/*"* ]] + [[ "$output" != *"(custom path)"* ]] +} + @test "clean_dev_docker skips when daemon not running" { run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" MO_DEBUG=1 DRY_RUN=false bash --noprofile --norc <<'EOF' set -euo pipefail From 43d9bb237ac0993639f6bf28a120b361a2fcf3fb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 16 Feb 2026 07:40:31 +0000 Subject: [PATCH 2/2] chore: update contributors [skip ci] --- CONTRIBUTORS.svg | 69 ++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/CONTRIBUTORS.svg b/CONTRIBUTORS.svg index f5a5111..7d242b0 100644 --- a/CONTRIBUTORS.svg +++ b/CONTRIBUTORS.svg @@ -1,5 +1,5 @@ - - + + @@ -167,6 +167,17 @@ + + + + + + + + andmev + + + @@ -177,7 +188,7 @@ ndbroadbent - + @@ -188,7 +199,7 @@ ppauel - + @@ -199,7 +210,7 @@ shakeelmohamed - + @@ -210,7 +221,7 @@ Sizk - + @@ -221,7 +232,7 @@ thijsvanhal - + @@ -232,7 +243,7 @@ TomP0 - + @@ -243,7 +254,7 @@ yuzeguitarist - + @@ -254,7 +265,7 @@ zeldrisho - + @@ -265,7 +276,7 @@ bikraj2 - + @@ -276,7 +287,7 @@ bunizao - + @@ -287,7 +298,7 @@ rans0 - + @@ -298,7 +309,7 @@ frozturk - + @@ -309,7 +320,7 @@ huyixi - + @@ -320,7 +331,7 @@ purofle - + @@ -331,7 +342,7 @@ yamamel - + @@ -342,17 +353,6 @@ NanmiCoder - - - - - - - - - andmev - - @@ -508,6 +508,17 @@ + + + + + + + + mickyyy68 + + + @@ -518,7 +529,7 @@ EastSun5566 - +