#!/usr/bin/env bash set -euo pipefail fail() { printf '\nMacish failed: %s\n' "$*" >&2; exit 1; } step() { printf '\n==> %s\n' "$*"; } run() { printf ' %s\n' "$*"; "$@"; } append_once() { local file="$1" line="$2" touch "$file" if ! grep -Fqx "$line" "$file"; then printf '\n%s\n' "$line" >>"$file"; fi } require_ready() { [[ "$(uname -s)" == "Darwin" ]] || fail "macOS is required." [[ "$EUID" -ne 0 ]] || fail "Run as your normal user, not with sudo." if [[ "${MACISH_YES:-${MACI_YES:-}}" != "1" && "${CI:-}" != "true" ]]; then if { exec 3<>/dev/tty; } 2>/dev/null; then printf '\nPress return to install, or Ctrl-C to stop. ' >&3 read -r _ <&3 || fail "Confirmation cancelled." exec 3>&- else fail "No terminal for confirmation. Review the script, then set MACISH_YES=1 to run unattended." fi fi if ! xcode-select -p >/dev/null 2>&1; then xcode-select --install || true fail "Finish installing Xcode Command Line Tools, then run this script again." fi } printf '\nMacish / Rust\nStable Rust, Cargo, rustfmt, and Clippy. No database services.\n' require_ready cargo_bin="${CARGO_HOME:-$HOME/.cargo}/bin" [[ "$cargo_bin" == /* ]] || fail "CARGO_HOME must be an absolute path." export PATH="$cargo_bin:$PATH" step "Installing the Rust toolchain" if command -v rustup >/dev/null 2>&1; then run rustup toolchain install stable --profile default else installer="$(curl --proto '=https' --tlsv1.2 -fsSL https://sh.rustup.rs)" || fail "Could not download rustup." sh -c "$installer" -- -y --no-modify-path --default-toolchain stable --profile default fi run rustup component add --toolchain stable rustfmt clippy printf -v cargo_path 'export PATH=%q:"$PATH"' "$cargo_bin" append_once "$HOME/.zshrc" "$cargo_path" step "Verifying tools" run rustup run stable rustc --version run rustup run stable cargo --version run rustup run stable rustfmt --version run rustup run stable cargo clippy --version printf '\nDone. Open a new terminal to use Rust. Existing default toolchains are preserved.\n'