Skip to content

Commit 603182f

Browse files
authored
Merge branch 'main' into remove-release-as-pin
2 parents 393f878 + e836ab1 commit 603182f

4 files changed

Lines changed: 112 additions & 39 deletions

File tree

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,6 @@
2525
[submodule "vendor/owl"]
2626
path = vendor/owl
2727
url = git@github.com:fuelen/owl
28+
[submodule "vendor/rubyists-homebrew-tap"]
29+
path = vendor/rubyists-homebrew-tap
30+
url = git@github.com:rubyists/homebrew-tap

Readme.adoc

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,6 @@ built with. The container image has its own separate SBOM (its OS packages -
7272
irrelevant if you're not using the container), published as a workflow
7373
artifact on the release's build rather than a release asset.
7474

75-
NOTE: A Homebrew tap is planned but not yet available.
76-
7775
On macOS, Gatekeeper blocks `lc` itself (the wrapper scripts are plain shell,
7876
so they're unaffected) since it isn't signed/notarized yet:
7977

@@ -82,18 +80,37 @@ so they're unaffected) since it isn't signed/notarized yet:
8280
$ xattr -d com.apple.quarantine /usr/local/bin/lc
8381
----
8482

85-
=== install.sh (builds from source, for machines without Homebrew)
83+
=== Homebrew (macOS Apple Silicon, Linux x86_64)
8684

8785
[source,sh]
8886
----
89-
$ git clone https://github.com/rubyists/linear-cli-ex.git
90-
$ cd linear-cli-ex
91-
$ ./install.sh
87+
$ brew tap rubyists/tap
88+
$ brew install lc
89+
----
90+
91+
See https://github.com/rubyists/homebrew-tap for the formula itself.
92+
93+
=== install.sh (fetches a release binary, for machines without Homebrew)
94+
95+
[source,sh]
96+
----
97+
$ curl -fsSL https://raw.githubusercontent.com/rubyists/linear-cli-ex/main/install.sh | bash
98+
----
99+
100+
Detects your platform, downloads and checksum-verifies the matching release
101+
tarball (the same one the "Download a release binary" section above uses),
102+
and installs `lc` plus the `bin/` wrapper scripts onto a directory already on
103+
your `$PATH` - no Erlang/Elixir/Zig toolchain required. `LC_VERSION` pins a
104+
specific release tag instead of the latest one; `LC_INSTALL_DIR` pins a
105+
specific install directory.
106+
107+
[source,sh]
108+
----
109+
$ curl -fsSL https://raw.githubusercontent.com/rubyists/linear-cli-ex/main/uninstall.sh | bash
92110
----
93111

94-
Builds a native release via https://mise.jdx.dev[mise] and installs `lc` plus
95-
the `bin/` wrapper scripts onto a directory already on your `$PATH`. Run
96-
`./uninstall.sh` to remove exactly what it installed.
112+
Removes exactly what `install.sh` installed, by replaying the manifest it
113+
wrote - not a guess at where things ended up.
97114

98115
=== From Source (You are obviously a developer)
99116

install.sh

Lines changed: 82 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
#!/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.
2+
# Downloads a precompiled Burrito release of `lc` for the current machine
3+
# and installs it, plus the bin/ wrapper scripts (lcreate, lcls, lclose,
4+
# lcomment, lproj) already bundled in the same release tarball, onto a
5+
# directory already on $PATH. Fallback path for machines without
6+
# Homebrew - see rubyists/homebrew-tap for that.
7+
#
8+
# LC_VERSION pins a specific release tag (e.g. "v1.0.0") instead of the
9+
# latest one. LC_INSTALL_DIR pins a specific install directory instead of
10+
# the first writable $PATH entry found.
611
#
712
# Records exactly what it installed and where in a manifest file, so
813
# uninstall.sh can remove precisely those files even if $PATH changes
914
# between install and uninstall.
1015

11-
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12-
app_dir="$repo_root/app"
16+
repo=rubyists/linear-cli-ex
17+
version=${LC_VERSION:-latest}
1318
state_dir="${XDG_STATE_HOME:-$HOME/.local/state}/linear-cli-ex"
1419
manifest="$state_dir/manifest"
1520

@@ -64,44 +69,85 @@ pick_install_dir() {
6469
printf '%s\n' "$HOME/.local/bin"
6570
}
6671

67-
build_lc() {
68-
local target="$1"
69-
70-
if ! cd "$app_dir"
72+
# GNU coreutils' sha256sum vs. macOS's shasum -a 256 - both read the same
73+
# "<hash> <filename>" format via `-c -` on stdin.
74+
checksum_cmd() {
75+
if command -v sha256sum >/dev/null 2>&1
7176
then
72-
printf 'error: could not cd into %s\n' "$app_dir" >&2
77+
printf 'sha256sum\n'
78+
elif command -v shasum >/dev/null 2>&1
79+
then
80+
printf 'shasum -a 256\n'
81+
else
82+
printf 'error: need sha256sum or shasum on $PATH to verify the download\n' >&2
7383
exit 1
7484
fi
85+
}
7586

76-
rm -rf _build/prod
77-
78-
have_mise=0
79-
if command -v mise >/dev/null 2>&1
87+
release_url() {
88+
local asset="$1"
89+
if [ "$version" = "latest" ]
8090
then
81-
have_mise=1
91+
printf 'https://github.com/%s/releases/latest/download/%s\n' "$repo" "$asset"
8292
else
83-
printf 'warning: mise not found on PATH; building with whatever Erlang/Elixir are active\n' >&2
93+
printf 'https://github.com/%s/releases/download/%s/%s\n' "$repo" "$version" "$asset"
94+
fi
95+
}
96+
97+
# Downloads lc_<target>.tar.gz + SHA256SUMS, verifies the tarball's
98+
# checksum against just its own line (SHA256SUMS covers every target,
99+
# not only the one being installed here), and extracts it. Prints the
100+
# directory it extracted into.
101+
fetch_lc() {
102+
local target="$1" tarball tmp_dir sum_tool
103+
tarball="lc_${target}.tar.gz"
104+
105+
tmp_dir=$(mktemp -d) || {
106+
printf 'error: could not create a temp directory\n' >&2
107+
exit 1
108+
}
109+
trap 'rm -rf "$tmp_dir"' EXIT
110+
111+
printf 'Downloading %s (%s)...\n' "$tarball" "$version" >&2
112+
113+
if ! curl -fsSL "$(release_url "$tarball")" -o "$tmp_dir/$tarball"
114+
then
115+
printf 'error: failed to download %s\n' "$tarball" >&2
116+
exit 1
84117
fi
85118

86-
if [ "$have_mise" -eq 1 ]
119+
if ! curl -fsSL "$(release_url "SHA256SUMS")" -o "$tmp_dir/SHA256SUMS"
87120
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
121+
printf 'error: failed to download SHA256SUMS\n' >&2
122+
exit 1
123+
fi
124+
125+
sum_tool=$(checksum_cmd)
126+
127+
if ! grep -- " $tarball\$" "$tmp_dir/SHA256SUMS" | (cd "$tmp_dir" && $sum_tool -c -) >/dev/null
128+
then
129+
printf 'error: checksum verification failed for %s\n' "$tarball" >&2
130+
exit 1
91131
fi
92132

93-
if [ "$?" -ne 0 ]
133+
if ! tar -xzf "$tmp_dir/$tarball" -C "$tmp_dir"
94134
then
95-
printf 'error: build failed (mix release lc, target %s)\n' "$target" >&2
135+
printf 'error: failed to extract %s\n' "$tarball" >&2
96136
exit 1
97137
fi
138+
139+
printf '%s\n' "$tmp_dir"
98140
}
99141

142+
if ! command -v curl >/dev/null 2>&1
143+
then
144+
printf 'error: curl is required\n' >&2
145+
exit 1
146+
fi
147+
100148
target=$(detect_target) || exit 1
101149
install_dir=$(pick_install_dir)
102-
103-
printf 'Building lc (%s)...\n' "$target"
104-
build_lc "$target"
150+
extracted_dir=$(fetch_lc "$target") || exit 1
105151

106152
if ! mkdir -p "$install_dir"
107153
then
@@ -118,10 +164,7 @@ fi
118164
: > "$manifest"
119165
for name in lc lcreate lcls lclose lcomment lproj
120166
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"
167+
if ! install -m 755 "$extracted_dir/$name" "$install_dir/$name"
125168
then
126169
printf 'error: failed to install %s to %s\n' "$name" "$install_dir" >&2
127170
exit 1
@@ -130,6 +173,15 @@ do
130173
printf '%s\n' "$install_dir/$name" >> "$manifest"
131174
done
132175

176+
# Gatekeeper blocks lc itself (a real Mach-O binary) on macOS since it
177+
# isn't signed/notarized - the wrapper scripts are plain shell, so they're
178+
# unaffected. Best-effort: xattr not existing/failing shouldn't fail the
179+
# install, since the user can still do this by hand (see the README).
180+
if [ "$(uname -s)" = Darwin ]
181+
then
182+
xattr -d com.apple.quarantine "$install_dir/lc" 2>/dev/null || true
183+
fi
184+
133185
printf 'Installed lc, lcreate, lcls, lclose, lcomment, lproj to %s\n' "$install_dir"
134186
printf '(uninstall.sh will remove exactly these files - manifest at %s)\n' "$manifest"
135187

vendor/rubyists-homebrew-tap

Submodule rubyists-homebrew-tap added at 098d41c

0 commit comments

Comments
 (0)