Skip to content

Commit 50efe51

Browse files
committed
fix(clean): guard empty Xcode DeviceSupport arrays
1 parent b12308f commit 50efe51

File tree

2 files changed

+55
-35
lines changed

2 files changed

+55
-35
lines changed

lib/clean/dev.sh

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -359,47 +359,49 @@ clean_xcode_device_support() {
359359
version_dirs+=("$entry")
360360
done < <(command find "$ds_dir" -mindepth 1 -maxdepth 1 -print0 2> /dev/null)
361361

362-
# Sort by modification time (most recent first)
363-
local -a sorted_dirs=()
364-
while IFS= read -r line; do
365-
sorted_dirs+=("${line#* }")
366-
done < <(
367-
for entry in "${version_dirs[@]}"; do
368-
printf '%s %s\n' "$(stat -f%m "$entry" 2> /dev/null || echo 0)" "$entry"
369-
done | sort -rn
370-
)
371-
372-
# Get stale versions (everything after keep_count)
373-
local -a stale_dirs=("${sorted_dirs[@]:$keep_count}")
362+
if [[ ${#version_dirs[@]} -gt 0 ]]; then
363+
# Sort by modification time (most recent first)
364+
local -a sorted_dirs=()
365+
while IFS= read -r line; do
366+
sorted_dirs+=("${line#* }")
367+
done < <(
368+
for entry in "${version_dirs[@]}"; do
369+
printf '%s %s\n' "$(stat -f%m "$entry" 2> /dev/null || echo 0)" "$entry"
370+
done | sort -rn
371+
)
374372

375-
if [[ ${#stale_dirs[@]} -gt 0 ]]; then
376-
# Calculate total size of stale versions
377-
local stale_size_kb=0 entry_size_kb
378-
for stale_entry in "${stale_dirs[@]}"; do
379-
entry_size_kb=$(get_path_size_kb "$stale_entry" 2> /dev/null || echo 0)
380-
stale_size_kb=$((stale_size_kb + entry_size_kb))
381-
done
382-
local stale_size_human
383-
stale_size_human=$(bytes_to_human "$((stale_size_kb * 1024))")
373+
# Get stale versions (everything after keep_count)
374+
local -a stale_dirs=("${sorted_dirs[@]:$keep_count}")
384375

385-
if [[ "$DRY_RUN" == "true" ]]; then
386-
echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} ${display_name} · would remove ${#stale_dirs[@]} old versions (${stale_size_human}), keeping ${keep_count} most recent"
387-
note_activity
388-
else
389-
# Remove old versions
390-
local removed_count=0
376+
if [[ ${#stale_dirs[@]} -gt 0 ]]; then
377+
# Calculate total size of stale versions
378+
local stale_size_kb=0 entry_size_kb
391379
for stale_entry in "${stale_dirs[@]}"; do
392-
if should_protect_path "$stale_entry" || is_path_whitelisted "$stale_entry"; then
393-
continue
394-
fi
395-
if safe_remove "$stale_entry"; then
396-
removed_count=$((removed_count + 1))
397-
fi
380+
entry_size_kb=$(get_path_size_kb "$stale_entry" 2> /dev/null || echo 0)
381+
stale_size_kb=$((stale_size_kb + entry_size_kb))
398382
done
383+
local stale_size_human
384+
stale_size_human=$(bytes_to_human "$((stale_size_kb * 1024))")
399385

400-
if [[ $removed_count -gt 0 ]]; then
401-
echo -e " ${GREEN}${ICON_SUCCESS}${NC} ${display_name} · removed ${removed_count} old versions, ${stale_size_human}"
386+
if [[ "$DRY_RUN" == "true" ]]; then
387+
echo -e " ${YELLOW}${ICON_DRY_RUN}${NC} ${display_name} · would remove ${#stale_dirs[@]} old versions (${stale_size_human}), keeping ${keep_count} most recent"
402388
note_activity
389+
else
390+
# Remove old versions
391+
local removed_count=0
392+
for stale_entry in "${stale_dirs[@]}"; do
393+
if should_protect_path "$stale_entry" || is_path_whitelisted "$stale_entry"; then
394+
continue
395+
fi
396+
if safe_remove "$stale_entry"; then
397+
removed_count=$((removed_count + 1))
398+
fi
399+
done
400+
401+
if [[ $removed_count -gt 0 ]]; then
402+
echo -e " ${GREEN}${ICON_SUCCESS}${NC} ${display_name} · removed ${removed_count} old versions, ${stale_size_human}"
403+
note_activity
404+
fi
403405
fi
404406
fi
405407
fi

tests/dev_extended.bats

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,24 @@ EOF
136136
[[ "$output" != *"NDK versions"* ]]
137137
}
138138

139+
@test "clean_xcode_device_support handles empty directories under nounset" {
140+
local ds_dir="$HOME/EmptyDeviceSupport"
141+
mkdir -p "$ds_dir"
142+
143+
run env HOME="$HOME" PROJECT_ROOT="$PROJECT_ROOT" bash --noprofile --norc <<'EOF'
144+
set -euo pipefail
145+
source "$PROJECT_ROOT/lib/core/common.sh"
146+
source "$PROJECT_ROOT/lib/clean/dev.sh"
147+
note_activity() { :; }
148+
safe_clean() { :; }
149+
clean_xcode_device_support "$HOME/EmptyDeviceSupport" "iOS DeviceSupport"
150+
echo "survived"
151+
EOF
152+
153+
[ "$status" -eq 0 ]
154+
[[ "$output" == *"survived"* ]]
155+
}
156+
139157
@test "clean_xcode_documentation_cache keeps newest DeveloperDocumentation index" {
140158
local doc_root="$HOME/DocumentationCache"
141159
mkdir -p "$doc_root"

0 commit comments

Comments
 (0)