#!/bin/sh # EnvKit installer for macOS (Apple Silicon). # # curl -fsSL https://envkit.net/install.sh | sh # # Downloads the latest EnvKit--arm64.dmg from GitHub Releases, copies # EnvKit.app into /Applications, clears the Gatekeeper quarantine flag and # launches the app. Re-running upgrades an existing install in place; your # sites, databases and settings live outside the app bundle and are kept. # # Before launching, it leaves an install-source note for the app # (`script-sh`, plus an optional website campaign code from $ENVKIT_CAMPAIGN: # lowercase letters, digits, - and _; max 64) so EnvKit can count installs per # channel. The app reads it once and deletes it. # # curl -fsSL https://envkit.net/install.sh | ENVKIT_CAMPAIGN=hn sh # # Windows: irm https://envkit.net/install.ps1 | iex set -eu REPO="Env-Kit/envkit-releases" API="https://api.github.com/repos/$REPO/releases/latest" RELEASES="https://github.com/$REPO/releases" APP_NAME="EnvKit.app" DEST_DIR="/Applications" # EnvKit's data folder (src/shared/paths.ts in the app) — not the app bundle. DATA_DIR="$HOME/Library/Application Support/envkit" say() { printf '%s\n' "$*"; } fail() { printf 'envkit: %s\n' "$*" >&2; exit 1; } case "$(uname -s)" in Darwin) ;; Linux) fail "Linux is not supported yet. EnvKit runs on macOS (Apple Silicon) and Windows 10/11." ;; MINGW*|MSYS*|CYGWIN*) fail "On Windows run: irm https://envkit.net/install.ps1 | iex" ;; *) fail "Unsupported OS. See $RELEASES" ;; esac case "$(uname -m)" in arm64) ;; *) fail "Only Apple Silicon Macs are supported (Intel builds were dropped). See $RELEASES" ;; esac command -v curl >/dev/null 2>&1 || fail "curl is required." command -v hdiutil >/dev/null 2>&1 || fail "hdiutil not found; is this macOS?" say "Looking up the latest EnvKit release..." json="$(curl -fsSL -H 'Accept: application/vnd.github+json' "$API")" \ || fail "Could not reach the GitHub API. See $RELEASES" version="$(printf '%s' "$json" | sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -n 1)" dmg_url="$(printf '%s' "$json" \ | tr ',' '\n' \ | sed -n 's/.*"browser_download_url"[[:space:]]*:[[:space:]]*"\([^"]*-arm64\.dmg\)".*/\1/p' \ | head -n 1)" [ -n "$dmg_url" ] || fail "No arm64 .dmg found in the latest release. See $RELEASES" tmp="$(mktemp -d "${TMPDIR:-/tmp}/envkit-install.XXXXXX")" mount="" cleanup() { if [ -n "$mount" ]; then hdiutil detach "$mount" -quiet >/dev/null 2>&1 || true; fi rm -rf "$tmp" } trap cleanup EXIT INT TERM dmg="$tmp/EnvKit.dmg" say "Downloading EnvKit ${version:-latest}..." curl -fL --progress-bar -o "$dmg" "$dmg_url" || fail "Download failed." say "Mounting the disk image..." mount="$tmp/mnt" mkdir -p "$mount" hdiutil attach "$dmg" -nobrowse -quiet -mountpoint "$mount" >/dev/null \ || fail "Could not mount the .dmg." src="$(find "$mount" -maxdepth 1 -name '*.app' | head -n 1)" [ -n "$src" ] || fail "No .app found inside the disk image." dest="$DEST_DIR/$APP_NAME" # Close a running copy so the bundle can be replaced on upgrade. if pgrep -xq EnvKit 2>/dev/null; then say "Closing the running EnvKit..." osascript -e 'tell application "EnvKit" to quit' >/dev/null 2>&1 || true sleep 2 fi say "Installing to $dest..." if [ -w "$DEST_DIR" ] && { [ ! -e "$dest" ] || [ -w "$dest" ]; }; then rm -rf "$dest" ditto "$src" "$dest" else say "Administrator password needed to write to $DEST_DIR." sudo rm -rf "$dest" sudo ditto "$src" "$dest" sudo chown -R "$(id -u):$(id -g)" "$dest" 2>/dev/null || true fi # Skip the Gatekeeper "downloaded from the internet" prompt. xattr -dr com.apple.quarantine "$dest" 2>/dev/null \ || sudo xattr -dr com.apple.quarantine "$dest" 2>/dev/null \ || true hdiutil detach "$mount" -quiet >/dev/null 2>&1 || true mount="" # Install-source note, one line `script-sh[,campaign]`. On an upgrade the app # has already registered and never reads it. Best-effort — a failure here must # not fail the install. source_line="script-sh" campaign="${ENVKIT_CAMPAIGN:-}" if [ -n "$campaign" ] && printf '%s' "$campaign" | grep -Eq '^[a-z0-9][a-z0-9_-]{0,63}$'; then source_line="$source_line,$campaign" fi { mkdir -p "$DATA_DIR" && printf '%s\n' "$source_line" > "$DATA_DIR/install-source.txt"; } 2>/dev/null || true say "EnvKit ${version:-} installed. Launching..." open -a "$dest" || say "Open EnvKit from /Applications to get started."