From 9440d9e52a386cc5dfb8156b6e7f5d4bd597d939 Mon Sep 17 00:00:00 2001 From: tw93 Date: Sat, 21 Feb 2026 20:22:01 +0800 Subject: [PATCH] fix(dev): normalize npm cache paths and add maven function guard - Normalize npm cache paths with pwd -P to handle symlinks and trailing slashes, preventing duplicate scans of same directory - Add declare -f check before calling clean_maven_repository for robustness when dynamic source fails - Add test for trailing slash handling Addresses: dev.sh (line 27, 48, 602) --- lib/clean/dev.sh | 16 ++++++++++++++-- tests/clean_dev_caches.bats | 26 ++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/lib/clean/dev.sh b/lib/clean/dev.sh index c54127b..3cd9229 100644 --- a/lib/clean/dev.sh +++ b/lib/clean/dev.sh @@ -44,8 +44,18 @@ clean_dev_npm() { safe_clean "$npm_default_cache/${npm_residual_dirs[$i]}"/* "${npm_descriptions[$i]}" done + # Normalize paths for comparison (remove trailing slash + resolve symlinked dirs) + local npm_cache_path_normalized="${npm_cache_path%/}" + local npm_default_cache_normalized="${npm_default_cache%/}" + if [[ -d "$npm_cache_path_normalized" ]]; then + npm_cache_path_normalized=$(cd "$npm_cache_path_normalized" 2> /dev/null && pwd -P) || npm_cache_path_normalized="${npm_cache_path%/}" + fi + if [[ -d "$npm_default_cache_normalized" ]]; then + npm_default_cache_normalized=$(cd "$npm_default_cache_normalized" 2> /dev/null && pwd -P) || npm_default_cache_normalized="${npm_default_cache%/}" + fi + # Clean custom npm cache path (if different from default) - if [[ "$npm_cache_path" != "$npm_default_cache" ]]; then + if [[ "$npm_cache_path_normalized" != "$npm_default_cache_normalized" ]]; then for i in "${!npm_residual_dirs[@]}"; do safe_clean "$npm_cache_path/${npm_residual_dirs[$i]}"/* "${npm_descriptions[$i]} (custom path)" done @@ -600,7 +610,9 @@ clean_dev_jvm() { # Source Maven cleanup module (requires bash for BASH_SOURCE) # shellcheck disable=SC1091 source "$(dirname "${BASH_SOURCE[0]}")/maven.sh" 2> /dev/null || true - clean_maven_repository + if declare -f clean_maven_repository > /dev/null 2>&1; then + clean_maven_repository + fi safe_clean ~/.sbt/* "SBT cache" safe_clean ~/.ivy2/cache/* "Ivy cache" safe_clean ~/.gradle/caches/* "Gradle cache" diff --git a/tests/clean_dev_caches.bats b/tests/clean_dev_caches.bats index bbe3d6d..004ccd3 100644 --- a/tests/clean_dev_caches.bats +++ b/tests/clean_dev_caches.bats @@ -133,6 +133,32 @@ EOF [[ "$output" != *"(custom path)"* ]] } +@test "clean_dev_npm treats default cache path with trailing slash as same path" { + 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" != *"(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