-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclean.sh
More file actions
executable file
·193 lines (170 loc) · 5.58 KB
/
Copy pathclean.sh
File metadata and controls
executable file
·193 lines (170 loc) · 5.58 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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#!/usr/bin/env bash
# Removes every trace of Allofit from the system: launchd services, cache
# files, user preferences, build artifacts and log files. Useful for a
# clean reinstall test or to fully uninstall. Can be called from anywhere -
# paths are resolved relative to the script's own location.
#
# Usage:
# ./scripts/clean.sh # from project root
# scripts/clean.sh --keep-build # leave .build/ and outputs/ in place
# ./clean.sh --keep-prefs # from scripts/, keep user prefs
# ./clean.sh --dry-run # print what would happen, change nothing
set -uo pipefail
# ==================
# MARK: Constants
# ==================
kBundleId="com.bitsycore.allofit"
kServiceLabel="${kBundleId}.service"
kServicePlistName="${kServiceLabel}.plist"
kUserAgentPlist="$HOME/Library/LaunchAgents/${kServicePlistName}"
kSystemDaemonPlist="/Library/LaunchDaemons/${kServicePlistName}"
kUserCacheDir="$HOME/Library/Application Support/Allofit"
kSystemCacheDir="/Library/Application Support/Allofit"
kUserPrefsPlist="$HOME/Library/Preferences/${kBundleId}.plist"
kServiceLogStdout="/tmp/allofit-service.log"
kServiceLogStderr="/tmp/allofit-service.err"
# ==================
# MARK: Args
# ==================
# Resolve the project root from the script's own location (scripts/..),
# so this script works regardless of the caller's CWD.
vProjectRoot="$(cd "$(dirname "$0")/.." && pwd)"
vKeepBuild=0
vKeepPrefs=0
vDryRun=0
for vArg in "$@"; do
case "$vArg" in
--keep-build) vKeepBuild=1 ;;
--keep-prefs) vKeepPrefs=1 ;;
--dry-run|-n) vDryRun=1 ;;
-h|--help)
# print the comment block at the top of this file
sed -n '2,/^set /p' "$0" | sed -E 's/^#( |$)//;/^set /d'
exit 0
;;
*)
echo "Unknown argument: $vArg" >&2
exit 1
;;
esac
done
# ==================
# MARK: Helpers
# ==================
# runs a command, or just prints it under --dry-run
vRun() {
if [[ "$vDryRun" -eq 1 ]]; then
echo " [dry-run] $*"
else
"$@"
fi
}
# caches a sudo session once so later sudo calls don't re-prompt
vGotSudo=0
vNeedsSudo() {
if [[ "$vGotSudo" -eq 0 ]]; then
if [[ "$vDryRun" -eq 1 ]]; then
echo " [dry-run] sudo -v"
else
echo "==> Acquiring sudo (for /Library cleanup)"
sudo -v
fi
vGotSudo=1
fi
}
# stops a launchd job by plist path then deletes the plist
# inDomain inPlist [inSudo]
vRemoveLaunchd() {
local inDomain="$1"
local inPlist="$2"
local inSudo="${3:-}"
if [[ ! -f "$inPlist" ]]; then return 0; fi
if [[ -n "$inSudo" ]]; then vNeedsSudo; fi
vRun $inSudo launchctl bootout "$inDomain" "$inPlist" >/dev/null 2>&1 || true
vRun $inSudo launchctl unload -w "$inPlist" >/dev/null 2>&1 || true
vRun $inSudo rm -f "$inPlist"
}
# ==================
# MARK: launchd services
# ==================
echo "==> Stopping & removing user LaunchAgent (if present)"
vRemoveLaunchd "gui/$(id -u)" "$kUserAgentPlist"
if [[ -f "$kSystemDaemonPlist" ]]; then
echo "==> Stopping & removing system LaunchDaemon"
vRemoveLaunchd "system" "$kSystemDaemonPlist" "sudo"
fi
echo "==> Killing any leftover daemon processes"
# `pkill -f` matches against the full command line; the daemon binary is
# now installed as ".../Allofit service" (renamed copy), so the literal
# "Allofit --service" no longer appears - use a regex that handles both
# the legacy and the renamed binary by anchoring on "Allofit...--service"
vRun pkill -f "Allofit.*--service" >/dev/null 2>&1 || true
# ==================
# MARK: Cache files
# ==================
if [[ -d "$kUserCacheDir" ]]; then
echo "==> Removing user cache directory"
vRun rm -rf "$kUserCacheDir"
fi
if [[ -d "$kSystemCacheDir" ]]; then
echo "==> Removing system cache directory"
vNeedsSudo
vRun sudo rm -rf "$kSystemCacheDir"
fi
# ==================
# MARK: Preferences
# ==================
if [[ "$vKeepPrefs" -eq 0 ]]; then
echo "==> Removing user preferences"
# defaults handles cfprefsd's cached copy in addition to the on-disk plist
vRun defaults delete "$kBundleId" >/dev/null 2>&1 || true
# also clear the SwiftPM "swift run" domain, which may differ from the
# bundled .app's domain depending on how the binary was launched
vRun defaults delete "Allofit" >/dev/null 2>&1 || true
vRun rm -f "$kUserPrefsPlist"
# wipe ByHost variants if any
shopt -s nullglob
for vByHost in "$HOME/Library/Preferences/ByHost/${kBundleId}".*.plist; do
vRun rm -f "$vByHost"
done
shopt -u nullglob
fi
# ==================
# MARK: Logs
# ==================
if [[ -f "$kServiceLogStdout" || -f "$kServiceLogStderr" ]]; then
echo "==> Removing service log files"
# /tmp has the sticky bit, so only the file's owner can rm it. Logs
# left over from a previous *root* daemon run are owned by root - we
# need sudo to delete them. Plain rm for user-owned logs (user agent
# mode), sudo rm for root-owned ones.
for vLog in "$kServiceLogStdout" "$kServiceLogStderr"; do
if [[ -f "$vLog" ]]; then
if [[ -O "$vLog" ]]; then
vRun rm -f "$vLog"
else
vNeedsSudo
vRun sudo rm -f "$vLog"
fi
fi
done
fi
# ==================
# MARK: Build artifacts
# ==================
if [[ "$vKeepBuild" -eq 0 ]]; then
if [[ -d "${vProjectRoot}/.build" ]]; then
echo "==> Removing SwiftPM .build directory"
vRun rm -rf "${vProjectRoot}/.build"
fi
if [[ -d "${vProjectRoot}/outputs" ]]; then
echo "==> Removing outputs/ directory (built .app and .dmg)"
vRun rm -rf "${vProjectRoot}/outputs"
fi
fi
echo
echo "Clean complete."
echo
echo "Note: any Full Disk Access grant in System Settings → Privacy & Security"
echo "still points at the previous binary location. Remove it manually if you"
echo "intend to install Allofit at a different path."