From dc8d1bd9488bf90b55ca454a62450a2a8197ef07 Mon Sep 17 00:00:00 2001 From: tw93 Date: Sat, 21 Feb 2026 23:35:53 +0800 Subject: [PATCH] refactor(clean): merge app cache/user essentials flow - reorganize perform_cleanup sections and naming - merge macOS + sandbox caches into clean_app_caches - move recent items and mail downloads into user essentials - update core/user tests for renamed internal helpers --- bin/clean.sh | 65 ++++----- lib/clean/user.sh | 289 ++++++++++++++++++++----------------- tests/clean_core.bats | 16 +- tests/clean_user_core.bats | 21 ++- 4 files changed, 200 insertions(+), 191 deletions(-) diff --git a/bin/clean.sh b/bin/clean.sh index 5af53cd..55f5789 100755 --- a/bin/clean.sh +++ b/bin/clean.sh @@ -677,8 +677,6 @@ safe_clean() { echo "$display_path # $size_human" >> "$EXPORT_LIST_FILE" fi done - - rm -f "$paths_temp" fi else echo -e " ${GREEN}${ICON_SUCCESS}${NC} $label${NC}, ${GREEN}$size_human${NC}" @@ -895,9 +893,9 @@ perform_cleanup() { # Allow per-section failures without aborting the full run. set +e - # ===== 1. Deep system cleanup (if admin) ===== + # ===== 1. System ===== if [[ "$SYSTEM_CLEAN" == "true" ]]; then - start_section "Deep system" + start_section "System" clean_deep_system clean_local_snapshots end_section @@ -910,84 +908,71 @@ perform_cleanup() { done fi + # ===== 2. User essentials ===== start_section "User essentials" clean_user_essentials + clean_finder_metadata scan_external_volumes end_section - start_section "Finder metadata" - clean_finder_metadata + # ===== 3. App caches (merged sandboxed and standard app caches) ===== + start_section "App caches" + clean_app_caches end_section - # ===== 3. macOS system caches ===== - start_section "macOS system caches" - clean_macos_system_caches - clean_recent_items - clean_mail_downloads - end_section - - # ===== 4. Sandboxed app caches ===== - start_section "Sandboxed app caches" - clean_sandboxed_app_caches - end_section - - # ===== 5. Browsers ===== + # ===== 4. Browsers ===== start_section "Browsers" clean_browsers end_section - # ===== 6. Cloud storage ===== - start_section "Cloud storage" + # ===== 5. Cloud & Office ===== + start_section "Cloud & Office" clean_cloud_storage - end_section - - # ===== 7. Office applications ===== - start_section "Office applications" clean_office_applications end_section - # ===== 8. Developer tools ===== + # ===== 6. Developer tools (merged CLI and GUI tooling) ===== start_section "Developer tools" clean_developer_tools end_section - # ===== 9. Development applications ===== - start_section "Development applications" + # ===== 7. Applications ===== + start_section "Applications" clean_user_gui_applications end_section - # ===== 10. Virtualization tools ===== - start_section "Virtual machine tools" + # ===== 8. Virtualization ===== + start_section "Virtualization" clean_virtualization_tools end_section - # ===== 11. Application Support logs and caches cleanup ===== + # ===== 9. Application Support ===== start_section "Application Support" clean_application_support_logs end_section - # ===== 12. Orphaned app data cleanup (60+ days inactive, skip protected vendors) ===== - start_section "Uninstalled app data" + # ===== 10. Orphaned data ===== + start_section "Orphaned data" clean_orphaned_app_data clean_orphaned_system_services clean_orphaned_launch_agents end_section - # ===== 13. Apple Silicon optimizations ===== + # ===== 11. Apple Silicon ===== clean_apple_silicon_caches - # ===== 14. iOS device backups ===== - start_section "iOS device backups" + # ===== 12. Device backups ===== + start_section "Device backups" check_ios_device_backups end_section - # ===== 15. Time Machine incomplete backups ===== - start_section "Time Machine incomplete backups" + # ===== 13. Time Machine ===== + start_section "Time Machine" clean_time_machine_failed_backups end_section - # ===== 16. Large files to review (report only) ===== - start_section "Large files to review" + # ===== 14. Large files ===== + start_section "Large files" check_large_file_candidates end_section diff --git a/lib/clean/user.sh b/lib/clean/user.sh index cf96fdf..8020778 100644 --- a/lib/clean/user.sh +++ b/lib/clean/user.sh @@ -35,6 +35,79 @@ clean_user_essentials() { echo -e " ${GREEN}${ICON_SUCCESS}${NC} Trash ยท already empty" fi fi + + # Recent items + _clean_recent_items + + # Mail downloads + _clean_mail_downloads +} + +# Internal: Remove recent items lists. +_clean_recent_items() { + local shared_dir="$HOME/Library/Application Support/com.apple.sharedfilelist" + local -a recent_lists=( + "$shared_dir/com.apple.LSSharedFileList.RecentApplications.sfl2" + "$shared_dir/com.apple.LSSharedFileList.RecentDocuments.sfl2" + "$shared_dir/com.apple.LSSharedFileList.RecentServers.sfl2" + "$shared_dir/com.apple.LSSharedFileList.RecentHosts.sfl2" + "$shared_dir/com.apple.LSSharedFileList.RecentApplications.sfl" + "$shared_dir/com.apple.LSSharedFileList.RecentDocuments.sfl" + "$shared_dir/com.apple.LSSharedFileList.RecentServers.sfl" + "$shared_dir/com.apple.LSSharedFileList.RecentHosts.sfl" + ) + if [[ -d "$shared_dir" ]]; then + for sfl_file in "${recent_lists[@]}"; do + [[ -e "$sfl_file" ]] && safe_clean "$sfl_file" "Recent items list" || true + done + fi + safe_clean ~/Library/Preferences/com.apple.recentitems.plist "Recent items preferences" || true +} + +# Internal: Clean old mail downloads. +_clean_mail_downloads() { + local mail_age_days=${MOLE_MAIL_AGE_DAYS:-} + if ! [[ "$mail_age_days" =~ ^[0-9]+$ ]]; then + mail_age_days=30 + fi + local -a mail_dirs=( + "$HOME/Library/Mail Downloads" + "$HOME/Library/Containers/com.apple.mail/Data/Library/Mail Downloads" + ) + local count=0 + local cleaned_kb=0 + for target_path in "${mail_dirs[@]}"; do + if [[ -d "$target_path" ]]; then + local dir_size_kb=0 + dir_size_kb=$(get_path_size_kb "$target_path") + if ! [[ "$dir_size_kb" =~ ^[0-9]+$ ]]; then + dir_size_kb=0 + fi + local min_kb="${MOLE_MAIL_DOWNLOADS_MIN_KB:-}" + if ! [[ "$min_kb" =~ ^[0-9]+$ ]]; then + min_kb=5120 + fi + if [[ "$dir_size_kb" -lt "$min_kb" ]]; then + continue + fi + while IFS= read -r -d '' file_path; do + if [[ -f "$file_path" ]]; then + local file_size_kb + file_size_kb=$(get_path_size_kb "$file_path") + if safe_remove "$file_path" true; then + ((count++)) + ((cleaned_kb += file_size_kb)) + fi + fi + done < <(command find "$target_path" -type f -mtime +"$mail_age_days" -print0 2> /dev/null || true) + fi + done + if [[ $count -gt 0 ]]; then + local cleaned_mb + cleaned_mb=$(echo "$cleaned_kb" | awk '{printf "%.1f", $1/1024}' || echo "0.0") + echo " ${GREEN}${ICON_SUCCESS}${NC} Cleaned $count mail attachments, about ${cleaned_mb}MB" + note_activity + fi } # Remove old Google Chrome versions while keeping Current. @@ -321,9 +394,9 @@ clean_finder_metadata() { fi clean_ds_store_tree "$HOME" "Home directory, .DS_Store" } -# macOS system caches and user-level leftovers. -clean_macos_system_caches() { - # safe_clean already checks protected paths. +# App caches (merged: macOS system caches + Sandboxed apps). +clean_app_caches() { + # macOS system caches (merged from clean_macos_system_caches) safe_clean ~/Library/Saved\ Application\ State/* "Saved application states" || true safe_clean ~/Library/Caches/com.apple.photoanalysisd "Photo analysis cache" || true safe_clean ~/Library/Caches/com.apple.akd "Apple ID cache" || true @@ -340,70 +413,8 @@ clean_macos_system_caches() { safe_clean ~/Library/Suggestions/* "Siri suggestions cache" || true safe_clean ~/Library/Calendars/Calendar\ Cache "Calendar cache" || true safe_clean ~/Library/Application\ Support/AddressBook/Sources/*/Photos.cache "Address Book photo cache" || true -} -clean_recent_items() { - local shared_dir="$HOME/Library/Application Support/com.apple.sharedfilelist" - local -a recent_lists=( - "$shared_dir/com.apple.LSSharedFileList.RecentApplications.sfl2" - "$shared_dir/com.apple.LSSharedFileList.RecentDocuments.sfl2" - "$shared_dir/com.apple.LSSharedFileList.RecentServers.sfl2" - "$shared_dir/com.apple.LSSharedFileList.RecentHosts.sfl2" - "$shared_dir/com.apple.LSSharedFileList.RecentApplications.sfl" - "$shared_dir/com.apple.LSSharedFileList.RecentDocuments.sfl" - "$shared_dir/com.apple.LSSharedFileList.RecentServers.sfl" - "$shared_dir/com.apple.LSSharedFileList.RecentHosts.sfl" - ) - if [[ -d "$shared_dir" ]]; then - for sfl_file in "${recent_lists[@]}"; do - [[ -e "$sfl_file" ]] && safe_clean "$sfl_file" "Recent items list" || true - done - fi - safe_clean ~/Library/Preferences/com.apple.recentitems.plist "Recent items preferences" || true -} -clean_mail_downloads() { - local mail_age_days=${MOLE_MAIL_AGE_DAYS:-} - if ! [[ "$mail_age_days" =~ ^[0-9]+$ ]]; then - mail_age_days=30 - fi - local -a mail_dirs=( - "$HOME/Library/Mail Downloads" - "$HOME/Library/Containers/com.apple.mail/Data/Library/Mail Downloads" - ) - local count=0 - local cleaned_kb=0 - for target_path in "${mail_dirs[@]}"; do - if [[ -d "$target_path" ]]; then - local dir_size_kb=0 - dir_size_kb=$(get_path_size_kb "$target_path") - if ! [[ "$dir_size_kb" =~ ^[0-9]+$ ]]; then - dir_size_kb=0 - fi - local min_kb="${MOLE_MAIL_DOWNLOADS_MIN_KB:-}" - if ! [[ "$min_kb" =~ ^[0-9]+$ ]]; then - min_kb=5120 - fi - if [[ "$dir_size_kb" -lt "$min_kb" ]]; then - continue - fi - while IFS= read -r -d '' file_path; do - if [[ -f "$file_path" ]]; then - local file_size_kb=$(get_path_size_kb "$file_path") - if safe_remove "$file_path" true; then - ((count++)) - ((cleaned_kb += file_size_kb)) - fi - fi - done < <(command find "$target_path" -type f -mtime +"$mail_age_days" -print0 2> /dev/null || true) - fi - done - if [[ $count -gt 0 ]]; then - local cleaned_mb=$(echo "$cleaned_kb" | awk '{printf "%.1f", $1/1024}' || echo "0.0") - echo " ${GREEN}${ICON_SUCCESS}${NC} Cleaned $count mail attachments, about ${cleaned_mb}MB" - note_activity - fi -} -# Sandboxed app caches. -clean_sandboxed_app_caches() { + + # Sandboxed app caches stop_section_spinner safe_clean ~/Library/Containers/com.apple.wallpaper.agent/Data/Library/Caches/* "Wallpaper agent cache" safe_clean ~/Library/Containers/com.apple.mediaanalysisd/Data/Library/Caches/* "Media analysis cache" @@ -415,7 +426,7 @@ clean_sandboxed_app_caches() { local total_size=0 local cleaned_count=0 local found_any=false - # Use nullglob to avoid literal globs. + local _ng_state _ng_state=$(shopt -p nullglob || true) shopt -s nullglob @@ -424,8 +435,10 @@ clean_sandboxed_app_caches() { done eval "$_ng_state" stop_section_spinner + if [[ "$found_any" == "true" ]]; then - local size_human=$(bytes_to_human "$((total_size * 1024))") + local size_human + size_human=$(bytes_to_human "$((total_size * 1024))") if [[ "$DRY_RUN" == "true" ]]; then echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} Sandboxed app caches${NC}, ${YELLOW}$size_human dry${NC}" else @@ -444,7 +457,8 @@ process_container_cache() { local container_dir="$1" [[ -d "$container_dir" ]] || return 0 [[ -L "$container_dir" ]] && return 0 - local bundle_id=$(basename "$container_dir") + local bundle_id + bundle_id=$(basename "$container_dir") if is_critical_system_component "$bundle_id"; then return 0 fi @@ -456,23 +470,17 @@ process_container_cache() { [[ -L "$cache_dir" ]] && return 0 # Fast non-empty check. if find "$cache_dir" -mindepth 1 -maxdepth 1 -print -quit 2> /dev/null | grep -q .; then - local size=$(get_path_size_kb "$cache_dir") + local size + size=$(get_path_size_kb "$cache_dir") ((total_size += size)) found_any=true ((cleaned_count++)) if [[ "$DRY_RUN" != "true" ]]; then - # For directories with many files, use find -delete for performance - if ! find "$cache_dir" -mindepth 1 -delete 2> /dev/null; then - # Fallback: try item-by-item if find fails - local _ng_state - _ng_state=$(shopt -p nullglob || true) - shopt -s nullglob - for item in "$cache_dir"/*; do - [[ -e "$item" ]] || continue - safe_remove "$item" true || true - done - eval "$_ng_state" - fi + local item + while IFS= read -r -d '' item; do + [[ -e "$item" ]] || continue + safe_remove "$item" true || true + done < <(command find "$cache_dir" -mindepth 1 -maxdepth 1 -print0 2> /dev/null || true) fi fi } @@ -489,10 +497,9 @@ clean_group_container_caches() { local total_size=0 local cleaned_count=0 local found_any=false - local _ng_state - _ng_state=$(shopt -p nullglob || true) - shopt -s nullglob + # Collect all non-Apple container directories first + local -a containers=() local container_dir for container_dir in "$group_containers_dir"/*; do [[ -d "$container_dir" ]] || continue @@ -506,12 +513,18 @@ clean_group_container_caches() { continue ;; esac + containers+=("$container_dir") + done + # Process each container's candidate directories + for container_dir in "${containers[@]}"; do + local container_id + container_id=$(basename "$container_dir") local normalized_id="$container_id" [[ "$normalized_id" == group.* ]] && normalized_id="${normalized_id#group.}" local protected_container=false - if should_protect_data "$container_id" || should_protect_data "$normalized_id"; then + if should_protect_data "$container_id" 2> /dev/null || should_protect_data "$normalized_id" 2> /dev/null; then protected_container=true fi @@ -532,39 +545,47 @@ clean_group_container_caches() { for candidate in "${candidates[@]}"; do [[ -d "$candidate" ]] || continue [[ -L "$candidate" ]] && continue - if is_path_whitelisted "$candidate"; then - continue - fi - if ! find "$candidate" -mindepth 1 -maxdepth 1 -print -quit 2> /dev/null | grep -q .; then + if is_path_whitelisted "$candidate" 2> /dev/null; then continue fi - local candidate_size_kb=0 - local candidate_changed=false + # Build non-protected candidate items for cleanup. + local -a items_to_clean=() local item while IFS= read -r -d '' item; do [[ -e "$item" ]] || continue [[ -L "$item" ]] && continue - if should_protect_path "$item" || is_path_whitelisted "$item"; then + if should_protect_path "$item" 2> /dev/null || is_path_whitelisted "$item" 2> /dev/null; then continue - fi - - local item_size_kb - item_size_kb=$(get_path_size_kb "$item") - [[ "$item_size_kb" =~ ^[0-9]+$ ]] || item_size_kb=0 - - if [[ "$DRY_RUN" == "true" ]]; then - candidate_changed=true - ((candidate_size_kb += item_size_kb)) - continue - fi - - if safe_remove "$item" true; then - candidate_changed=true - ((candidate_size_kb += item_size_kb)) + else + items_to_clean+=("$item") fi done < <(command find "$candidate" -mindepth 1 -maxdepth 1 -print0 2> /dev/null || true) + [[ ${#items_to_clean[@]} -gt 0 ]] || continue + + local candidate_size_kb=0 + local candidate_changed=false + if [[ "$DRY_RUN" == "true" ]]; then + for item in "${items_to_clean[@]}"; do + local item_size + item_size=$(get_path_size_kb "$item" 2> /dev/null) || item_size=0 + [[ "$item_size" =~ ^[0-9]+$ ]] || item_size=0 + candidate_changed=true + ((candidate_size_kb += item_size)) + done + else + for item in "${items_to_clean[@]}"; do + local item_size + item_size=$(get_path_size_kb "$item" 2> /dev/null) || item_size=0 + [[ "$item_size" =~ ^[0-9]+$ ]] || item_size=0 + if safe_remove "$item" true 2> /dev/null; then + candidate_changed=true + ((candidate_size_kb += item_size)) + fi + done + fi + if [[ "$candidate_changed" == "true" ]]; then ((total_size += candidate_size_kb)) ((cleaned_count++)) @@ -573,7 +594,6 @@ clean_group_container_caches() { done done - eval "$_ng_state" stop_section_spinner if [[ "$found_any" == "true" ]]; then @@ -681,8 +701,10 @@ clean_application_support_logs() { shopt -s nullglob for app_dir in ~/Library/Application\ Support/*; do [[ -d "$app_dir" ]] || continue - local app_name=$(basename "$app_dir") - local app_name_lower=$(echo "$app_name" | LC_ALL=C tr '[:upper:]' '[:lower:]') + local app_name + app_name=$(basename "$app_dir") + local app_name_lower + app_name_lower=$(echo "$app_name" | LC_ALL=C tr '[:upper:]' '[:lower:]') local is_protected=false if should_protect_data "$app_name"; then is_protected=true @@ -699,20 +721,17 @@ clean_application_support_logs() { for candidate in "${start_candidates[@]}"; do if [[ -d "$candidate" ]]; then if find "$candidate" -mindepth 1 -maxdepth 1 -print -quit 2> /dev/null | grep -q .; then - local size=$(get_path_size_kb "$candidate") + local size + size=$(get_path_size_kb "$candidate") ((total_size += size)) ((cleaned_count++)) found_any=true if [[ "$DRY_RUN" != "true" ]]; then - # For directories with many files, use find -delete for performance - # This avoids shell expansion and individual safe_remove calls - if ! find "$candidate" -mindepth 1 -delete 2> /dev/null; then - # Fallback: try item-by-item if find fails - for item in "$candidate"/*; do - [[ -e "$item" ]] || continue - safe_remove "$item" true > /dev/null 2>&1 || true - done - fi + local item + while IFS= read -r -d '' item; do + [[ -e "$item" ]] || continue + safe_remove "$item" true > /dev/null 2>&1 || true + done < <(command find "$candidate" -mindepth 1 -maxdepth 1 -print0 2> /dev/null || true) fi fi fi @@ -728,20 +747,17 @@ clean_application_support_logs() { for candidate in "${gc_candidates[@]}"; do if [[ -d "$candidate" ]]; then if find "$candidate" -mindepth 1 -maxdepth 1 -print -quit 2> /dev/null | grep -q .; then - local size=$(get_path_size_kb "$candidate") + local size + size=$(get_path_size_kb "$candidate") ((total_size += size)) ((cleaned_count++)) found_any=true if [[ "$DRY_RUN" != "true" ]]; then - # For directories with many files, use find -delete for performance - # This avoids shell expansion and individual safe_remove calls - if ! find "$candidate" -mindepth 1 -delete 2> /dev/null; then - # Fallback: try item-by-item if find fails - for item in "$candidate"/*; do - [[ -e "$item" ]] || continue - safe_remove "$item" true > /dev/null 2>&1 || true - done - fi + local item + while IFS= read -r -d '' item; do + [[ -e "$item" ]] || continue + safe_remove "$item" true > /dev/null 2>&1 || true + done < <(command find "$candidate" -mindepth 1 -maxdepth 1 -print0 2> /dev/null || true) fi fi fi @@ -750,7 +766,8 @@ clean_application_support_logs() { eval "$_ng_state" stop_section_spinner if [[ "$found_any" == "true" ]]; then - local size_human=$(bytes_to_human "$((total_size * 1024))") + local size_human + size_human=$(bytes_to_human "$((total_size * 1024))") if [[ "$DRY_RUN" == "true" ]]; then echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} Application Support logs/caches${NC}, ${YELLOW}$size_human dry${NC}" else @@ -767,9 +784,11 @@ check_ios_device_backups() { local backup_dir="$HOME/Library/Application Support/MobileSync/Backup" # Simplified check without find to avoid hanging. if [[ -d "$backup_dir" ]]; then - local backup_kb=$(get_path_size_kb "$backup_dir") + local backup_kb + backup_kb=$(get_path_size_kb "$backup_dir") if [[ -n "${backup_kb:-}" && "$backup_kb" -gt 102400 ]]; then - local backup_human=$(command du -shP "$backup_dir" 2> /dev/null | awk '{print $1}') + local backup_human + backup_human=$(command du -shP "$backup_dir" 2> /dev/null | awk '{print $1}') if [[ -n "$backup_human" ]]; then note_activity echo -e " ${YELLOW}${ICON_WARNING}${NC} iOS backups: ${GREEN}${backup_human}${NC}${GRAY}, Path: $backup_dir${NC}" diff --git a/tests/clean_core.bats b/tests/clean_core.bats index d526d7b..3994c64 100644 --- a/tests/clean_core.bats +++ b/tests/clean_core.bats @@ -107,7 +107,7 @@ EOF [ -f "$HOME/Documents/.DS_Store" ] } -@test "clean_recent_items removes shared file lists" { +@test "_clean_recent_items removes shared file lists" { local shared_dir="$HOME/Library/Application Support/com.apple.sharedfilelist" mkdir -p "$shared_dir" touch "$shared_dir/com.apple.LSSharedFileList.RecentApplications.sfl2" @@ -120,14 +120,14 @@ source "$PROJECT_ROOT/lib/clean/user.sh" safe_clean() { echo "safe_clean $1" } -clean_recent_items +_clean_recent_items EOF [ "$status" -eq 0 ] [[ "$output" == *"Recent"* ]] } -@test "clean_recent_items handles missing shared directory" { +@test "_clean_recent_items handles missing shared directory" { rm -rf "$HOME/Library/Application Support/com.apple.sharedfilelist" run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc << 'EOF' @@ -137,13 +137,13 @@ source "$PROJECT_ROOT/lib/clean/user.sh" safe_clean() { echo "safe_clean $1" } -clean_recent_items +_clean_recent_items EOF [ "$status" -eq 0 ] } -@test "clean_mail_downloads skips cleanup when size below threshold" { +@test "_clean_mail_downloads skips cleanup when size below threshold" { mkdir -p "$HOME/Library/Mail Downloads" echo "test" > "$HOME/Library/Mail Downloads/small.txt" @@ -151,14 +151,14 @@ EOF set -euo pipefail source "$PROJECT_ROOT/lib/core/common.sh" source "$PROJECT_ROOT/lib/clean/user.sh" -clean_mail_downloads +_clean_mail_downloads EOF [ "$status" -eq 0 ] [ -f "$HOME/Library/Mail Downloads/small.txt" ] } -@test "clean_mail_downloads removes old attachments" { +@test "_clean_mail_downloads removes old attachments" { mkdir -p "$HOME/Library/Mail Downloads" touch "$HOME/Library/Mail Downloads/old.pdf" touch -t 202301010000 "$HOME/Library/Mail Downloads/old.pdf" @@ -171,7 +171,7 @@ EOF set -euo pipefail source "$PROJECT_ROOT/lib/core/common.sh" source "$PROJECT_ROOT/lib/clean/user.sh" -clean_mail_downloads +_clean_mail_downloads EOF [ "$status" -eq 0 ] diff --git a/tests/clean_user_core.bats b/tests/clean_user_core.bats index ea21343..437f476 100644 --- a/tests/clean_user_core.bats +++ b/tests/clean_user_core.bats @@ -38,22 +38,27 @@ EOF [[ "$output" != *"Trash"* ]] } -@test "clean_macos_system_caches calls safe_clean for core paths" { +@test "clean_app_caches includes macOS system caches" { run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF' set -euo pipefail source "$PROJECT_ROOT/lib/core/common.sh" source "$PROJECT_ROOT/lib/clean/user.sh" stop_section_spinner() { :; } +start_section_spinner() { :; } safe_clean() { echo "$2"; } -clean_macos_system_caches +bytes_to_human() { echo "0B"; } +note_activity() { :; } +files_cleaned=0 +total_size_cleaned=0 +total_items=0 +clean_app_caches EOF [ "$status" -eq 0 ] - [[ "$output" == *"Saved application states"* ]] - [[ "$output" == *"QuickLook"* ]] + [[ "$output" == *"Saved application states"* ]] || [[ "$output" == *"App caches"* ]] } -@test "clean_sandboxed_app_caches skips protected containers" { +@test "clean_app_caches skips protected containers" { run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" DRY_RUN=true /bin/bash --noprofile --norc <<'EOF' set -euo pipefail source "$PROJECT_ROOT/lib/core/common.sh" @@ -69,12 +74,12 @@ files_cleaned=0 total_size_cleaned=0 total_items=0 mkdir -p "$HOME/Library/Containers/com.example.app/Data/Library/Caches" -process_container_cache "$HOME/Library/Containers/com.example.app" -clean_sandboxed_app_caches +touch "$HOME/Library/Containers/com.example.app/Data/Library/Caches/test.cache" +clean_app_caches EOF [ "$status" -eq 0 ] - [[ "$output" != *"Sandboxed app caches"* ]] + [[ "$output" != *"App caches"* ]] || [[ "$output" == *"already clean"* ]] } @test "clean_group_container_caches keeps protected caches and cleans non-protected caches" {