1
0
mirror of https://github.com/tw93/Mole.git synced 2026-02-16 16:25:17 +00:00

Parallel scanning and testing

This commit is contained in:
Tw93
2025-12-11 19:24:23 +08:00
parent d5f36e1e9a
commit 2d7932025f
4 changed files with 62 additions and 78 deletions

View File

@@ -126,15 +126,18 @@ clean_service_worker_cache() {
# Clean Next.js (.next/cache) and Python (__pycache__) build caches # Clean Next.js (.next/cache) and Python (__pycache__) build caches
# Uses maxdepth 3, excludes Library/.Trash/node_modules, 10s timeout per scan # Uses maxdepth 3, excludes Library/.Trash/node_modules, 10s timeout per scan
clean_project_caches() { clean_project_caches() {
# Clean Next.js caches
if [[ -t 1 ]]; then if [[ -t 1 ]]; then
MOLE_SPINNER_PREFIX=" " MOLE_SPINNER_PREFIX=" "
start_inline_spinner "Searching Next.js caches..." start_inline_spinner "Searching project caches..."
fi fi
# Use timeout to prevent hanging on problematic directories
local nextjs_tmp_file local nextjs_tmp_file
nextjs_tmp_file=$(create_temp_file) nextjs_tmp_file=$(create_temp_file)
local pycache_tmp_file
pycache_tmp_file=$(create_temp_file)
local find_timeout=10
# 1. Start Next.js search
( (
command find "$HOME" -P -mount -type d -name ".next" -maxdepth 3 \ command find "$HOME" -P -mount -type d -name ".next" -maxdepth 3 \
-not -path "*/Library/*" \ -not -path "*/Library/*" \
@@ -143,42 +146,9 @@ clean_project_caches() {
-not -path "*/.*" \ -not -path "*/.*" \
2> /dev/null || true 2> /dev/null || true
) > "$nextjs_tmp_file" 2>&1 & ) > "$nextjs_tmp_file" 2>&1 &
local find_pid=$! local next_pid=$!
local find_timeout=10
local elapsed=0
# Wait for find to complete or timeout # 2. Start Python search
while kill -0 $find_pid 2> /dev/null && [[ $elapsed -lt $find_timeout ]]; do
sleep 1
((elapsed++))
done
# Kill if still running after timeout
if kill -0 $find_pid 2> /dev/null; then
kill -TERM $find_pid 2> /dev/null || true
wait $find_pid 2> /dev/null || true
else
wait $find_pid 2> /dev/null || true
fi
# Clean found Next.js caches
while IFS= read -r next_dir; do
[[ -d "$next_dir/cache" ]] && safe_clean "$next_dir/cache"/* "Next.js build cache" || true
done < "$nextjs_tmp_file"
if [[ -t 1 ]]; then
stop_inline_spinner
fi
# Clean Python bytecode caches
if [[ -t 1 ]]; then
MOLE_SPINNER_PREFIX=" "
start_inline_spinner "Searching Python caches..."
fi
# Use timeout to prevent hanging on problematic directories
local pycache_tmp_file
pycache_tmp_file=$(create_temp_file)
( (
command find "$HOME" -P -mount -type d -name "__pycache__" -maxdepth 3 \ command find "$HOME" -P -mount -type d -name "__pycache__" -maxdepth 3 \
-not -path "*/Library/*" \ -not -path "*/Library/*" \
@@ -187,32 +157,41 @@ clean_project_caches() {
-not -path "*/.*" \ -not -path "*/.*" \
2> /dev/null || true 2> /dev/null || true
) > "$pycache_tmp_file" 2>&1 & ) > "$pycache_tmp_file" 2>&1 &
local find_pid=$! local py_pid=$!
local find_timeout=10
local elapsed=0
# Wait for find to complete or timeout # 3. Wait for both with timeout
while kill -0 $find_pid 2> /dev/null && [[ $elapsed -lt $find_timeout ]]; do local elapsed=0
while [[ $elapsed -lt $find_timeout ]]; do
if ! kill -0 $next_pid 2> /dev/null && ! kill -0 $py_pid 2> /dev/null; then
break
fi
sleep 1 sleep 1
((elapsed++)) ((elapsed++))
done done
# Kill if still running after timeout # 4. Clean up any stuck processes
if kill -0 $find_pid 2> /dev/null; then for pid in $next_pid $py_pid; do
kill -TERM $find_pid 2> /dev/null || true if kill -0 "$pid" 2> /dev/null; then
wait $find_pid 2> /dev/null || true kill -TERM "$pid" 2> /dev/null || true
wait "$pid" 2> /dev/null || true
else else
wait $find_pid 2> /dev/null || true wait "$pid" 2> /dev/null || true
fi fi
done
# Clean found Python caches
while IFS= read -r pycache; do
[[ -d "$pycache" ]] && safe_clean "$pycache"/* "Python bytecode cache" || true
done < "$pycache_tmp_file"
if [[ -t 1 ]]; then if [[ -t 1 ]]; then
stop_inline_spinner stop_inline_spinner
fi fi
# 5. Process Next.js results
while IFS= read -r next_dir; do
[[ -d "$next_dir/cache" ]] && safe_clean "$next_dir/cache"/* "Next.js build cache" || true
done < "$nextjs_tmp_file"
# 6. Process Python results
while IFS= read -r pycache; do
[[ -d "$pycache" ]] && safe_clean "$pycache"/* "Python bytecode cache" || true
done < "$pycache_tmp_file"
} }
# Clean Spotlight user caches # Clean Spotlight user caches

View File

@@ -10,7 +10,7 @@ clean_user_essentials() {
safe_clean ~/.Trash/* "Trash" safe_clean ~/.Trash/* "Trash"
# Empty trash on mounted volumes # Empty trash on mounted volumes
if [[ -d "/Volumes" ]]; then if [[ -d "/Volumes" && "$DRY_RUN" != "true" ]]; then
for volume in /Volumes/*; do for volume in /Volumes/*; do
[[ -d "$volume" && -d "$volume/.Trashes" && -w "$volume" ]] || continue [[ -d "$volume" && -d "$volume/.Trashes" && -w "$volume" ]] || continue
@@ -23,7 +23,6 @@ clean_user_essentials() {
# Verify volume is mounted and not a symlink # Verify volume is mounted and not a symlink
mount | grep -q "on $volume " || continue mount | grep -q "on $volume " || continue
[[ -L "$volume/.Trashes" ]] && continue [[ -L "$volume/.Trashes" ]] && continue
[[ "$DRY_RUN" == "true" ]] && continue
# Safely iterate and remove each item # Safely iterate and remove each item
while IFS= read -r -d '' item; do while IFS= read -r -d '' item; do

5
mole
View File

@@ -22,7 +22,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/lib/core/common.sh" source "$SCRIPT_DIR/lib/core/common.sh"
# Version info # Version info
VERSION="1.12.10" VERSION="1.12.11"
MOLE_TAGLINE="can dig deep to clean your Mac." MOLE_TAGLINE="can dig deep to clean your Mac."
# Check if Touch ID is already configured # Check if Touch ID is already configured
@@ -738,6 +738,9 @@ main() {
"touchid") "touchid")
exec "$SCRIPT_DIR/bin/touchid.sh" "${args[@]:1}" exec "$SCRIPT_DIR/bin/touchid.sh" "${args[@]:1}"
;; ;;
"test")
exec "$SCRIPT_DIR/scripts/run-tests.sh" "${args[@]:1}"
;;
"update") "update")
update_mole update_mole
exit 0 exit 0

View File

@@ -13,9 +13,9 @@ GREEN='\033[0;32m'
YELLOW='\033[1;33m' YELLOW='\033[1;33m'
NC='\033[0m' NC='\033[0m'
echo "================================" echo "==============================="
echo " Mole Test Runner" echo " Mole Test Runner"
echo "================================" echo "==============================="
echo "" echo ""
# Track failures # Track failures
@@ -26,13 +26,13 @@ echo "1. Running ShellCheck..."
if command -v shellcheck > /dev/null 2>&1; then if command -v shellcheck > /dev/null 2>&1; then
if shellcheck mole bin/*.sh 2> /dev/null && if shellcheck mole bin/*.sh 2> /dev/null &&
find lib -name "*.sh" -type f -exec shellcheck {} + 2> /dev/null; then find lib -name "*.sh" -type f -exec shellcheck {} + 2> /dev/null; then
echo -e "${GREEN}✓ ShellCheck passed${NC}" printf "${GREEN}✓ ShellCheck passed${NC}\n"
else else
echo -e "${RED}✗ ShellCheck failed${NC}" printf "${RED}✗ ShellCheck failed${NC}\n"
((FAILED++)) ((FAILED++))
fi fi
else else
echo -e "${YELLOW}⚠ ShellCheck not installed, skipping${NC}" printf "${YELLOW}⚠ ShellCheck not installed, skipping${NC}\n"
fi fi
echo "" echo ""
@@ -41,9 +41,9 @@ echo "2. Running syntax check..."
if bash -n mole && if bash -n mole &&
bash -n bin/*.sh 2> /dev/null && bash -n bin/*.sh 2> /dev/null &&
find lib -name "*.sh" -type f -exec bash -n {} \; 2> /dev/null; then find lib -name "*.sh" -type f -exec bash -n {} \; 2> /dev/null; then
echo -e "${GREEN}✓ Syntax check passed${NC}" printf "${GREEN}✓ Syntax check passed${NC}\n"
else else
echo -e "${RED}✗ Syntax check failed${NC}" printf "${RED}✗ Syntax check failed${NC}\n"
((FAILED++)) ((FAILED++))
fi fi
echo "" echo ""
@@ -51,14 +51,16 @@ echo ""
# 3. Unit Tests # 3. Unit Tests
echo "3. Running unit tests..." echo "3. Running unit tests..."
if command -v bats > /dev/null 2>&1; then if command -v bats > /dev/null 2>&1; then
# Note: bats might detect non-TTY and suppress color.
# Adding --tap prevents spinner issues in background.
if bats tests/*.bats; then if bats tests/*.bats; then
echo -e "${GREEN}✓ Unit tests passed${NC}" printf "${GREEN}✓ Unit tests passed${NC}\n"
else else
echo -e "${RED}✗ Unit tests failed${NC}" printf "${RED}✗ Unit tests failed${NC}\n"
((FAILED++)) ((FAILED++))
fi fi
else else
echo -e "${YELLOW}⚠ Bats not installed, skipping unit tests${NC}" printf "${YELLOW}⚠ Bats not installed, skipping unit tests${NC}\n"
echo " Install with: brew install bats-core" echo " Install with: brew install bats-core"
fi fi
echo "" echo ""
@@ -67,45 +69,46 @@ echo ""
echo "4. Running Go tests..." echo "4. Running Go tests..."
if command -v go > /dev/null 2>&1; then if command -v go > /dev/null 2>&1; then
if go build ./... && go vet ./cmd/... && go test ./cmd/...; then if go build ./... && go vet ./cmd/... && go test ./cmd/...; then
echo -e "${GREEN}✓ Go tests passed${NC}" printf "${GREEN}✓ Go tests passed${NC}\n"
else else
echo -e "${RED}✗ Go tests failed${NC}" printf "${RED}✗ Go tests failed${NC}\n"
((FAILED++)) ((FAILED++))
fi fi
else else
echo -e "${YELLOW}⚠ Go not installed, skipping Go tests${NC}" printf "${YELLOW}⚠ Go not installed, skipping Go tests${NC}\n"
fi fi
echo "" echo ""
# 5. Module Loading Test # 5. Module Loading Test
echo "5. Testing module loading..." echo "5. Testing module loading..."
if bash -c 'source lib/core/common.sh && echo "OK"' > /dev/null 2>&1; then if bash -c 'source lib/core/common.sh && echo "OK"' > /dev/null 2>&1; then
echo -e "${GREEN}✓ Module loading passed${NC}" printf "${GREEN}✓ Module loading passed${NC}\n"
else else
echo -e "${RED}✗ Module loading failed${NC}" printf "${RED}✗ Module loading failed${NC}\n"
((FAILED++)) ((FAILED++))
fi fi
echo "" echo ""
# 6. Integration Tests # 6. Integration Tests
echo "6. Running integration tests..." echo "6. Running integration tests..."
export MOLE_MAX_PARALLEL_JOBS=30
if ./bin/clean.sh --dry-run > /dev/null 2>&1; then if ./bin/clean.sh --dry-run > /dev/null 2>&1; then
echo -e "${GREEN}✓ Clean dry-run passed${NC}" printf "${GREEN}✓ Clean dry-run passed${NC}\n"
else else
echo -e "${RED}✗ Clean dry-run failed${NC}" printf "${RED}✗ Clean dry-run failed${NC}\n"
((FAILED++)) ((FAILED++))
fi fi
echo "" echo ""
# Summary # Summary
echo "================================" echo "==============================="
if [[ $FAILED -eq 0 ]]; then if [[ $FAILED -eq 0 ]]; then
echo -e "${GREEN}All tests passed!${NC}" printf "${GREEN}All tests passed!${NC}\n"
echo "" echo ""
echo "You can now commit your changes." echo "You can now commit your changes."
exit 0 exit 0
else else
echo -e "${RED}$FAILED test(s) failed!${NC}" printf "${RED}$FAILED test(s) failed!${NC}\n"
echo "" echo ""
echo "Please fix the failing tests before committing." echo "Please fix the failing tests before committing."
exit 1 exit 1