Files
rustbox-package-builder/scripts/ensure-rust-toolchain.sh
T
2026-10-30 12:59:58 +01:00

36 lines
1.4 KiB
Bash
Executable File

#!/usr/bin/env bash
set -Eeuo pipefail
SOURCE_DIR=${1:?usage: ensure-rust-toolchain.sh SOURCE_DIR}
[[ -r "$SOURCE_DIR/Cargo.toml" ]] || { echo "missing Cargo.toml: $SOURCE_DIR" >&2; exit 1; }
metadata=$(python3.11 - "$SOURCE_DIR" <<'PY'
import pathlib, re, sys, tomllib
root=pathlib.Path(sys.argv[1])
manifest=tomllib.loads((root/'Cargo.toml').read_text())
minimum=manifest.get('package',{}).get('rust-version','')
pinned=''
p=root/'rust-toolchain.toml'
if p.exists(): pinned=tomllib.loads(p.read_text()).get('toolchain',{}).get('channel','')
if minimum and not re.fullmatch(r'[0-9]+\.[0-9]+(?:\.[0-9]+)?', minimum): raise SystemExit('unsupported rust-version')
if pinned and not (pinned=='stable' or re.fullmatch(r'[0-9]+\.[0-9]+(?:\.[0-9]+)?', pinned)): raise SystemExit('unsupported rust-toolchain channel')
print(minimum)
print(pinned)
PY
)
mapfile -t requested <<< "$metadata"
minimum=${requested[0]:-}
channel=${requested[1]:-stable}
[[ -n "$channel" ]] || channel=stable
if ! rustup run "$channel" rustc --version >/dev/null 2>&1; then
echo "installing Rust toolchain $channel" >&2
rustup toolchain install "$channel" --profile minimal >&2
fi
installed=$(rustup run "$channel" rustc --version | awk '{print $2}')
if [[ -n "$minimum" ]]; then
lowest=$(printf '%s\n%s\n' "$installed" "$minimum" | sort -V | head -n1)
if [[ "$lowest" != "$minimum" ]]; then
echo "Rust $installed does not satisfy project MSRV $minimum" >&2
exit 1
fi
fi
printf '%s\n' "$channel"