#!/usr/bin/env bash set -euo pipefail MODE="native" while [[ $# -gt 0 ]]; do case "$1" in --mode) MODE="${2:-}" shift 2 ;; *) echo "usage: $0 --mode " exit 2 ;; esac done if [[ -z "${MODE}" ]]; then echo "error: --mode is required" exit 2 fi OS="$(uname -s)" FAILED=0 print_install_hint() { local cmd="$1" if [[ "${OS}" == "Darwin" ]]; then case "${cmd}" in nix) echo " install: sh <(curl -L https://nixos.org/nix/install) --daemon" ;; cargo|rustc|rustup) echo " install: curl https://sh.rustup.rs -sSf | sh" ;; just) echo " install: brew install just" ;; rg) echo " install: brew install ripgrep" ;; fd) echo " install: brew install fd" ;; tree) echo " install: brew install tree" ;; cargo-watch) echo " install: cargo install cargo-watch" ;; cargo-nextest) echo " install: cargo install cargo-nextest --locked" ;; *) echo " install: use your package manager to install '${cmd}'" ;; esac return fi case "${cmd}" in nix) echo " install: sh <(curl -L https://nixos.org/nix/install) --daemon" ;; cargo|rustc|rustup) echo " install: curl https://sh.rustup.rs -sSf | sh" ;; just) echo " install: sudo apt update && sudo apt install -y just" ;; rg) echo " install: sudo apt update && sudo apt install -y ripgrep" ;; fd) echo " install: sudo apt update && sudo apt install -y fd-find" ;; tree) echo " install: sudo apt update && sudo apt install -y tree" ;; cargo-watch) echo " install: cargo install cargo-watch" ;; cargo-nextest) echo " install: cargo install cargo-nextest --locked" ;; *) echo " install: use your package manager to install '${cmd}'" ;; esac } require_cmd() { local cmd="$1" if command -v "${cmd}" >/dev/null 2>&1; then echo "ok: ${cmd}" else echo "missing: ${cmd}" print_install_hint "${cmd}" FAILED=1 fi } warn_if_missing() { local cmd="$1" if command -v "${cmd}" >/dev/null 2>&1; then echo "ok(optional): ${cmd}" else echo "missing(optional): ${cmd}" print_install_hint "${cmd}" fi } check_xcode_clt() { if [[ "${OS}" != "Darwin" ]]; then return fi if xcode-select -p >/dev/null 2>&1; then echo "ok: xcode-command-line-tools" else echo "missing: xcode-command-line-tools" echo " install: xcode-select --install" FAILED=1 fi } print_context_note() { if [[ -f "ai/context/project-context.md" ]]; then echo "ok: ai/context/project-context.md exists (generated file)" else echo "info: ai/context/project-context.md is generated and currently missing" echo " generate with: just context" echo " or: ./ai/scripts/build-context.sh" fi } check_native() { echo "mode: native" require_cmd cargo require_cmd rustc require_cmd just require_cmd rg require_cmd fd require_cmd tree if command -v rustup >/dev/null 2>&1; then if rustup component list --installed | rg -q "^rustfmt"; then echo "ok: rustup component rustfmt" else echo "missing: rustup component rustfmt" echo " install: rustup component add rustfmt" FAILED=1 fi if rustup component list --installed | rg -q "^clippy"; then echo "ok: rustup component clippy" else echo "missing: rustup component clippy" echo " install: rustup component add clippy" FAILED=1 fi else echo "missing: rustup" print_install_hint rustup FAILED=1 fi warn_if_missing cargo-watch warn_if_missing cargo-nextest check_xcode_clt print_context_note } check_nix_host() { echo "mode: nix-host" require_cmd nix check_xcode_clt } check_nix_shell() { echo "mode: nix-shell" require_cmd cargo require_cmd rustc require_cmd just require_cmd rg require_cmd fd require_cmd tree require_cmd cargo-watch require_cmd cargo-nextest check_xcode_clt print_context_note } case "${MODE}" in native) check_native ;; nix-host) check_nix_host ;; nix-shell) check_nix_shell ;; *) echo "error: unknown mode '${MODE}'" echo "usage: $0 --mode " exit 2 ;; esac if [[ "${FAILED}" -ne 0 ]]; then echo "requirements check: FAILED" exit 1 fi echo "requirements check: OK"