#!/usr/bin/env bash set -euo pipefail stable_toolchain="${1:-1.88.0}" nightly_toolchain="${2:-nightly}" if ! command -v rustup >/dev/null 2>&1; then curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \ | sh -s -- -y --profile minimal --default-toolchain none fi if [ -f "${HOME}/.cargo/env" ]; then # shellcheck disable=SC1091 source "${HOME}/.cargo/env" fi command -v rustup >/dev/null 2>&1 || { echo "rustup is required after bootstrap" >&2 exit 1 } export RUSTUP_MAX_RETRIES="${RUSTUP_MAX_RETRIES:-3}" toolchain_is_installed() { local requested="$1" local installed while read -r installed _; do if [[ "${installed}" == "${requested}" || "${installed}" == "${requested}-"* ]]; then return 0 fi done < <(rustup toolchain list) return 1 } component_is_installed() { local toolchain="$1" local component="$2" rustup component list --toolchain "${toolchain}" --installed \ | awk '{ print $1 }' \ | grep -Fxq "${component}" } ensure_toolchain() { local toolchain="$1" shift local missing_components=() local install_args=() local component if toolchain_is_installed "${toolchain}"; then for component in "$@"; do if ! component_is_installed "${toolchain}" "${component}"; then missing_components+=("${component}") fi done if [ "${#missing_components[@]}" -eq 0 ]; then echo "rustup: reusing installed ${toolchain}" return 0 fi rustup component add --toolchain "${toolchain}" "${missing_components[@]}" return 0 fi for component in "$@"; do install_args+=(--component "${component}") done rustup toolchain install "${toolchain}" --profile minimal "${install_args[@]}" } ensure_toolchain "${stable_toolchain}" rustfmt clippy rust-src if [ "${nightly_toolchain}" != "none" ]; then ensure_toolchain "${nightly_toolchain}" rust-src fi rustup default "${stable_toolchain}" cargo --version rustc --version rustup show active-toolchain