-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuninstall.sh
More file actions
executable file
·578 lines (495 loc) · 16.6 KB
/
uninstall.sh
File metadata and controls
executable file
·578 lines (495 loc) · 16.6 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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
#!/bin/sh
# revoco uninstaller script
# Usage: curl -fsSL https://raw.githubusercontent.com/fulgidus/revoco/main/uninstall.sh | bash
#
# Options:
# --yes Skip all prompts and remove everything
# --help Show help message
#
# Note: When piped (non-interactive), --yes is required to proceed.
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
BOLD='\033[1m'
NC='\033[0m' # No Color
# Paths
CONFIG_DIR="$HOME/.config/revoco"
SESSIONS_DIR="$HOME/.revoco/sessions"
INSTALL_INFO="$CONFIG_DIR/install.json"
# Detect cache directory
detect_cache_dir() {
case "$(uname -s)" in
Darwin*|Linux*)
echo "$HOME/.cache/revoco"
;;
CYGWIN*|MINGW*|MSYS*)
echo "$LOCALAPPDATA/revoco"
;;
*)
echo "$HOME/.cache/revoco"
;;
esac
}
CACHE_DIR=$(detect_cache_dir)
# Options
SKIP_PROMPTS=false
SHOW_HELP=false
info() {
printf "${BLUE}[INFO]${NC} %s\n" "$1"
}
success() {
printf "${GREEN}[OK]${NC} %s\n" "$1"
}
warn() {
printf "${YELLOW}[WARN]${NC} %s\n" "$1"
}
error() {
printf "${RED}[ERROR]${NC} %s\n" "$1"
exit 1
}
show_help() {
cat << 'EOF'
revoco uninstaller
Usage: uninstall.sh [OPTIONS]
Options:
--yes Skip all prompts and remove everything (binary, config, plugins, sessions, cache)
--help Show this help message
Examples:
# Interactive uninstall (will prompt for each component)
./uninstall.sh
# Non-interactive full removal
./uninstall.sh --yes
# Via curl (interactive - requires TTY)
curl -fsSL https://raw.githubusercontent.com/fulgidus/revoco/main/uninstall.sh | bash
# Via curl (non-interactive full removal)
curl -fsSL https://raw.githubusercontent.com/fulgidus/revoco/main/uninstall.sh | bash -s -- --yes
Components that may be removed:
- Binary: The revoco executable (location from install.json)
- Shell config: PATH configuration added to your shell profile
- Config: ~/.config/revoco/ (config files)
- Plugins: ~/.config/revoco/plugins/ (installed plugins)
- Sessions: ~/.revoco/sessions/ (your work sessions - DATA LOSS WARNING)
- Cache: ~/.cache/revoco/ (cached binary tools like exiftool)
EOF
}
# Ask a yes/no question, return 0 for yes, 1 for no
# Reads from /dev/tty if stdin is not a terminal (e.g., when piped via curl)
ask() {
prompt="$1"
default="$2" # "y" or "n"
if [ "$SKIP_PROMPTS" = true ]; then
return 0 # Always yes when --yes flag
fi
if [ "$default" = "y" ]; then
prompt_suffix="[Y/n]"
else
prompt_suffix="[y/N]"
fi
printf "${BOLD}%s${NC} %s " "$prompt" "$prompt_suffix"
# Read from /dev/tty if available (works when piped), otherwise stdin
if [ ! -t 0 ] && [ -e /dev/tty ]; then
read -r answer < /dev/tty
else
read -r answer
fi
case "$answer" in
[Yy]|[Yy][Ee][Ss])
return 0
;;
[Nn]|[Nn][Oo])
return 1
;;
"")
if [ "$default" = "y" ]; then
return 0
else
return 1
fi
;;
*)
return 1
;;
esac
}
# Get binary path from install.json or return empty
get_binary_path() {
if [ -f "$INSTALL_INFO" ]; then
# Parse JSON manually (portable)
grep '"binary_path"' "$INSTALL_INFO" 2>/dev/null | \
sed 's/.*"binary_path"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/' || true
fi
}
# Get shell config file from install.json or return empty
get_shell_config() {
if [ -f "$INSTALL_INFO" ]; then
grep '"shell_config_file"' "$INSTALL_INFO" 2>/dev/null | \
sed 's/.*"shell_config_file"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/' || true
fi
}
# Get update channel from config.json or return 'unknown'
get_update_channel() {
config_file="$CONFIG_DIR/config.json"
if [ -f "$config_file" ]; then
# Parse JSON manually (portable) - extract updates.channel value
grep '"channel"' "$config_file" 2>/dev/null | \
sed 's/.*"channel"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/' || echo "unknown"
else
echo "unknown (no config found)"
fi
}
# Remove PATH configuration from shell config file
# Returns 0 on success, 1 if not found or error
remove_path_config() {
shell_config="$1"
if [ -z "$shell_config" ] || [ ! -f "$shell_config" ]; then
return 1
fi
# Check if our markers exist
if ! grep -q "# Added by revoco installer" "$shell_config" 2>/dev/null; then
return 1
fi
# Create backup
cp "$shell_config" "${shell_config}.revoco-backup"
# Remove lines between markers (inclusive) using sed
# This handles the block: # Added by revoco installer ... # End revoco
if sed -i.bak '/# Added by revoco installer/,/# End revoco/d' "$shell_config" 2>/dev/null; then
rm -f "${shell_config}.bak"
# Clean up trailing empty lines at end of file
# Use a temp file approach for portability
while [ "$(tail -c 1 "$shell_config" 2>/dev/null | wc -l)" -eq 0 ] && \
[ "$(tail -n 1 "$shell_config" 2>/dev/null)" = "" ] && \
[ "$(wc -l < "$shell_config")" -gt 0 ]; do
# Remove last empty line
sed -i.bak '$ { /^$/d }' "$shell_config" 2>/dev/null || break
rm -f "${shell_config}.bak"
done
rm -f "${shell_config}.revoco-backup"
return 0
else
# Restore backup on failure
mv "${shell_config}.revoco-backup" "$shell_config"
return 1
fi
}
# Check if we can run interactively
# Returns true if stdin is a TTY, or if /dev/tty is available (piped via curl)
can_interact() {
[ -t 0 ] || [ -e /dev/tty ]
}
# Calculate directory size
dir_size() {
dir="$1"
if [ -d "$dir" ]; then
du -sh "$dir" 2>/dev/null | cut -f1 || echo "unknown"
else
echo "0"
fi
}
# Count files in directory
file_count() {
dir="$1"
if [ -d "$dir" ]; then
find "$dir" -type f 2>/dev/null | wc -l | tr -d ' '
else
echo "0"
fi
}
# Parse arguments
parse_args() {
while [ $# -gt 0 ]; do
case "$1" in
--yes|-y)
SKIP_PROMPTS=true
;;
--help|-h)
SHOW_HELP=true
;;
*)
warn "Unknown option: $1"
;;
esac
shift
done
}
# Main uninstallation
main() {
parse_args "$@"
if [ "$SHOW_HELP" = true ]; then
show_help
exit 0
fi
echo ""
info "revoco uninstaller"
echo ""
# Check if we can interact with user
if ! can_interact && [ "$SKIP_PROMPTS" = false ]; then
error "Cannot read user input. Use --yes flag to proceed without prompts.
Example:
curl -fsSL .../uninstall.sh | bash -s -- --yes"
fi
# Get binary path
BINARY_PATH=$(get_binary_path)
if [ -z "$BINARY_PATH" ]; then
warn "No install.json found - revoco may have been installed manually"
# Try to find it
if command -v revoco >/dev/null 2>&1; then
BINARY_PATH=$(command -v revoco)
info "Found revoco at: $BINARY_PATH"
else
warn "Could not locate revoco binary"
fi
else
info "Installation record found: $BINARY_PATH"
fi
# Get shell config file
SHELL_CONFIG_FILE=$(get_shell_config)
# Show what will be examined
echo ""
echo "Components found:"
echo ""
# Binary
if [ -n "$BINARY_PATH" ] && [ -f "$BINARY_PATH" ]; then
printf " Binary: %s\n" "$BINARY_PATH"
HAVE_BINARY=true
else
printf " Binary: ${YELLOW}not found${NC}\n"
HAVE_BINARY=false
fi
# Shell config
if [ -n "$SHELL_CONFIG_FILE" ] && [ -f "$SHELL_CONFIG_FILE" ] && \
grep -q "# Added by revoco installer" "$SHELL_CONFIG_FILE" 2>/dev/null; then
printf " Shell config: %s\n" "$SHELL_CONFIG_FILE"
HAVE_SHELL_CONFIG=true
else
printf " Shell config: ${YELLOW}not found${NC}\n"
HAVE_SHELL_CONFIG=false
fi
# Config
if [ -d "$CONFIG_DIR" ]; then
config_size=$(dir_size "$CONFIG_DIR")
printf " Config: %s (%s)\n" "$CONFIG_DIR" "$config_size"
HAVE_CONFIG=true
else
printf " Config: ${YELLOW}not found${NC}\n"
HAVE_CONFIG=false
fi
# Channel (informational, from config if present)
UPDATE_CHANNEL=$(get_update_channel)
printf " Channel: %s\n" "$UPDATE_CHANNEL"
# Plugins (subdirectory of config)
PLUGINS_DIR="$CONFIG_DIR/plugins"
if [ -d "$PLUGINS_DIR" ]; then
plugins_count=$(file_count "$PLUGINS_DIR")
plugins_size=$(dir_size "$PLUGINS_DIR")
printf " Plugins: %s (%s files, %s)\n" "$PLUGINS_DIR" "$plugins_count" "$plugins_size"
HAVE_PLUGINS=true
else
printf " Plugins: ${YELLOW}not found${NC}\n"
HAVE_PLUGINS=false
fi
# Sessions
if [ -d "$SESSIONS_DIR" ]; then
sessions_count=$(ls -1 "$SESSIONS_DIR" 2>/dev/null | wc -l | tr -d ' ')
sessions_size=$(dir_size "$SESSIONS_DIR")
printf " Sessions: %s (%s sessions, %s)\n" "$SESSIONS_DIR" "$sessions_count" "$sessions_size"
HAVE_SESSIONS=true
else
printf " Sessions: ${YELLOW}not found${NC}\n"
HAVE_SESSIONS=false
fi
# Cache
if [ -d "$CACHE_DIR" ]; then
cache_size=$(dir_size "$CACHE_DIR")
printf " Cache: %s (%s)\n" "$CACHE_DIR" "$cache_size"
HAVE_CACHE=true
else
printf " Cache: ${YELLOW}not found${NC}\n"
HAVE_CACHE=false
fi
echo ""
# Check if anything to remove
if [ "$HAVE_BINARY" = false ] && [ "$HAVE_SHELL_CONFIG" = false ] && \
[ "$HAVE_CONFIG" = false ] && [ "$HAVE_SESSIONS" = false ] && [ "$HAVE_CACHE" = false ]; then
success "Nothing to uninstall - revoco is not installed"
exit 0
fi
# Track what to remove
REMOVE_BINARY=false
REMOVE_SHELL_CONFIG=false
REMOVE_CONFIG=false
REMOVE_PLUGINS=false
REMOVE_SESSIONS=false
REMOVE_CACHE=false
# Ask about each component
if [ "$SKIP_PROMPTS" = true ]; then
REMOVE_BINARY=$HAVE_BINARY
REMOVE_SHELL_CONFIG=$HAVE_SHELL_CONFIG
REMOVE_CONFIG=$HAVE_CONFIG
REMOVE_PLUGINS=$HAVE_PLUGINS
REMOVE_SESSIONS=$HAVE_SESSIONS
REMOVE_CACHE=$HAVE_CACHE
else
echo "Select components to remove:"
echo ""
# Binary
if [ "$HAVE_BINARY" = true ]; then
if ask "Remove revoco binary?" "y"; then
REMOVE_BINARY=true
fi
fi
# Shell config
if [ "$HAVE_SHELL_CONFIG" = true ]; then
if ask "Remove PATH configuration from $SHELL_CONFIG_FILE?" "y"; then
REMOVE_SHELL_CONFIG=true
fi
fi
# Config (excluding plugins - ask separately)
if [ "$HAVE_CONFIG" = true ]; then
if ask "Remove configuration files?" "y"; then
REMOVE_CONFIG=true
fi
fi
# Plugins
if [ "$HAVE_PLUGINS" = true ]; then
if ask "Remove installed plugins?" "y"; then
REMOVE_PLUGINS=true
fi
fi
# Sessions - strong warning
if [ "$HAVE_SESSIONS" = true ]; then
echo ""
printf "${RED}${BOLD}WARNING:${NC} Sessions contain your work data (imported archives, processed files, etc.)\n"
printf " This action ${RED}CANNOT be undone${NC}.\n"
echo ""
if ask "Remove ALL sessions and their data?" "n"; then
REMOVE_SESSIONS=true
fi
fi
# Cache
if [ "$HAVE_CACHE" = true ]; then
if ask "Remove cached tools (exiftool, etc.)?" "y"; then
REMOVE_CACHE=true
fi
fi
fi
echo ""
# Summary of what will be removed
echo "Will remove:"
[ "$REMOVE_BINARY" = true ] && echo " - Binary: $BINARY_PATH"
[ "$REMOVE_SHELL_CONFIG" = true ] && echo " - Shell config: PATH entry in $SHELL_CONFIG_FILE"
[ "$REMOVE_CONFIG" = true ] && echo " - Config files"
[ "$REMOVE_PLUGINS" = true ] && echo " - Plugins"
[ "$REMOVE_SESSIONS" = true ] && printf " - ${RED}Sessions (DATA WILL BE LOST)${NC}\n"
[ "$REMOVE_CACHE" = true ] && echo " - Cache"
if [ "$REMOVE_BINARY" = false ] && [ "$REMOVE_SHELL_CONFIG" = false ] && \
[ "$REMOVE_CONFIG" = false ] && [ "$REMOVE_PLUGINS" = false ] && \
[ "$REMOVE_SESSIONS" = false ] && [ "$REMOVE_CACHE" = false ]; then
info "Nothing selected for removal"
exit 0
fi
echo ""
# Final confirmation (unless --yes)
if [ "$SKIP_PROMPTS" = false ]; then
if ! ask "Proceed with uninstallation?" "y"; then
info "Uninstallation cancelled"
exit 0
fi
fi
echo ""
info "Removing components..."
echo ""
# Perform removal
ERRORS=0
# Remove binary
if [ "$REMOVE_BINARY" = true ]; then
if rm -f "$BINARY_PATH" 2>/dev/null; then
success "Removed binary: $BINARY_PATH"
else
warn "Failed to remove binary: $BINARY_PATH (may need sudo)"
ERRORS=$((ERRORS + 1))
fi
fi
# Remove shell config PATH entry
if [ "$REMOVE_SHELL_CONFIG" = true ]; then
if remove_path_config "$SHELL_CONFIG_FILE"; then
success "Removed PATH config from: $SHELL_CONFIG_FILE"
info "Restart your terminal for changes to take effect"
else
warn "Failed to remove PATH config from: $SHELL_CONFIG_FILE"
ERRORS=$((ERRORS + 1))
fi
fi
# Remove plugins (before config, as it's inside config dir)
if [ "$REMOVE_PLUGINS" = true ]; then
if rm -rf "$PLUGINS_DIR" 2>/dev/null; then
success "Removed plugins: $PLUGINS_DIR"
else
warn "Failed to remove plugins: $PLUGINS_DIR"
ERRORS=$((ERRORS + 1))
fi
fi
# Remove config
if [ "$REMOVE_CONFIG" = true ]; then
# If not removing plugins, just remove config files
if [ "$REMOVE_PLUGINS" = false ] && [ -d "$PLUGINS_DIR" ]; then
# Remove only config files, keep plugins
rm -f "$CONFIG_DIR/config.json" 2>/dev/null
rm -f "$CONFIG_DIR/plugins.json" 2>/dev/null
rm -f "$CONFIG_DIR/install.json" 2>/dev/null
success "Removed config files (kept plugins)"
else
# Remove entire config directory
if rm -rf "$CONFIG_DIR" 2>/dev/null; then
success "Removed config: $CONFIG_DIR"
else
warn "Failed to remove config: $CONFIG_DIR"
ERRORS=$((ERRORS + 1))
fi
fi
fi
# Remove sessions
if [ "$REMOVE_SESSIONS" = true ]; then
if rm -rf "$SESSIONS_DIR" 2>/dev/null; then
success "Removed sessions: $SESSIONS_DIR"
# Also remove parent .revoco if empty
rmdir "$HOME/.revoco" 2>/dev/null || true
else
warn "Failed to remove sessions: $SESSIONS_DIR"
ERRORS=$((ERRORS + 1))
fi
fi
# Remove cache
if [ "$REMOVE_CACHE" = true ]; then
if rm -rf "$CACHE_DIR" 2>/dev/null; then
success "Removed cache: $CACHE_DIR"
else
warn "Failed to remove cache: $CACHE_DIR"
ERRORS=$((ERRORS + 1))
fi
fi
echo ""
# Final summary
if [ $ERRORS -eq 0 ]; then
success "Uninstallation complete!"
else
warn "Uninstallation completed with $ERRORS error(s)"
echo ""
echo "Some components may require manual removal or elevated privileges."
fi
# Show what remains
echo ""
REMAINING=""
[ "$HAVE_BINARY" = true ] && [ "$REMOVE_BINARY" = false ] && REMAINING="$REMAINING binary"
[ "$HAVE_SHELL_CONFIG" = true ] && [ "$REMOVE_SHELL_CONFIG" = false ] && REMAINING="$REMAINING shell-config"
[ "$HAVE_CONFIG" = true ] && [ "$REMOVE_CONFIG" = false ] && REMAINING="$REMAINING config"
[ "$HAVE_PLUGINS" = true ] && [ "$REMOVE_PLUGINS" = false ] && REMAINING="$REMAINING plugins"
[ "$HAVE_SESSIONS" = true ] && [ "$REMOVE_SESSIONS" = false ] && REMAINING="$REMAINING sessions"
[ "$HAVE_CACHE" = true ] && [ "$REMOVE_CACHE" = false ] && REMAINING="$REMAINING cache"
if [ -n "$REMAINING" ]; then
info "Kept:$REMAINING"
fi
}
main "$@"