From 950af1a5ede9c0619de22ebd8e6cca9ed24a9729 Mon Sep 17 00:00:00 2001 From: tw93 Date: Sun, 15 Feb 2026 08:45:47 +0800 Subject: [PATCH] Improve clean progress visibility for dev runtime scans --- lib/clean/caches.sh | 1 + lib/clean/dev.sh | 72 ++++++++++++++++++++++------------------- tests/dev_extended.bats | 46 ++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 33 deletions(-) diff --git a/lib/clean/caches.sh b/lib/clean/caches.sh index cdfe86a..41cbb23 100644 --- a/lib/clean/caches.sh +++ b/lib/clean/caches.sh @@ -149,6 +149,7 @@ clean_project_caches() { fi [[ "$has_dev_projects" == "false" ]] && return 0 fi + echo -e " ${GRAY}${ICON_LIST}${NC} Project caches · scanning for Next.js/Python/Flutter artifacts" if [[ -t 1 ]]; then MOLE_SPINNER_PREFIX=" " start_inline_spinner "Searching project caches..." diff --git a/lib/clean/dev.sh b/lib/clean/dev.sh index 6506ed1..3ea2a68 100644 --- a/lib/clean/dev.sh +++ b/lib/clean/dev.sh @@ -319,7 +319,6 @@ clean_xcode_simulator_runtime_volumes() { [[ -n "$line" ]] && mount_points+=("$line") done < <(_sim_runtime_mount_points) - local -a size_values=() local -a entry_statuses=() local -a sorted_candidates=() local sorted @@ -327,39 +326,48 @@ clean_xcode_simulator_runtime_volumes() { [[ -n "$sorted" ]] && sorted_candidates+=("$sorted") done < <(printf '%s\n' "${candidates[@]}" | LC_ALL=C sort) - local idx=0 + echo -e " ${GRAY}${ICON_LIST}${NC} Xcode runtime volumes · scanning ${#sorted_candidates[@]} entries" + local runtime_scan_spinner=false + if [[ -t 1 ]]; then + start_section_spinner "Scanning Xcode runtime volumes..." + runtime_scan_spinner=true + fi + + local in_use_count=0 + local unused_count=0 for candidate in "${sorted_candidates[@]}"; do local status="UNUSED" if _sim_runtime_is_path_in_use "$candidate" "${mount_points[@]}"; then status="IN_USE" - fi - - local size_kb - size_kb=$(_sim_runtime_size_kb "$candidate") - size_values+=("$size_kb") - entry_statuses+=("$status") - idx=$((idx + 1)) - done - - local in_use_count=0 - local unused_count=0 - local in_use_kb=0 - local unused_kb=0 - local status - local i=0 - for status in "${entry_statuses[@]}"; do - local entry_size_kb="${size_values[$i]:-0}" - if [[ "$status" == "IN_USE" ]]; then in_use_count=$((in_use_count + 1)) - in_use_kb=$((in_use_kb + entry_size_kb)) else unused_count=$((unused_count + 1)) - unused_kb=$((unused_kb + entry_size_kb)) fi - i=$((i + 1)) + entry_statuses+=("$status") done if [[ "$DRY_RUN" == "true" ]]; then + local -a size_values=() + local in_use_kb=0 + local unused_kb=0 + local i=0 + for candidate in "${sorted_candidates[@]}"; do + local size_kb + size_kb=$(_sim_runtime_size_kb "$candidate") + size_values+=("$size_kb") + local status="${entry_statuses[$i]:-UNUSED}" + if [[ "$status" == "IN_USE" ]]; then + in_use_kb=$((in_use_kb + size_kb)) + else + unused_kb=$((unused_kb + size_kb)) + fi + i=$((i + 1)) + done + if [[ "$runtime_scan_spinner" == "true" ]]; then + stop_section_spinner + runtime_scan_spinner=false + fi + echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} Xcode runtime volumes · ${unused_count} unused, ${in_use_count} in use" local dryrun_total_kb=$((unused_kb + in_use_kb)) local dryrun_total_human @@ -406,8 +414,6 @@ clean_xcode_simulator_runtime_volumes() { # Auto-clean all UNUSED runtime volumes (no user selection) local -a selected_paths=() - local -a selected_sizes_kb=() - local selected_total_kb=0 local skipped_protected=0 local i=0 for ((i = 0; i < ${#sorted_candidates[@]}; i++)); do @@ -420,10 +426,13 @@ clean_xcode_simulator_runtime_volumes() { continue fi selected_paths+=("$candidate_path") - selected_sizes_kb+=("${size_values[$i]:-0}") - selected_total_kb=$((selected_total_kb + ${size_values[$i]:-0})) done + if [[ "$runtime_scan_spinner" == "true" ]]; then + stop_section_spinner + runtime_scan_spinner=false + fi + if [[ ${#selected_paths[@]} -eq 0 ]]; then echo -e " ${GREEN}${ICON_SUCCESS}${NC} Xcode runtime volumes · nothing to clean" note_activity @@ -438,24 +447,21 @@ clean_xcode_simulator_runtime_volumes() { fi fi - local selected_human - selected_human=$(bytes_to_human "$((selected_total_kb * 1024))") - echo -e " ${GREEN}${ICON_SUCCESS}${NC} Xcode runtime volumes · cleaning ${#selected_paths[@]} unused, ${selected_human}" + echo -e " ${GREEN}${ICON_SUCCESS}${NC} Xcode runtime volumes · cleaning ${#selected_paths[@]} unused" if [[ $skipped_protected -gt 0 ]]; then echo -e " ${GRAY}${ICON_WARNING}${NC} Xcode runtime volumes · skipped ${skipped_protected} protected items" fi local removed_count=0 local removed_size_kb=0 - local i=0 local selected_path for selected_path in "${selected_paths[@]}"; do - local selected_size_kb="${selected_sizes_kb[$i]:-0}" + local selected_size_kb=0 + selected_size_kb=$(_sim_runtime_size_kb "$selected_path") if safe_sudo_remove "$selected_path"; then removed_count=$((removed_count + 1)) removed_size_kb=$((removed_size_kb + selected_size_kb)) fi - i=$((i + 1)) done if [[ $removed_count -gt 0 ]]; then diff --git a/tests/dev_extended.bats b/tests/dev_extended.bats index cbc4ee5..18f44a5 100644 --- a/tests/dev_extended.bats +++ b/tests/dev_extended.bats @@ -253,3 +253,49 @@ EOF [[ "$output" == *"/241.1"* ]] [[ "$output" != *"/241.2"* ]] } + +@test "clean_xcode_simulator_runtime_volumes shows scan progress and skips sizing in-use volumes" { + local volumes_root="$HOME/sim-volumes" + local cryptex_root="$HOME/sim-cryptex" + mkdir -p "$volumes_root/in-use-runtime" "$volumes_root/unused-runtime" + mkdir -p "$cryptex_root" + + run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" MOLE_XCODE_SIM_RUNTIME_VOLUMES_ROOT="$volumes_root" MOLE_XCODE_SIM_RUNTIME_CRYPTEX_ROOT="$cryptex_root" bash --noprofile --norc <<'EOF' +set -euo pipefail +source "$PROJECT_ROOT/lib/core/common.sh" +source "$PROJECT_ROOT/lib/clean/dev.sh" + +size_log="$HOME/size-calls.log" +: > "$size_log" +DRY_RUN=false + +note_activity() { :; } +has_sudo_session() { return 0; } +is_path_whitelisted() { return 1; } +should_protect_path() { return 1; } +_sim_runtime_mount_points() { + printf '%s\n' "$MOLE_XCODE_SIM_RUNTIME_VOLUMES_ROOT/in-use-runtime" +} +_sim_runtime_size_kb() { + local target_path="$1" + echo "$target_path" >> "$size_log" + echo "1" +} +safe_sudo_remove() { + local target_path="$1" + echo "REMOVE:$target_path" + return 0 +} + +clean_xcode_simulator_runtime_volumes +echo "SIZE_LOG_START" +cat "$size_log" +EOF + + [ "$status" -eq 0 ] + [[ "$output" == *"Xcode runtime volumes · scanning 2 entries"* ]] + [[ "$output" == *"Xcode runtime volumes · cleaning 1 unused"* ]] + [[ "$output" == *"REMOVE:$volumes_root/unused-runtime"* ]] + [[ "$output" == *"$volumes_root/unused-runtime"* ]] + [[ "$output" != *"$volumes_root/in-use-runtime"* ]] +}