From 8dc8d6c0634d0697fc5c9e6e5b9b38e73f612898 Mon Sep 17 00:00:00 2001 From: Tw93 Date: Sat, 11 Oct 2025 14:12:00 +0800 Subject: [PATCH] Improved whitelist experience --- bin/clean.sh | 17 +++++++- lib/paginated_menu.sh | 20 ++------- lib/whitelist_manager.sh | 92 +++++++++++++++++++++++++--------------- 3 files changed, 75 insertions(+), 54 deletions(-) diff --git a/bin/clean.sh b/bin/clean.sh index e53d903..f03c162 100755 --- a/bin/clean.sh +++ b/bin/clean.sh @@ -23,11 +23,12 @@ readonly TEMP_FILE_AGE_DAYS=7 # Age threshold for temp file cleanup readonly ORPHAN_AGE_DAYS=60 # Age threshold for orphaned data readonly SIZE_1GB_KB=1048576 # 1GB in kilobytes readonly SIZE_1MB_KB=1024 # 1MB in kilobytes -# Core whitelist patterns - always protected -WHITELIST_PATTERNS=( +# Default whitelist patterns (preselected, user can disable) +declare -a DEFAULT_WHITELIST_PATTERNS=( "$HOME/Library/Caches/ms-playwright*" "$HOME/.cache/huggingface*" ) +declare -a WHITELIST_PATTERNS=() WHITELIST_WARNINGS=() # Load user-defined whitelist @@ -57,8 +58,20 @@ if [[ -f "$HOME/.config/mole/whitelist" ]]; then ;; esac + duplicate="false" + if [[ ${#WHITELIST_PATTERNS[@]} -gt 0 ]]; then + for existing in "${WHITELIST_PATTERNS[@]}"; do + if [[ "$line" == "$existing" ]]; then + duplicate="true" + break + fi + done + fi + [[ "$duplicate" == "true" ]] && continue WHITELIST_PATTERNS+=("$line") done < "$HOME/.config/mole/whitelist" +else + WHITELIST_PATTERNS=("${DEFAULT_WHITELIST_PATTERNS[@]}") fi total_items=0 diff --git a/lib/paginated_menu.sh b/lib/paginated_menu.sh index 4e8e940..50ff8eb 100755 --- a/lib/paginated_menu.sh +++ b/lib/paginated_menu.sh @@ -95,8 +95,8 @@ paginated_multi_select() { render_item() { local idx=$1 is_current=$2 - local checkbox="[ ]" - [[ ${selected[idx]} == true ]] && checkbox="[x]" + local checkbox="○" + [[ ${selected[idx]} == true ]] && checkbox="●" if [[ $is_current == true ]]; then printf "\r\033[2K${BLUE}> %s %s${NC}\n" "$checkbox" "${items[idx]}" >&2 @@ -150,7 +150,7 @@ paginated_multi_select() { # Clear any remaining lines at bottom printf "${clear_line}\n" >&2 - printf "${clear_line}${GRAY}↑/↓${NC} Navigate ${GRAY}|${NC} ${GRAY}Space${NC} Select ${GRAY}|${NC} ${GRAY}Enter${NC} Confirm ${GRAY}|${NC} ${GRAY}Q/ESC${NC} Quit\n" >&2 + printf "${clear_line}${GRAY}↑/↓${NC} Navigate ${GRAY}|${NC} ${GRAY}Space${NC} Select ${GRAY}|${NC} ${GRAY}Enter${NC} Confirm ${GRAY}|${NC} ${GRAY}Q/ESC${NC} Quit ${GRAY}|${NC} ○ off ● on\n" >&2 # Clear one more line to ensure no artifacts printf "${clear_line}" >&2 @@ -229,20 +229,6 @@ EOF ;; "HELP") show_help ;; "ENTER") - # Auto-select current item if nothing selected - local has_selection=false - for ((i = 0; i < total_items; i++)); do - if [[ ${selected[i]} == true ]]; then - has_selection=true - break - fi - done - - if [[ $has_selection == false ]]; then - local idx=$((current_page * items_per_page + cursor_pos)) - [[ $idx -lt $total_items ]] && selected[idx]=true - fi - # Store result in global variable instead of returning via stdout local -a selected_indices=() for ((i = 0; i < total_items; i++)); do diff --git a/lib/whitelist_manager.sh b/lib/whitelist_manager.sh index a23816e..a23ab3f 100755 --- a/lib/whitelist_manager.sh +++ b/lib/whitelist_manager.sh @@ -12,45 +12,30 @@ source "$SCRIPT_DIR/paginated_menu.sh" # Config file path WHITELIST_CONFIG="$HOME/.config/mole/whitelist" -# Core whitelist patterns that are always protected +# Default whitelist patterns (preselected on first run) 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 +# Default protections: Playwright browsers, HuggingFace models (can be disabled) +# Add one pattern per line to keep items safe. EOF if [[ ${#patterns[@]} -gt 0 ]]; then + local -a unique_patterns=() 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 [[ ${#unique_patterns[@]} -gt 0 ]]; then + for existing in "${unique_patterns[@]}"; do if patterns_equivalent "$pattern" "$existing"; then duplicate="true" break @@ -58,12 +43,12 @@ EOF done fi [[ "$duplicate" == "true" ]] && continue - custom_patterns+=("$pattern") + unique_patterns+=("$pattern") done - if [[ ${#custom_patterns[@]} -gt 0 ]]; then + if [[ ${#unique_patterns[@]} -gt 0 ]]; then printf '\n' >> "$WHITELIST_CONFIG" - for pattern in "${custom_patterns[@]}"; do + for pattern in "${unique_patterns[@]}"; do echo "$pattern" >> "$WHITELIST_CONFIG" done fi @@ -130,9 +115,8 @@ patterns_equivalent() { load_whitelist() { - local -a patterns=("${DEFAULT_WHITELIST_PATTERNS[@]}") + local -a patterns=() - # Load user-defined patterns from config file if [[ -f "$WHITELIST_CONFIG" ]]; then while IFS= read -r line; do line="${line#${line%%[![:space:]]*}}" @@ -140,6 +124,8 @@ load_whitelist() { [[ -z "$line" || "$line" =~ ^# ]] && continue patterns+=("$line") done < "$WHITELIST_CONFIG" + else + patterns=("${DEFAULT_WHITELIST_PATTERNS[@]}") fi if [[ ${#patterns[@]} -gt 0 ]]; then @@ -203,7 +189,6 @@ manage_whitelist_categories() { 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 @@ -214,15 +199,48 @@ manage_whitelist_categories() { 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 + # Prioritize already-selected items to appear first + local -a selected_cache_items=() + local -a selected_cache_patterns=() + local -a selected_menu_options=() + local -a remaining_cache_items=() + local -a remaining_cache_patterns=() + local -a remaining_menu_options=() + + for ((i = 0; i < ${#cache_patterns[@]}; i++)); do + if is_whitelisted "${cache_patterns[i]}"; then + selected_cache_items+=("${cache_items[i]}") + selected_cache_patterns+=("${cache_patterns[i]}") + selected_menu_options+=("${menu_options[i]}") + else + remaining_cache_items+=("${cache_items[i]}") + remaining_cache_patterns+=("${cache_patterns[i]}") + remaining_menu_options+=("${menu_options[i]}") + fi + done + + cache_items=() + cache_patterns=() + menu_options=() + if [[ ${#selected_cache_items[@]} -gt 0 ]]; then + cache_items=("${selected_cache_items[@]}") + cache_patterns=("${selected_cache_patterns[@]}") + menu_options=("${selected_menu_options[@]}") + fi + if [[ ${#remaining_cache_items[@]} -gt 0 ]]; then + cache_items+=("${remaining_cache_items[@]}") + cache_patterns+=("${remaining_cache_patterns[@]}") + menu_options+=("${remaining_menu_options[@]}") + fi + + if [[ ${#selected_cache_patterns[@]} -gt 0 ]]; then + local -a preselected_indices=() + for ((i = 0; i < ${#selected_cache_patterns[@]}; i++)); do + preselected_indices+=("$i") + done local IFS=',' MOLE_PRESELECTED_INDICES="${preselected_indices[*]}" else @@ -255,8 +273,12 @@ manage_whitelist_categories() { done fi - # Save to whitelist config - save_whitelist_patterns "${selected_patterns[@]}" + # Save to whitelist config (bash 3.2 + set -u safe) + if [[ ${#selected_patterns[@]} -gt 0 ]]; then + save_whitelist_patterns "${selected_patterns[@]}" + else + save_whitelist_patterns + fi echo "" echo -e "${GREEN}✓${NC} Protected ${#selected_patterns[@]} cache(s)"