-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuninstall.sh
More file actions
executable file
·125 lines (105 loc) · 4.43 KB
/
Copy pathuninstall.sh
File metadata and controls
executable file
·125 lines (105 loc) · 4.43 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
#!/usr/bin/env bash
set -euo pipefail
HOME_DIR="${HOME:?HOME is not set}"
COCO_INSTALL_DIR="${COCO_INSTALL_DIR:-${HOME_DIR}/.coco}"
COCO_SYSTEM_BIN="${COCO_SYSTEM_BIN:-/usr/local/bin/coco}"
COCO_BIN_DIR="${COCO_BIN_DIR:-}"
COCO_AGENT_DIR="${COCO_AGENT_DIR:-${COCO_CODING_AGENT_DIR:-${HOME_DIR}/.coco/agent}}"
die() { printf 'coco: %s\n' "$*" >&2; exit 1; }
info() { printf 'coco: %s\n' "$*"; }
canonical_path() {
local path=$1 parent name
parent="$(dirname "$path")"; name="$(basename "$path")"
[ -d "$parent" ] || return 1
(cd -P -- "$parent" && printf '%s/%s\n' "$(pwd -P)" "$name")
}
path_contains() {
local parent=$1 child=$2
[ "$parent" = "$child" ] || [ "${child#"$parent"/}" != "$child" ]
}
is_owned_install() {
[ -d "$COCO_INSTALL_DIR" ] && [ ! -L "$COCO_INSTALL_DIR" ] || return 1
[ -x "$COCO_INSTALL_DIR/bin/coco" ] &&
[ -f "$COCO_INSTALL_DIR/resources/provider-registry.v1.json" ] &&
[ -d "$COCO_INSTALL_DIR/node_modules" ] || return 1
if [ -f "$COCO_INSTALL_DIR/.coco-install-owner" ] && [ ! -L "$COCO_INSTALL_DIR/.coco-install-owner" ]; then
[ "$(<"$COCO_INSTALL_DIR/.coco-install-owner")" = "coco-install-v1" ]
return
fi
# v0.1.7 did not write a marker, so retain one-click removal for its default layout only.
[ "$COCO_INSTALL_DIR" = "$HOME_DIR/.coco" ]
}
is_managed_launcher() {
local path=$1 target="$COCO_INSTALL_DIR/bin/coco"
if [ -L "$path" ]; then
[ "$(readlink -- "$path")" = "$target" ]
return
fi
[ -f "$path" ] || return 1
if printf '%s\n' '#!/usr/bin/env bash' "exec \"$COCO_INSTALL_DIR/runtime/node/bin/node\" \"$target\" \"\$@\"" | cmp -s - "$path"; then return 0; fi
printf '#!/usr/bin/env bash\nexport PI_OFFLINE=1\nexport COCO_CODING_AGENT_DIR=%q\nexec %q %q "$@"\n' \
"$COCO_AGENT_DIR" "$COCO_INSTALL_DIR/runtime/node/bin/node" "$target" | cmp -s - "$path"
}
remove_managed_launcher() {
local path=$1
( [ -e "$path" ] || [ -L "$path" ] ) && is_managed_launcher "$path" || return 0
if [ -w "$(dirname "$path")" ]; then rm -f -- "$path"
elif command -v sudo >/dev/null 2>&1; then sudo rm -f -- "$path"
else die "Run as root to remove $path"
fi
}
is_managed_coweb() {
local path=$1 target="$COCO_BIN_DIR/coco"
[ -f "$path" ] && [ ! -L "$path" ] || return 1
grep -Fqx "exec \"$target\" coweb \"\$@\"" "$path" || grep -Fqx "exec \"$target\" web \"\$@\"" "$path"
}
remove_managed_coweb() {
local path=$1
( [ -e "$path" ] || [ -L "$path" ] ) && is_managed_coweb "$path" || return 0
rm -f "$path"
}
[ "$HOME_DIR" != "/" ] || die "Refusing to uninstall with HOME=/"
[ -n "$COCO_INSTALL_DIR" ] || die "COCO_INSTALL_DIR is empty"
[ "$COCO_INSTALL_DIR" != "/" ] || die "Refusing to remove COCO_INSTALL_DIR=/"
[ "$COCO_BIN_DIR" != "/" ] || die "Refusing to remove COCO_BIN_DIR=/"
CANONICAL_HOME="$(canonical_path "$HOME_DIR")" || die "Cannot resolve HOME"
CANONICAL_INSTALL="$(canonical_path "$COCO_INSTALL_DIR")" || die "Cannot resolve COCO_INSTALL_DIR"
[ "$CANONICAL_INSTALL" != "$CANONICAL_HOME" ] || die "Refusing to remove HOME"
path_contains "$CANONICAL_INSTALL" "$CANONICAL_HOME" && die "Refusing to remove an ancestor of HOME"
if [ -e "$COCO_AGENT_DIR" ] || [ -L "$COCO_AGENT_DIR" ]; then
CANONICAL_AGENT="$(canonical_path "$COCO_AGENT_DIR")" || die "Cannot resolve COCO_AGENT_DIR"
if path_contains "$CANONICAL_INSTALL" "$CANONICAL_AGENT" && [ "$CANONICAL_AGENT" != "$CANONICAL_INSTALL/agent" ]; then
die "Refusing to remove an ancestor of COCO_AGENT_DIR"
fi
fi
if [ -e "$COCO_INSTALL_DIR" ] || [ -L "$COCO_INSTALL_DIR" ]; then
is_owned_install || die "Refusing to remove an unrecognized CoCo installation: $COCO_INSTALL_DIR"
fi
info "Removing CoCo completely"
rm -rf -- \
"$COCO_INSTALL_DIR" \
"$HOME_DIR/.config/coco" \
"$HOME_DIR/.cache/coco" \
"$HOME_DIR/.local/share/coco" \
"$HOME_DIR/.local/state/coco"
remove_managed_launcher "$HOME_DIR/.local/bin/coco"
if [ -n "$COCO_BIN_DIR" ]; then
remove_managed_launcher "$COCO_BIN_DIR/coco"
remove_managed_coweb "$COCO_BIN_DIR/coweb"
remove_managed_coweb "$COCO_BIN_DIR/web"
fi
for path in \
"$HOME_DIR"/.coco-config-backup-* \
"$HOME_DIR"/.coco.install.* \
"$HOME_DIR"/.coco.coco-candidate-* \
"$HOME_DIR"/.coco.coco-rollback-*
do
[ -e "$path" ] || [ -L "$path" ] || continue
rm -rf -- "$path"
done
remove_managed_launcher "$COCO_SYSTEM_BIN"
hash -r 2>/dev/null || true
if command -v coco >/dev/null 2>&1; then
die "Another CoCo executable remains at $(command -v coco)"
fi
info "CoCo has been completely removed"