mirror of
https://github.com/tw93/Mole.git
synced 2026-02-04 15:04:42 +00:00
270 lines
9.3 KiB
Bash
Executable File
270 lines
9.3 KiB
Bash
Executable File
#!/bin/bash
|
|
# Whitelist management functionality
|
|
# Shows actual files that would be deleted by dry-run
|
|
|
|
set -euo pipefail
|
|
|
|
# Get script directory and source dependencies
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
source "$SCRIPT_DIR/common.sh"
|
|
source "$SCRIPT_DIR/paginated_menu.sh"
|
|
|
|
# Config file path
|
|
WHITELIST_CONFIG="$HOME/.config/mole/whitelist"
|
|
|
|
# Core whitelist patterns that are always protected
|
|
declare -a DEFAULT_WHITELIST_PATTERNS=(
|
|
"$HOME/Library/Caches/ms-playwright*"
|
|
"$HOME/.cache/huggingface*"
|
|
)
|
|
|
|
# Determine if a pattern matches one of the defaults
|
|
is_default_pattern() {
|
|
local candidate="$1"
|
|
for default_pat in "${DEFAULT_WHITELIST_PATTERNS[@]}"; do
|
|
if patterns_equivalent "$candidate" "$default_pat"; then
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
# Save whitelist patterns to config
|
|
save_whitelist_patterns() {
|
|
local -a patterns
|
|
patterns=("$@")
|
|
local -a custom_patterns
|
|
custom_patterns=()
|
|
mkdir -p "$(dirname "$WHITELIST_CONFIG")"
|
|
|
|
cat > "$WHITELIST_CONFIG" << 'EOF'
|
|
# Mole Whitelist - Protected paths won't be deleted
|
|
# Default protections: Playwright browsers, HuggingFace models
|
|
# You can add custom paths here
|
|
EOF
|
|
|
|
if [[ ${#patterns[@]} -gt 0 ]]; then
|
|
for pattern in "${patterns[@]}"; do
|
|
if is_default_pattern "$pattern"; then
|
|
continue
|
|
fi
|
|
local duplicate="false"
|
|
if [[ ${#custom_patterns[@]} -gt 0 ]]; then
|
|
for existing in "${custom_patterns[@]}"; do
|
|
if patterns_equivalent "$pattern" "$existing"; then
|
|
duplicate="true"
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
[[ "$duplicate" == "true" ]] && continue
|
|
custom_patterns+=("$pattern")
|
|
done
|
|
|
|
if [[ ${#custom_patterns[@]} -gt 0 ]]; then
|
|
printf '\n' >> "$WHITELIST_CONFIG"
|
|
for pattern in "${custom_patterns[@]}"; do
|
|
echo "$pattern" >> "$WHITELIST_CONFIG"
|
|
done
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Get all cache items with their patterns
|
|
get_all_cache_items() {
|
|
# Format: "display_name|pattern|category"
|
|
cat << 'EOF'
|
|
Gradle build cache (Android Studio, Gradle projects)|$HOME/.gradle/caches/*|ide_cache
|
|
Gradle daemon processes cache|$HOME/.gradle/daemon/*|ide_cache
|
|
Xcode DerivedData (build outputs, indexes)|$HOME/Library/Developer/Xcode/DerivedData/*|ide_cache
|
|
Xcode internal cache files|$HOME/Library/Caches/com.apple.dt.Xcode/*|ide_cache
|
|
Xcode iOS device support symbols|$HOME/Library/Developer/Xcode/iOS DeviceSupport/*/Symbols/System/Library/Caches/*|ide_cache
|
|
Maven local repository (Java dependencies)|$HOME/.m2/repository/*|ide_cache
|
|
JetBrains IDEs cache (IntelliJ, PyCharm, WebStorm)|$HOME/Library/Caches/JetBrains/*|ide_cache
|
|
Android Studio cache and indexes|$HOME/Library/Caches/Google/AndroidStudio*/*|ide_cache
|
|
VS Code runtime cache|$HOME/Library/Application Support/Code/Cache/*|ide_cache
|
|
VS Code extension and update cache|$HOME/Library/Application Support/Code/CachedData/*|ide_cache
|
|
VS Code system cache (Cursor, VSCodium)|$HOME/Library/Caches/com.microsoft.VSCode/*|ide_cache
|
|
Cursor editor cache|$HOME/Library/Caches/com.todesktop.230313mzl4w4u92/*|ide_cache
|
|
Bazel build cache|$HOME/.cache/bazel/*|compiler_cache
|
|
Go build cache and module cache|$HOME/Library/Caches/go-build/*|compiler_cache
|
|
Rust Cargo registry cache|$HOME/.cargo/registry/cache/*|compiler_cache
|
|
Rustup toolchain downloads|$HOME/.rustup/downloads/*|compiler_cache
|
|
ccache compiler cache|$HOME/.ccache/*|compiler_cache
|
|
sccache distributed compiler cache|$HOME/.cache/sccache/*|compiler_cache
|
|
CocoaPods cache (iOS dependencies)|$HOME/Library/Caches/CocoaPods/*|package_manager
|
|
npm package cache|$HOME/.npm/_cacache/*|package_manager
|
|
pip Python package cache|$HOME/.cache/pip/*|package_manager
|
|
Homebrew downloaded packages|$HOME/Library/Caches/Homebrew/*|package_manager
|
|
Yarn package manager cache|$HOME/.cache/yarn/*|package_manager
|
|
pnpm package store|$HOME/.pnpm-store/*|package_manager
|
|
Composer PHP dependencies cache|$HOME/.composer/cache/*|package_manager
|
|
RubyGems cache|$HOME/.gem/cache/*|package_manager
|
|
Go module cache|$HOME/go/pkg/mod/cache/*|package_manager
|
|
PyTorch model cache|$HOME/.cache/torch/*|ai_ml_cache
|
|
TensorFlow model and dataset cache|$HOME/.cache/tensorflow/*|ai_ml_cache
|
|
HuggingFace models and datasets|$HOME/.cache/huggingface/*|ai_ml_cache
|
|
Playwright browser binaries|$HOME/Library/Caches/ms-playwright*|ai_ml_cache
|
|
Selenium WebDriver binaries|$HOME/.cache/selenium/*|ai_ml_cache
|
|
Ollama local AI models|$HOME/.ollama/models/*|ai_ml_cache
|
|
Safari web browser cache|$HOME/Library/Caches/com.apple.Safari/*|browser_cache
|
|
Chrome browser cache|$HOME/Library/Caches/Google/Chrome/*|browser_cache
|
|
Firefox browser cache|$HOME/Library/Caches/Firefox/*|browser_cache
|
|
Brave browser cache|$HOME/Library/Caches/BraveSoftware/Brave-Browser/*|browser_cache
|
|
Docker Desktop image cache|$HOME/Library/Containers/com.docker.docker/Data/*|container_cache
|
|
Podman container cache|$HOME/.local/share/containers/cache/*|container_cache
|
|
Font cache|$HOME/Library/Caches/com.apple.FontRegistry/*|system_cache
|
|
Spotlight metadata cache|$HOME/Library/Caches/com.apple.spotlight/*|system_cache
|
|
CloudKit cache|$HOME/Library/Caches/CloudKit/*|system_cache
|
|
EOF
|
|
}
|
|
|
|
patterns_equivalent() {
|
|
local first="${1/#~/$HOME}"
|
|
local second="${2/#~/$HOME}"
|
|
|
|
# Only exact string match, no glob expansion
|
|
[[ "$first" == "$second" ]] && return 0
|
|
return 1
|
|
}
|
|
|
|
|
|
load_whitelist() {
|
|
local -a patterns=("${DEFAULT_WHITELIST_PATTERNS[@]}")
|
|
|
|
# Load user-defined patterns from config file
|
|
if [[ -f "$WHITELIST_CONFIG" ]]; then
|
|
while IFS= read -r line; do
|
|
line="${line#${line%%[![:space:]]*}}"
|
|
line="${line%${line##*[![:space:]]}}"
|
|
[[ -z "$line" || "$line" =~ ^# ]] && continue
|
|
patterns+=("$line")
|
|
done < "$WHITELIST_CONFIG"
|
|
fi
|
|
|
|
if [[ ${#patterns[@]} -gt 0 ]]; then
|
|
local -a unique_patterns=()
|
|
for pattern in "${patterns[@]}"; do
|
|
local duplicate="false"
|
|
if [[ ${#unique_patterns[@]} -gt 0 ]]; then
|
|
for existing in "${unique_patterns[@]}"; do
|
|
if patterns_equivalent "$pattern" "$existing"; then
|
|
duplicate="true"
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
[[ "$duplicate" == "true" ]] && continue
|
|
unique_patterns+=("$pattern")
|
|
done
|
|
CURRENT_WHITELIST_PATTERNS=("${unique_patterns[@]}")
|
|
else
|
|
CURRENT_WHITELIST_PATTERNS=()
|
|
fi
|
|
}
|
|
|
|
is_whitelisted() {
|
|
local pattern="$1"
|
|
local check_pattern="${pattern/#\~/$HOME}"
|
|
|
|
if [[ ${#CURRENT_WHITELIST_PATTERNS[@]} -eq 0 ]]; then
|
|
return 1
|
|
fi
|
|
|
|
for existing in "${CURRENT_WHITELIST_PATTERNS[@]}"; do
|
|
local existing_expanded="${existing/#\~/$HOME}"
|
|
if [[ "$check_pattern" == "$existing_expanded" ]]; then
|
|
return 0
|
|
fi
|
|
if [[ "$check_pattern" == $existing_expanded ]]; then
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
|
|
manage_whitelist() {
|
|
manage_whitelist_categories
|
|
}
|
|
|
|
manage_whitelist_categories() {
|
|
clear
|
|
echo ""
|
|
echo -e "${PURPLE}Whitelist Manager${NC}"
|
|
echo ""
|
|
echo -e "${GRAY}Select caches to protect from cleanup.${NC}"
|
|
echo ""
|
|
|
|
# Load currently enabled patterns from both sources
|
|
load_whitelist
|
|
|
|
# Build cache items list
|
|
local -a cache_items=()
|
|
local -a cache_patterns=()
|
|
local -a menu_options=()
|
|
local -a preselected_indices=()
|
|
local index=0
|
|
|
|
while IFS='|' read -r display_name pattern category; do
|
|
# Expand $HOME in pattern
|
|
pattern="${pattern/\$HOME/$HOME}"
|
|
|
|
cache_items+=("$display_name")
|
|
cache_patterns+=("$pattern")
|
|
menu_options+=("$display_name")
|
|
|
|
# Check if this pattern is currently whitelisted
|
|
if is_whitelisted "$pattern"; then
|
|
preselected_indices+=("$index")
|
|
fi
|
|
|
|
((index++))
|
|
done < <(get_all_cache_items)
|
|
|
|
if [[ ${#preselected_indices[@]} -gt 0 ]]; then
|
|
local IFS=','
|
|
MOLE_PRESELECTED_INDICES="${preselected_indices[*]}"
|
|
else
|
|
unset MOLE_PRESELECTED_INDICES
|
|
fi
|
|
|
|
MOLE_SELECTION_RESULT=""
|
|
paginated_multi_select "Select caches to protect" "${menu_options[@]}"
|
|
unset MOLE_PRESELECTED_INDICES
|
|
local exit_code=$?
|
|
|
|
if [[ $exit_code -ne 0 ]]; then
|
|
echo ""
|
|
echo -e "${YELLOW}Cancelled${NC}"
|
|
return 1
|
|
fi
|
|
|
|
# Convert selected indices to patterns
|
|
local -a selected_patterns=()
|
|
if [[ -n "$MOLE_SELECTION_RESULT" ]]; then
|
|
local -a selected_indices
|
|
IFS=',' read -ra selected_indices <<< "$MOLE_SELECTION_RESULT"
|
|
for idx in "${selected_indices[@]}"; do
|
|
if [[ $idx -ge 0 && $idx -lt ${#cache_patterns[@]} ]]; then
|
|
local pattern="${cache_patterns[$idx]}"
|
|
# Convert back to portable format with ~
|
|
pattern="${pattern/#$HOME/~}"
|
|
selected_patterns+=("$pattern")
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Save to whitelist config
|
|
save_whitelist_patterns "${selected_patterns[@]}"
|
|
|
|
echo ""
|
|
echo -e "${GREEN}✓${NC} Protected ${#selected_patterns[@]} cache(s)"
|
|
echo -e "${GRAY}Config: ${WHITELIST_CONFIG}${NC}"
|
|
}
|
|
|
|
|
|
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
manage_whitelist
|
|
fi
|