|
|
|
@@ -126,9 +126,32 @@ CONTENT_B='pub fn f() -> u32 { 22222 } pub fn g() -> u32 { 7 }'
|
|
|
|
|
# 2 NOT MEASURED — a probe step failed; nothing was
|
|
|
|
|
# learned about the toolchain
|
|
|
|
|
#
|
|
|
|
|
# Every step that could fail for a reason other than the experiment's own
|
|
|
|
|
# outcome exits 2 explicitly, so a `set -e` abort can never be mistaken for the
|
|
|
|
|
# `1` that means "measured, and the answer is mtime".
|
|
|
|
|
# Two mechanisms, and BOTH are needed. Every step that could fail for a reason
|
|
|
|
|
# other than the experiment's own outcome exits 2 explicitly; the subshell also
|
|
|
|
|
# arms `set -e` with an ERR trap that maps any unguarded failure onto 2, so a
|
|
|
|
|
# step added later without a guard lands on "not measured" rather than on an
|
|
|
|
|
# answer.
|
|
|
|
|
#
|
|
|
|
|
# The `set +e` around the call site is what makes the second mechanism work,
|
|
|
|
|
# and it is not decoration. A command on the left of `||` — or in an `if`
|
|
|
|
|
# condition — runs with errexit suppressed, and that suppression propagates
|
|
|
|
|
# into a subshell and is NOT undone by a `set -e` inside it (verified on bash
|
|
|
|
|
# 5.3: an unguarded `false` there falls through to `exit 0` and reports
|
|
|
|
|
# ACTIVE). Calling with errexit disarmed at the site is the only form that
|
|
|
|
|
# lets the subshell re-arm it. The ERR trap is then required on top, because a
|
|
|
|
|
# bare `set -e` abort exits with the FAILING COMMAND's status — `false` gives
|
|
|
|
|
# 1, which is precisely the value that means "measured, and the answer is
|
|
|
|
|
# mtime". Belt and braces here buys a wrong answer; belt, braces and a trap
|
|
|
|
|
# buys "not measured".
|
|
|
|
|
#
|
|
|
|
|
# WHY 2 SKIPS RATHER THAN FAILS. The scenario it gates is the only thing in
|
|
|
|
|
# this suite that depends on freshness mode; everything else still runs and
|
|
|
|
|
# still catches real regressions. Failing instead would turn a statement about
|
|
|
|
|
# one machine's toolchain into a red gate reading "the hardlink scheme is
|
|
|
|
|
# broken" across the three repos consuming this action — the same category
|
|
|
|
|
# error the three-state split exists to prevent, one level up. What would
|
|
|
|
|
# change the answer is 2 becoming the everyday CI outcome; it is not (gitdan-ci
|
|
|
|
|
# reports 1, by measurement).
|
|
|
|
|
CHECKSUM_MODE="off"
|
|
|
|
|
CHECKSUM_REASON="no nightly on PATH accepting -Z checksum-freshness"
|
|
|
|
|
CARGO_BIN=(cargo)
|
|
|
|
@@ -136,6 +159,8 @@ checksum_freshness_probe() {
|
|
|
|
|
local d="$scratch/freshness-probe" t="$scratch/freshness-probe-target"
|
|
|
|
|
mkcrate "$d" || return 2
|
|
|
|
|
(
|
|
|
|
|
set -e
|
|
|
|
|
trap 'exit 2' ERR
|
|
|
|
|
cd "$d" || exit 2
|
|
|
|
|
printf '%s\n' "$CONTENT_A" > src/lib.rs || exit 2
|
|
|
|
|
CARGO_TARGET_DIR="$t" cargo +nightly build -q > "$scratch/freshness-probe-warm.log" 2>&1 || exit 2
|
|
|
|
@@ -148,8 +173,13 @@ checksum_freshness_probe() {
|
|
|
|
|
}
|
|
|
|
|
if cargo +nightly -Z checksum-freshness locate-project > /dev/null 2>&1; then
|
|
|
|
|
export CARGO_UNSTABLE_CHECKSUM_FRESHNESS=true
|
|
|
|
|
# Errexit off across the call, so the subshell can arm its own — see the
|
|
|
|
|
# header. `probe_rc` is read before it is restored.
|
|
|
|
|
probe_rc=0
|
|
|
|
|
checksum_freshness_probe || probe_rc=$?
|
|
|
|
|
set +e
|
|
|
|
|
checksum_freshness_probe
|
|
|
|
|
probe_rc=$?
|
|
|
|
|
set -e
|
|
|
|
|
case "$probe_rc" in
|
|
|
|
|
0)
|
|
|
|
|
CARGO_BIN=(cargo +nightly)
|
|
|
|
|