1
0
mirror of https://github.com/tw93/Mole.git synced 2026-03-22 19:05:07 +00:00

fix(purge): detect artifacts when search path is project root

This commit is contained in:
tw93
2026-02-22 10:08:20 +08:00
parent ec3affe882
commit 894c81bb9a
2 changed files with 71 additions and 0 deletions

View File

@@ -226,6 +226,29 @@ load_purge_config() {
# Initialize paths on script load. # Initialize paths on script load.
load_purge_config load_purge_config
# Args: $1 - directory path
# Determine whether a directory is a project root.
# This is used to safely allow cleaning direct-child artifacts when
# users configure a single project directory as a purge search path.
is_purge_project_root() {
local dir="$1"
local indicator
for indicator in "${MONOREPO_INDICATORS[@]}"; do
if [[ -e "$dir/$indicator" ]]; then
return 0
fi
done
for indicator in "${PROJECT_INDICATORS[@]}"; do
if [[ -e "$dir/$indicator" ]]; then
return 0
fi
done
return 1
}
# Args: $1 - path to check # Args: $1 - path to check
# Safe cleanup requires the path be inside a project directory. # Safe cleanup requires the path be inside a project directory.
is_safe_project_artifact() { is_safe_project_artifact() {
@@ -234,10 +257,20 @@ is_safe_project_artifact() {
if [[ "$path" != /* ]]; then if [[ "$path" != /* ]]; then
return 1 return 1
fi fi
if [[ "$path" != "$search_path/"* ]]; then
return 1
fi
# Must not be a direct child of the search root. # Must not be a direct child of the search root.
local relative_path="${path#"$search_path"/}" local relative_path="${path#"$search_path"/}"
local depth=$(echo "$relative_path" | LC_ALL=C tr -cd '/' | wc -c) local depth=$(echo "$relative_path" | LC_ALL=C tr -cd '/' | wc -c)
if [[ $depth -lt 1 ]]; then if [[ $depth -lt 1 ]]; then
# Allow direct-child artifacts only when the search path is itself
# a project root (single-project mode).
if is_purge_project_root "$search_path"; then
return 0
fi
return 1 return 1
fi fi
return 0 return 0

View File

@@ -76,6 +76,22 @@ setup() {
[[ "$result" == "ALLOWED" ]] [[ "$result" == "ALLOWED" ]]
} }
@test "is_safe_project_artifact: allows direct child when search path is project root" {
mkdir -p "$HOME/single-project/node_modules"
touch "$HOME/single-project/package.json"
result=$(bash -c "
source '$PROJECT_ROOT/lib/clean/project.sh'
if is_safe_project_artifact '$HOME/single-project/node_modules' '$HOME/single-project'; then
echo 'ALLOWED'
else
echo 'BLOCKED'
fi
")
[[ "$result" == "ALLOWED" ]]
}
@test "filter_nested_artifacts: removes nested node_modules" { @test "filter_nested_artifacts: removes nested node_modules" {
mkdir -p "$HOME/www/project/node_modules/package/node_modules" mkdir -p "$HOME/www/project/node_modules/package/node_modules"
@@ -434,6 +450,28 @@ EOF
[[ "$result" == "SKIPPED" ]] [[ "$result" == "SKIPPED" ]]
} }
@test "scan_purge_targets: finds direct-child artifacts in project root with find mode" {
mkdir -p "$HOME/single-project/node_modules"
touch "$HOME/single-project/package.json"
local scan_output
scan_output="$(mktemp)"
result=$(bash -c "
source '$PROJECT_ROOT/lib/clean/project.sh'
MO_USE_FIND=1 scan_purge_targets '$HOME/single-project' '$scan_output'
if grep -q '$HOME/single-project/node_modules' '$scan_output'; then
echo 'FOUND'
else
echo 'MISSING'
fi
")
rm -f "$scan_output"
[[ "$result" == "FOUND" ]]
}
@test "is_recently_modified: detects recent projects" { @test "is_recently_modified: detects recent projects" {
mkdir -p "$HOME/www/project/node_modules" mkdir -p "$HOME/www/project/node_modules"
touch "$HOME/www/project/package.json" touch "$HOME/www/project/package.json"