#!/bin/sh # install easl 0.1.0: curl -fsSL https://easl.sh/install | sh # # downloads the release zip from github, checks its sha-256 against the pin below and moves # easl.app into /Applications (~/Applications if /Applications isn't writable). no sudo, no brew, # no quarantine changes: curl sets no quarantine flag, so the app opens without a prompt. # everything runs from main on the last line, so a cut-off download runs nothing. # # testing: EASL_INSTALL_DIR=/some/dir installs there instead of /Applications. set -eu VERSION=0.1.0 URL=https://github.com/twaldin/easl/releases/download/v0.1.0/easl-0.1.0.zip SHA256=97a7b1f99a25b23af5646c022c02d7bf36b76760635c05cc4a2aeb0fa5df5788 BUNDLE_ID=net.waldin.easl APP=easl.app say() { printf 'easl: %s\n' "$*"; } die() { printf 'easl: %s\n' "$*" >&2; exit 1; } main() { # macos 14+ on apple silicon. hw.optional.arm64 is 1 even in a rosetta shell, where uname -m says x86_64. [ "$(uname -s)" = Darwin ] || die "easl is a mac app: it needs macos 14 or later on apple silicon" macos=$(sw_vers -productVersion) [ "${macos%%.*}" -ge 14 ] || die "easl needs macos 14 or later; this mac runs $macos" [ "$(sysctl -n hw.optional.arm64 2>/dev/null)" = 1 ] || die "easl needs an apple silicon mac; there's no intel build" # /Applications, or ~/Applications if this user can't write there dir=${EASL_INSTALL_DIR:-/Applications} if [ ! -w "$dir" ]; then say "can't write to $dir, so installing to ~/Applications instead" dir=$HOME/Applications mkdir -p "$dir" fi dest=$dir/$APP # download into a temp dir that's removed on exit, then check it's the published zip tmp=$(mktemp -d) trap 'rm -rf "$tmp"' EXIT trap 'exit 1' INT TERM say "downloading easl $VERSION" curl -fsSL -o "$tmp/easl.zip" "$URL" sum=$(shasum -a 256 "$tmp/easl.zip" | cut -d ' ' -f 1) [ "$sum" = "$SHA256" ] || die "checksum mismatch, nothing installed (expected $SHA256, got $sum)" ditto -x -k "$tmp/easl.zip" "$tmp/unzipped" [ -d "$tmp/unzipped/$APP" ] || die "the zip has no $APP, nothing installed" # never replace a running app, and never delete an app that isn't easl if pgrep -x Easl >/dev/null; then die "easl is running: quit easl first (your terminals keep running)"; fi if [ -e "$dest" ] || [ -L "$dest" ]; then id=$(plutil -extract CFBundleIdentifier raw -o - "$dest/Contents/Info.plist" 2>/dev/null || true) [ "$id" = "$BUNDLE_ID" ] || die "$dest isn't easl ($BUNDLE_ID); move it aside and run this again" rm -rf "$dest" fi mv "$tmp/unzipped/$APP" "$dest" # zmx runs terminal tiles; bun runs the easl cli and the omp extension. suggest them, never install. missing= command -v zmx >/dev/null || missing="$missing zmx" command -v bun >/dev/null || missing="$missing bun" if [ -n "$missing" ]; then say "missing:$missing (zmx runs terminal tiles, bun the easl cli)" command -v brew >/dev/null || say "first get homebrew: https://brew.sh" say "install them with: brew install neurosnap/tap/zmx oven-sh/bun/bun" fi version=$(plutil -extract CFBundleShortVersionString raw -o - "$dest/Contents/Info.plist") say "installed easl $version in $dest" say "open it: open -a easl" } main "$@"