mirror of
https://github.com/tw93/Mole.git
synced 2026-02-11 04:14:17 +00:00
Reconstruct clean lib code
This commit is contained in:
200
lib/clean/caches.sh
Normal file
200
lib/clean/caches.sh
Normal file
@@ -0,0 +1,200 @@
|
||||
#!/bin/bash
|
||||
# Cache Cleanup Module
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Trigger all TCC permission dialogs upfront to avoid random interruptions
|
||||
# Only runs once (uses ~/.cache/mole/permissions_granted flag)
|
||||
check_tcc_permissions() {
|
||||
# Only check in interactive mode
|
||||
[[ -t 1 ]] || return 0
|
||||
|
||||
local permission_flag="$HOME/.cache/mole/permissions_granted"
|
||||
|
||||
# Skip if permissions were already granted
|
||||
[[ -f "$permission_flag" ]] && return 0
|
||||
|
||||
# Key protected directories that require TCC approval
|
||||
local -a tcc_dirs=(
|
||||
"$HOME/Library/Caches"
|
||||
"$HOME/Library/Logs"
|
||||
"$HOME/Library/Application Support"
|
||||
"$HOME/Library/Containers"
|
||||
"$HOME/.cache"
|
||||
)
|
||||
|
||||
# Quick permission test - if first directory is accessible, likely others are too
|
||||
# Use simple ls test instead of find to avoid triggering permission dialogs prematurely
|
||||
local needs_permission_check=false
|
||||
if ! ls "$HOME/Library/Caches" > /dev/null 2>&1; then
|
||||
needs_permission_check=true
|
||||
fi
|
||||
|
||||
if [[ "$needs_permission_check" == "true" ]]; then
|
||||
echo ""
|
||||
echo -e "${BLUE}First-time setup${NC}"
|
||||
echo -e "${GRAY}macOS will request permissions to access Library folders.${NC}"
|
||||
echo -e "${GRAY}You may see ${GREEN}${#tcc_dirs[@]} permission dialogs${NC}${GRAY} - please approve them all.${NC}"
|
||||
echo ""
|
||||
echo -ne "${PURPLE}${ICON_ARROW}${NC} Press ${GREEN}Enter${NC} to continue: "
|
||||
read -r
|
||||
|
||||
MOLE_SPINNER_PREFIX="" start_inline_spinner "Requesting permissions..."
|
||||
|
||||
# Trigger all TCC prompts upfront by accessing each directory
|
||||
# Using find -maxdepth 1 ensures we touch the directory without deep scanning
|
||||
for dir in "${tcc_dirs[@]}"; do
|
||||
[[ -d "$dir" ]] && find "$dir" -maxdepth 1 -type d > /dev/null 2>&1
|
||||
done
|
||||
|
||||
stop_inline_spinner
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Mark permissions as granted (won't prompt again)
|
||||
mkdir -p "$(dirname "$permission_flag")" 2> /dev/null || true
|
||||
touch "$permission_flag" 2> /dev/null || true
|
||||
}
|
||||
|
||||
# Clean browser Service Worker cache, protecting web editing tools (capcut, photopea, pixlr)
|
||||
# Args: $1=browser_name, $2=cache_path
|
||||
clean_service_worker_cache() {
|
||||
local browser_name="$1"
|
||||
local cache_path="$2"
|
||||
|
||||
[[ ! -d "$cache_path" ]] && return 0
|
||||
|
||||
local cleaned_size=0
|
||||
local protected_count=0
|
||||
|
||||
# Find all cache directories and calculate sizes
|
||||
while IFS= read -r cache_dir; do
|
||||
[[ ! -d "$cache_dir" ]] && continue
|
||||
|
||||
# Extract domain from path using regex
|
||||
# Pattern matches: letters/numbers, hyphens, then dot, then TLD
|
||||
# Example: "abc123_https_example.com_0" → "example.com"
|
||||
local domain=$(basename "$cache_dir" | grep -oE '[a-zA-Z0-9][-a-zA-Z0-9]*\.[a-zA-Z]{2,}' | head -1 || echo "")
|
||||
local size=$(du -sk "$cache_dir" 2> /dev/null | awk '{print $1}')
|
||||
|
||||
# Check if domain is protected
|
||||
local is_protected=false
|
||||
for protected_domain in "${PROTECTED_SW_DOMAINS[@]}"; do
|
||||
if [[ "$domain" == *"$protected_domain"* ]]; then
|
||||
is_protected=true
|
||||
protected_count=$((protected_count + 1))
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# Clean if not protected
|
||||
if [[ "$is_protected" == "false" ]]; then
|
||||
if [[ "$DRY_RUN" != "true" ]]; then
|
||||
safe_remove "$cache_dir" true || true
|
||||
fi
|
||||
cleaned_size=$((cleaned_size + size))
|
||||
fi
|
||||
done < <(find "$cache_path" -type d -depth 2 2> /dev/null)
|
||||
|
||||
if [[ $cleaned_size -gt 0 ]]; then
|
||||
local cleaned_mb=$((cleaned_size / 1024))
|
||||
if [[ "$DRY_RUN" != "true" ]]; then
|
||||
echo -e " ${GREEN}${ICON_SUCCESS}${NC} $browser_name Service Worker cache (${cleaned_mb}MB cleaned, $protected_count protected)"
|
||||
else
|
||||
echo -e " ${YELLOW}→${NC} $browser_name Service Worker cache (would clean ${cleaned_mb}MB, $protected_count protected)"
|
||||
fi
|
||||
note_activity
|
||||
fi
|
||||
}
|
||||
|
||||
# Clean Next.js (.next/cache) and Python (__pycache__) build caches
|
||||
# Uses maxdepth 3, excludes Library/.Trash/node_modules, 10s timeout per scan
|
||||
clean_project_caches() {
|
||||
# Clean Next.js caches
|
||||
if [[ -t 1 ]]; then
|
||||
MOLE_SPINNER_PREFIX=" "
|
||||
start_inline_spinner "Searching Next.js caches..."
|
||||
fi
|
||||
|
||||
# Use timeout to prevent hanging on problematic directories
|
||||
local nextjs_tmp_file
|
||||
nextjs_tmp_file=$(create_temp_file)
|
||||
(
|
||||
find "$HOME" -P -mount -type d -name ".next" -maxdepth 3 \
|
||||
-not -path "*/Library/*" \
|
||||
-not -path "*/.Trash/*" \
|
||||
-not -path "*/node_modules/*" \
|
||||
-not -path "*/.*" \
|
||||
2> /dev/null || true
|
||||
) > "$nextjs_tmp_file" 2>&1 &
|
||||
local find_pid=$!
|
||||
local find_timeout=10
|
||||
local elapsed=0
|
||||
|
||||
# Wait for find to complete or timeout
|
||||
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)
|
||||
(
|
||||
find "$HOME" -P -mount -type d -name "__pycache__" -maxdepth 3 \
|
||||
-not -path "*/Library/*" \
|
||||
-not -path "*/.Trash/*" \
|
||||
-not -path "*/node_modules/*" \
|
||||
-not -path "*/.*" \
|
||||
2> /dev/null || true
|
||||
) > "$pycache_tmp_file" 2>&1 &
|
||||
local find_pid=$!
|
||||
local find_timeout=10
|
||||
local elapsed=0
|
||||
|
||||
# Wait for find to complete or timeout
|
||||
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 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
|
||||
stop_inline_spinner
|
||||
fi
|
||||
}
|
||||
Reference in New Issue
Block a user