137 lines
4.7 KiB
Bash
Executable File
137 lines
4.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Offline simulation of rustup installation/selection; no Rust or network required.
|
|
set -Eeuo pipefail
|
|
ROOT=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
|
WORK=$(mktemp -d)
|
|
trap 'rm -rf "$WORK"' EXIT
|
|
mkdir -p "$WORK/bin" "$WORK/source" "$WORK/state"
|
|
cat > "$WORK/bin/rustup" <<'MOCK'
|
|
#!/usr/bin/env bash
|
|
set -Eeuo pipefail
|
|
state=${MOCK_RUSTUP_STATE:?}
|
|
case "$1" in
|
|
run)
|
|
channel=$2
|
|
[[ -r "$state/$channel.version" ]] || exit 1
|
|
printf 'rustc %s (mock)\n' "$(cat "$state/$channel.version")"
|
|
;;
|
|
toolchain)
|
|
[[ "$2" == install ]] || exit 7
|
|
channel=$3
|
|
[[ ${MOCK_INSTALL_FAIL:-0} != 1 ]] || exit 9
|
|
case "$channel" in
|
|
stable) version=${MOCK_NEW_STABLE:-1.100.0} ;;
|
|
*) case "$channel" in *.*.*) version=$channel ;; *) version=${channel}.0 ;; esac ;;
|
|
esac
|
|
echo "$version" > "$state/$channel.version"
|
|
printf 'install %s\n' "$channel" >> "$state/calls"
|
|
;;
|
|
target)
|
|
action=$2
|
|
if [[ "$action" == list ]]; then
|
|
[[ "$3" == --toolchain && "$5" == --installed ]] || exit 7
|
|
[[ -f "$state/$4.target" ]] && cat "$state/$4.target"
|
|
elif [[ "$action" == add ]]; then
|
|
[[ "$4" == --toolchain ]] || exit 7
|
|
echo "$3" > "$state/$5.target"
|
|
printf 'target %s %s\n' "$5" "$3" >> "$state/calls"
|
|
else exit 7
|
|
fi
|
|
;;
|
|
*) printf 'Unexpected rustup arguments: %s\n' "$*" >&2; exit 7 ;;
|
|
esac
|
|
MOCK
|
|
chmod +x "$WORK/bin/rustup"
|
|
export PATH="$WORK/bin:$PATH" MOCK_RUSTUP_STATE="$WORK/state" TOML_PYTHON=python3
|
|
TOOL="$ROOT/scripts/ensure-rust-toolchain.sh"
|
|
reset_state() { rm -f "$WORK/state/"*; }
|
|
manifest() { printf '[package]\nname = "rust-proxy"\nversion = "0.31.2"\nrust-version = "%s"\n' "$1" > "$WORK/source/Cargo.toml"; rm -f "$WORK/source/rust-toolchain" "$WORK/source/rust-toolchain.toml"; }
|
|
|
|
# No update or download when installed stable already satisfies the manifest.
|
|
reset_state
|
|
manifest 1.99
|
|
printf '1.100.0\n' > "$WORK/state/stable.version"
|
|
result=$($TOOL "$WORK/source" linux)
|
|
[[ "$result" == stable ]]
|
|
[[ ! -e "$WORK/state/calls" ]]
|
|
|
|
# Upgrade stable only when too old, then reuse it on subsequent checks.
|
|
reset_state
|
|
printf '1.98.1\n' > "$WORK/state/stable.version"
|
|
result=$($TOOL "$WORK/source" linux)
|
|
[[ "$result" == stable ]]
|
|
grep -Fqx 'install stable' "$WORK/state/calls"
|
|
[[ $($TOOL "$WORK/source" linux) == stable ]]
|
|
[[ $(wc -l < "$WORK/state/calls") == 1 ]]
|
|
|
|
# FreeBSD default 1.88 is auto raised to the project's 1.99 MSRV with its own target.
|
|
reset_state
|
|
result=$(FREEBSD_RUST_TOOLCHAIN=1.88.0 "$TOOL" "$WORK/source" freebsd)
|
|
[[ "$result" == 1.99 ]]
|
|
grep -Fqx 'install 1.99' "$WORK/state/calls"
|
|
grep -Fqx 'target 1.99 x86_64-unknown-freebsd' "$WORK/state/calls"
|
|
[[ $(FREEBSD_RUST_TOOLCHAIN=1.88.0 "$TOOL" "$WORK/source" freebsd) == 1.99 ]]
|
|
[[ $(wc -l < "$WORK/state/calls") == 2 ]]
|
|
|
|
# A deliberate rust-toolchain.toml pin is respected; do not silently override it.
|
|
reset_state
|
|
cat > "$WORK/source/rust-toolchain.toml" <<'PIN'
|
|
[toolchain]
|
|
channel = "1.98.0"
|
|
PIN
|
|
if "$TOOL" "$WORK/source" linux >/dev/null 2>&1; then
|
|
printf 'An incompatible explicit pin should have failed\n' >&2
|
|
exit 1
|
|
fi
|
|
[[ ! -e "$WORK/state/calls" ]] || { echo 'Should not install an incompatible pin' >&2; exit 1; }
|
|
rm "$WORK/source/rust-toolchain.toml"
|
|
|
|
# Pin that meets the project requirement is installed without changing stable.
|
|
reset_state
|
|
cat > "$WORK/source/rust-toolchain.toml" <<'PIN'
|
|
[toolchain]
|
|
channel = "1.99.0"
|
|
PIN
|
|
[[ $($TOOL "$WORK/source" linux) == 1.99.0 ]]
|
|
grep -Fqx 'install 1.99.0' "$WORK/state/calls"
|
|
rm "$WORK/source/rust-toolchain.toml"
|
|
|
|
# RustProxy-like rust-toolchain.toml (stable) also upgrades stale stable for FreeBSD.
|
|
reset_state
|
|
manifest 1.99
|
|
cat > "$WORK/source/rust-toolchain.toml" <<'PIN'
|
|
[toolchain]
|
|
channel = "stable"
|
|
profile = "minimal"
|
|
components = ["rustfmt", "clippy"]
|
|
PIN
|
|
printf '1.98.1\n' > "$WORK/state/stable.version"
|
|
[[ $(FREEBSD_RUST_TOOLCHAIN=1.88.0 "$TOOL" "$WORK/source" freebsd) == stable ]]
|
|
grep -Fqx 'install stable' "$WORK/state/calls"
|
|
grep -Fqx 'target stable x86_64-unknown-freebsd' "$WORK/state/calls"
|
|
rm "$WORK/source/rust-toolchain.toml"
|
|
|
|
# Workspace-inherited rust-version is resolved through TOML, not grep.
|
|
reset_state
|
|
cat > "$WORK/source/Cargo.toml" <<'MANIFEST'
|
|
[workspace.package]
|
|
rust-version = "1.99"
|
|
[package]
|
|
name = "rust-proxy"
|
|
version = "0.31.2"
|
|
rust-version = { workspace = true }
|
|
MANIFEST
|
|
printf '1.100.0\n' > "$WORK/state/stable.version"
|
|
[[ $($TOOL "$WORK/source" linux) == stable ]]
|
|
|
|
# An unavailable upgrade must be a hard failure.
|
|
reset_state
|
|
manifest 1.99
|
|
printf '1.98.1\n' > "$WORK/state/stable.version"
|
|
if MOCK_INSTALL_FAIL=1 "$TOOL" "$WORK/source" linux >/dev/null 2>&1; then
|
|
printf 'A failed rustup update should abort the build\n' >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo 'Rust toolchain selection: 8 offline scenarios OK'
|