set -euo pipefail
log() { printf '\033[1;34m[setup]\033[0m %s\n' "$*"; }
warn() { printf '\033[1;33m[setup] WARN:\033[0m %s\n' "$*" >&2; }
fail() { printf '\033[1;31m[setup] FAIL:\033[0m %s\n' "$*" >&2; exit 1; }
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
chmod +x "${BASH_SOURCE[0]}" 2>/dev/null || true
if [ -f "${HOME}/.cargo/env" ]; then
. "${HOME}/.cargo/env"
fi
ensure_rustup() {
if command -v rustup >/dev/null 2>&1; then
log "rustup found: $(rustup --version 2>/dev/null | head -n1)"
return 0
fi
log "rustup not found — installing via rustup-init (user-local, no sudo)"
if ! command -v curl >/dev/null 2>&1; then
fail "curl is required to install rustup. Install curl first."
fi
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
| sh -s -- -y --default-toolchain stable --no-modify-path
if [ -f "${HOME}/.cargo/env" ]; then
. "${HOME}/.cargo/env"
fi
if ! command -v rustup >/dev/null 2>&1; then
fail "rustup install reported success but rustup is not on PATH. Check ~/.cargo/bin."
fi
}
ensure_rust_components() {
log "Ensuring stable toolchain is installed"
rustup toolchain install stable --profile minimal >/dev/null
for component in clippy rustfmt; do
if rustup component list --installed 2>/dev/null | grep -q "^${component}-"; then
log "rustup component already installed: ${component}"
else
log "Installing rustup component: ${component}"
rustup component add "${component}"
fi
done
}
verify_cargo_build_tools() {
log "cargo: $(cargo --version)"
log "rustc: $(rustc --version)"
log "clippy: $(cargo clippy --version 2>/dev/null || echo 'MISSING')"
log "rustfmt: $(cargo fmt --version 2>/dev/null || echo 'MISSING')"
}
check_node() {
if ! command -v node >/dev/null 2>&1; then
warn "node not found. The web build (node web/build.js) will not work."
warn "Run bin/setup-twa to install Node LTS via nvm, or install Node yourself."
return 1
fi
log "node: $(node --version)"
if ! command -v npm >/dev/null 2>&1; then
warn "npm not found despite node being installed. Skipping npm install."
return 1
fi
log "npm: $(npm --version)"
return 0
}
install_npm_deps() {
if [ ! -f "${REPO_ROOT}/package.json" ]; then
warn "No package.json at ${REPO_ROOT}. Skipping npm install."
return 0
fi
if [ -d "${REPO_ROOT}/node_modules" ] \
&& [ -f "${REPO_ROOT}/package-lock.json" ] \
&& [ "${REPO_ROOT}/node_modules" -nt "${REPO_ROOT}/package-lock.json" ]; then
log "node_modules is newer than package-lock.json — skipping npm install"
return 0
fi
log "Installing npm dependencies (npm ci if lockfile, else npm install)"
if [ -f "${REPO_ROOT}/package-lock.json" ]; then
( cd "${REPO_ROOT}" && npm ci )
else
( cd "${REPO_ROOT}" && npm install )
fi
}
log "mobux setup starting (repo root: ${REPO_ROOT})"
ensure_rustup
ensure_rust_components
verify_cargo_build_tools
if check_node; then
install_npm_deps
fi
log "Done. You should now be able to run:"
log " cargo build"
log " node web/build.js (or: make build)"
if ! command -v node >/dev/null 2>&1; then
log ""
log "Note: node is not on PATH. Run bin/setup-twa to install it (and the"
log " Android/JDK toolchain needed to build the TWA APK)."
fi