Skip to content

Commit ed1fa6e

Browse files
committed
feat: add install.sh/uninstall.sh as a local, brew-less install path
Builds a native Burrito release for the current machine (macOS aarch64 or Linux x86_64) via mise, and installs lc plus the bin/ wrapper scripts onto a directory already on $PATH rather than assuming one. Writes a manifest of exactly what it installed and where, so uninstall.sh can remove precisely those files even if $PATH changes in between - a fallback for machines without Homebrew (rubyists/homebrew-tap to come once a real release exists to pin against).
1 parent d3c5169 commit ed1fa6e

2 files changed

Lines changed: 187 additions & 0 deletions

File tree

install.sh

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
#!/usr/bin/env bash
2+
# Builds a native Burrito release of `lc` for the current machine and
3+
# installs it, plus the bin/ wrapper scripts (lcreate, lcls, lclose,
4+
# lcomment, lproj), onto a directory already on $PATH. Fallback path for
5+
# machines without Homebrew - see rubyists/homebrew-tap once it exists.
6+
#
7+
# Records exactly what it installed and where in a manifest file, so
8+
# uninstall.sh can remove precisely those files even if $PATH changes
9+
# between install and uninstall.
10+
11+
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12+
app_dir="$repo_root/app"
13+
state_dir="${XDG_STATE_HOME:-$HOME/.local/state}/linear-cli-ex"
14+
manifest="$state_dir/manifest"
15+
16+
detect_target() {
17+
case "$(uname -s)" in
18+
Darwin)
19+
case "$(uname -m)" in
20+
arm64) printf '%s\n' macos_aarch64 ;;
21+
*)
22+
printf 'error: unsupported macOS architecture: %s (only aarch64 is built)\n' "$(uname -m)" >&2
23+
exit 1
24+
;;
25+
esac
26+
;;
27+
Linux)
28+
case "$(uname -m)" in
29+
x86_64) printf '%s\n' linux_x86_64 ;;
30+
*)
31+
printf 'error: unsupported Linux architecture: %s (only x86_64 is built)\n' "$(uname -m)" >&2
32+
exit 1
33+
;;
34+
esac
35+
;;
36+
*)
37+
printf 'error: unsupported OS: %s (use the container image on Windows)\n' "$(uname -s)" >&2
38+
exit 1
39+
;;
40+
esac
41+
}
42+
43+
# Prefer an install dir the user already has on $PATH (so no shell rc
44+
# editing is required) over inventing a new one. $LC_INSTALL_DIR always
45+
# wins if set, for anyone who wants a specific target.
46+
pick_install_dir() {
47+
if [ -n "${LC_INSTALL_DIR:-}" ]
48+
then
49+
printf '%s\n' "$LC_INSTALL_DIR"
50+
return
51+
fi
52+
53+
local dir
54+
IFS=: read -ra path_dirs <<< "$PATH"
55+
for dir in "${path_dirs[@]}"
56+
do
57+
if [ -n "$dir" ] && [ -d "$dir" ] && [ -w "$dir" ]
58+
then
59+
printf '%s\n' "$dir"
60+
return
61+
fi
62+
done
63+
64+
printf '%s\n' "$HOME/.local/bin"
65+
}
66+
67+
build_lc() {
68+
local target="$1"
69+
70+
if ! cd "$app_dir"
71+
then
72+
printf 'error: could not cd into %s\n' "$app_dir" >&2
73+
exit 1
74+
fi
75+
76+
rm -rf _build/prod
77+
78+
have_mise=0
79+
if command -v mise >/dev/null 2>&1
80+
then
81+
have_mise=1
82+
else
83+
printf 'warning: mise not found on PATH; building with whatever Erlang/Elixir are active\n' >&2
84+
fi
85+
86+
if [ "$have_mise" -eq 1 ]
87+
then
88+
MIX_ENV=prod BURRITO_TARGET="$target" mise exec -- mix release lc --overwrite
89+
else
90+
MIX_ENV=prod BURRITO_TARGET="$target" mix release lc --overwrite
91+
fi
92+
93+
if [ "$?" -ne 0 ]
94+
then
95+
printf 'error: build failed (mix release lc, target %s)\n' "$target" >&2
96+
exit 1
97+
fi
98+
}
99+
100+
target=$(detect_target) || exit 1
101+
install_dir=$(pick_install_dir)
102+
103+
printf 'Building lc (%s)...\n' "$target"
104+
build_lc "$target"
105+
106+
if ! mkdir -p "$install_dir"
107+
then
108+
printf 'error: could not create install dir %s\n' "$install_dir" >&2
109+
exit 1
110+
fi
111+
112+
if ! mkdir -p "$state_dir"
113+
then
114+
printf 'error: could not create state dir %s\n' "$state_dir" >&2
115+
exit 1
116+
fi
117+
118+
: > "$manifest"
119+
for name in lc lcreate lcls lclose lcomment lproj
120+
do
121+
src="$app_dir/burrito_out/lc_${target}"
122+
[ "$name" = lc ] || src="$repo_root/bin/$name"
123+
124+
if ! install -m 755 "$src" "$install_dir/$name"
125+
then
126+
printf 'error: failed to install %s to %s\n' "$name" "$install_dir" >&2
127+
exit 1
128+
fi
129+
130+
printf '%s\n' "$install_dir/$name" >> "$manifest"
131+
done
132+
133+
printf 'Installed lc, lcreate, lcls, lclose, lcomment, lproj to %s\n' "$install_dir"
134+
printf '(uninstall.sh will remove exactly these files - manifest at %s)\n' "$manifest"
135+
136+
case ":$PATH:" in
137+
*":$install_dir:"*) ;;
138+
*)
139+
printf '\n'
140+
printf 'warning: %s is not on your $PATH.\n' "$install_dir"
141+
printf 'Add it to your shell profile, e.g.:\n'
142+
printf ' export PATH="%s:$PATH"\n' "$install_dir"
143+
;;
144+
esac

uninstall.sh

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/usr/bin/env bash
2+
# Removes exactly what install.sh installed, using the manifest it wrote -
3+
# not a guess at where things might be, so this stays correct even if
4+
# $PATH changed since install.
5+
6+
state_dir="${XDG_STATE_HOME:-$HOME/.local/state}/linear-cli-ex"
7+
manifest="$state_dir/manifest"
8+
9+
if [ ! -f "$manifest" ]
10+
then
11+
printf 'error: no manifest at %s - nothing to uninstall (or it was installed another way, e.g. Homebrew: use `brew uninstall lc` instead)\n' "$manifest" >&2
12+
exit 1
13+
fi
14+
15+
removed=0
16+
failed=0
17+
while IFS= read -r path
18+
do
19+
[ -n "$path" ] || continue
20+
21+
if [ -e "$path" ]
22+
then
23+
if rm -f "$path"
24+
then
25+
printf 'removed %s\n' "$path"
26+
removed=$((removed + 1))
27+
else
28+
printf 'error: failed to remove %s\n' "$path" >&2
29+
failed=$((failed + 1))
30+
fi
31+
fi
32+
done < "$manifest"
33+
34+
rm -f "$manifest"
35+
rmdir "$state_dir" 2>/dev/null
36+
37+
if [ "$failed" -ne 0 ]
38+
then
39+
printf '%d file(s) removed, %d failed\n' "$removed" "$failed" >&2
40+
exit 1
41+
fi
42+
43+
printf '%d file(s) removed\n' "$removed"

0 commit comments

Comments
 (0)