-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcleanup.sh
More file actions
executable file
·161 lines (141 loc) · 4.77 KB
/
cleanup.sh
File metadata and controls
executable file
·161 lines (141 loc) · 4.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#!/usr/bin/env bash
set -euo pipefail
confirm() {
read -r -p "Proceed? [y/N] " ans
[[ "${ans:-N}" =~ ^[Yy]$ ]]
}
echo "== Disk usage before =="
df -h /
echo "== Docker =="
docker system df || true
echo "Prune Docker builders & caches (keeps running containers)."
if confirm; then
docker builder prune -af || true
docker system prune -af || true
docker volume prune -f || true
fi
echo "== Xcode =="
echo "Delete DerivedData, Archives, old DeviceSupport?"
if confirm; then
killall Xcode Simulator 2>/dev/null || true
rm -rf ~/Library/Developer/Xcode/DerivedData/*
rm -rf ~/Library/Developer/Xcode/Archives/*
# --- Interactive iOS DeviceSupport cleanup (macOS/Bash 3.2 compatible) ---
echo "List of installed iOS DeviceSupport folders:"
devs=()
while IFS= read -r -d '' d; do devs+=("$d"); done < <(find ~/Library/Developer/Xcode/iOS\ DeviceSupport -maxdepth 1 -mindepth 1 -type d -print0 2>/dev/null)
if ((${#devs[@]} == 0)); then
echo "(none found)"
else
for i in "${!devs[@]}"; do
base="$(basename "${devs[$i]}")"
printf "[%d] %s\n" "$i" "$base"
done
echo
echo "Choose DeviceSupport cleanup mode:"
echo " (K) Keep specific indices (delete all others)"
echo " (D) Delete specific indices (keep all others)"
read -r -p "Mode [K/D] (default K): " mode
mode=${mode:-K}
# Indexed array to mark selections (works in Bash 3.2)
pick=()
parse_indices() {
local raw="$1"; raw="${raw//,/ }"
for idx in $raw; do
if [[ "$idx" =~ ^[0-9]+$ ]] && (( idx >= 0 && idx < ${#devs[@]} )); then
pick[$idx]=1
else
echo "Skipping invalid index: $idx"
fi
done
}
if [[ "$mode" =~ ^[Kk]$ ]]; then
echo
echo "Enter indices to KEEP (comma-separated). Leave blank to keep the 2 most recently modified."
read -r -p "Keep indices: " keep_input
if [[ -z "$keep_input" ]]; then
# Find the two newest by mtime (portable with BSD tools)
pairs=()
for i in "${!devs[@]}"; do
m=$(stat -f %m "${devs[$i]}") || m=0
pairs+=("$m:$i")
done
IFS=$'\n' sorted=( $(printf '%s\n' "${pairs[@]}" | sort -rn) ); unset IFS
last_idx="${sorted[0]#*:}"
prev_idx="${sorted[1]#*:}"
[[ -n "$last_idx" ]] && pick[$last_idx]=1
[[ -n "$prev_idx" ]] && pick[$prev_idx]=1
echo "Keeping indices: ${prev_idx:-} ${last_idx:-} (newest two), deleting the rest."
else
parse_indices "$keep_input"
echo "Keeping indices: ${!pick[*]}"
fi
# Delete any DeviceSupport not in the keep set
for i in "${!devs[@]}"; do
if [[ -z "${pick[$i]:-}" ]]; then
echo "Deleting: [${i}] $(basename "${devs[$i]}")"
rm -rf "${devs[$i]}"
fi
done
else
echo
echo "Enter indices to DELETE (comma-separated). Leave blank to skip DeviceSupport deletion."
read -r -p "Delete indices: " del_input
if [[ -n "$del_input" ]]; then
parse_indices "$del_input"
for i in "${!pick[@]}"; do
echo "Deleting: [${i}] $(basename "${devs[$i]}")"
rm -rf "${devs[$i]}"
done
else
echo "No DeviceSupport deletion requested."
fi
fi
fi
# Simulator caches (safe to purge)
rm -rf ~/Library/Developer/CoreSimulator/Caches/*
fi
echo "== Package managers =="
echo "npm / yarn / pnpm caches?"
if confirm; then
npm cache clean --force || true
yarn cache clean || true
pnpm store prune || true
fi
echo "== Flutter / Gradle caches =="
if confirm; then
rm -rf ~/.pub-cache/* || true
rm -rf ~/.gradle/caches/* ~/.gradle/daemon/* || true
fi
echo "== VS Code caches =="
if confirm; then
rm -rf ~/Library/Application\ Support/Code/Cache/* 2>/dev/null || true
rm -rf ~/Library/Application\ Support/Code/CachedData/* 2>/dev/null || true
rm -rf ~/Library/Application\ Support/Code/Code\ Cache/* 2>/dev/null || true
rm -rf ~/Library/Application\ Support/Code/GPUCache/* 2>/dev/null || true
rm -rf ~/Library/Application\ Support/Code/Service\ Worker/CacheStorage/* || true
rm -rf ~/Library/Application\ Support/Code/User/workspaceStorage/* || true
fi
echo "== Multipass =="
multipass list --disk || true
echo "Run 'multipass purge' to free deleted instances."
read -r -p "Run purge now? [y/N] " mp
[[ "${mp:-N}" =~ ^[Yy]$ ]] && multipass purge || true
echo "== Homebrew =="
if confirm; then
brew cleanup -s || true
rm -rf ~/Library/Caches/Homebrew/* || true
fi
echo "== General macOS caches & logs (Requires Sudo) =="
if confirm; then
rm -rf ~/Library/Caches/* || true
qlmanage -r cache || true
rm -rf ~/Library/Logs/* || true
fi
echo "== Git aggressive GC in current repo? (runs in ./) =="
if confirm; then
git gc --prune=now --aggressive || true
fi
echo "== Disk usage after =="
df -h /
echo "Done."