fix: discard-dist-on-failure keeps the step's status when its message cannot be written (closes #342)
With stderr closed, the wrapper's message write failed and set -e ended it with status 2; with stderr a pipe whose reader had gone, the write killed it with 141. Either replaced the failed step's own status. The message is now written with SIGPIPE ignored and its failure ignored, after the step has run, so the step still sees the default SIGPIPE. The header now states that an interrupt removes nothing (it is not a build failure) and that a failed check-censored --require-dist removes dist/ (a dist/ not cleared of the barred name must not ship); neither behaviour changed. Also the README bullet's missing period. Model: opus-5-5
This commit is contained in:
@@ -277,7 +277,7 @@ provide:
|
||||
step's exit status, saying on stderr that it did and why. Every step of
|
||||
`make build` runs through it; `make build-debug` runs none of them through it.
|
||||
A step that succeeds removes nothing, and a removal that cannot be completed
|
||||
is reported as loudly as one that was
|
||||
is reported as loudly as one that was.
|
||||
- `script/test-verify-build` — exercise every failure mode of
|
||||
`script/verify-build` against a fixture tree in a temp dir, asserting the exit
|
||||
status and the message of each, assert the state of `dist/` on disk after a
|
||||
|
||||
@@ -45,6 +45,17 @@ but the review is broader than any of them.
|
||||
|
||||
# Completed Steps
|
||||
|
||||
- 2026-10-07: `script/discard-dist-on-failure` returns the failed step's own
|
||||
exit status even when it cannot write its message, to a closed stderr or to a
|
||||
pipe nobody reads any more
|
||||
([#342](https://git.eeqj.de/sneak/AutistMask/issues/342)); it used to return 2
|
||||
or 141 instead. Its header now states that an interrupt removes nothing and
|
||||
says nothing, because an interrupt is not a build failure, and that a failed
|
||||
`check-censored --require-dist` removes `dist/` like any other step, because a
|
||||
`dist/` not cleared of the name `RULES.md` bars must not ship. Neither
|
||||
behaviour changed. `script/test-verify-build` runs the wrapper with stderr
|
||||
closed.
|
||||
|
||||
- 2026-10-06: `script/bootstrap` no longer reports success while node cannot
|
||||
find a package listed in `dependencies` or `devDependencies` of `package.json`
|
||||
([#263](https://git.eeqj.de/sneak/AutistMask/issues/263)). After the install
|
||||
|
||||
@@ -3,22 +3,19 @@
|
||||
# step fails, remove dist/ before returning its exit status. Our own extension
|
||||
# to scripts-to-rule-them-all, wrapped around every step of make build.
|
||||
#
|
||||
# Why: with AUTISTMASK_DEBUG=1 exported in the calling shell, make build
|
||||
# compiles a debug bundle and then fails on it in script/verify-build — but the
|
||||
# bundle is already written. It is loadable, and every wallet it creates gets
|
||||
# the publicly committed test recovery phrase from src/shared/constants.js. A
|
||||
# failed release build that leaves that behind is a smaller version of the trap
|
||||
# the verifier exists to close, and "the failure was loud" only works on an
|
||||
# operator who does not load dist/chrome/ anyway. Removing the artifact does not
|
||||
# depend on that.
|
||||
# Why: with AUTISTMASK_DEBUG=1 exported, make build compiles a debug bundle and
|
||||
# then fails on it in script/verify-build, after the bundle is written. It is
|
||||
# loadable, and every wallet it creates gets the publicly committed test
|
||||
# recovery phrase from src/shared/constants.js, so a failed build must not leave
|
||||
# it behind. The removal is never silent: it says on stderr that dist/ is gone
|
||||
# and why.
|
||||
#
|
||||
# Two things this deliberately does not do. It does not wrap make build-debug: a
|
||||
# debug build that failed is not a mistakable artifact, and its output is the
|
||||
# evidence of what went wrong. And it never removes anything on a step that
|
||||
# SUCCEEDS, including the final check-censored --require-dist pass.
|
||||
#
|
||||
# The removal is never silent: it says dist/ is gone and why, on stderr, above
|
||||
# the build's own failure.
|
||||
# A failed check-censored --require-dist removes dist/ like any other step: a
|
||||
# dist/ not cleared of the name RULES.md bars must not ship either. A step that
|
||||
# succeeds removes nothing. An interrupt (Ctrl-C) removes nothing and says
|
||||
# nothing: it is not a build failure, and whoever interrupted the build knows it
|
||||
# did not finish. make build-debug is not wrapped: a debug build that failed is
|
||||
# not a mistakable artifact, and its output is the evidence of what went wrong.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
@@ -71,7 +68,10 @@ main() {
|
||||
|
||||
[ "$_status" -ne 0 ] || return 0
|
||||
|
||||
discard_dist
|
||||
# A message that cannot be written, to a closed stderr or to a pipe nobody
|
||||
# reads any more, must not replace the step's status.
|
||||
trap '' PIPE
|
||||
discard_dist || true
|
||||
exit "$_status"
|
||||
}
|
||||
|
||||
|
||||
@@ -915,6 +915,22 @@ run_cases() {
|
||||
discard_case "the wrapper given no command removes nothing" \
|
||||
c_control 1 kept "no command given" ""
|
||||
|
||||
# With stderr closed the wrapper cannot write its message, and must still
|
||||
# remove dist/ and return the step's own status.
|
||||
build_fixture
|
||||
_status=0
|
||||
(cd "$FIXTURE" &&
|
||||
"$FIXTURE/script/discard-dist-on-failure" sh -c 'exit 6' 2>&-) ||
|
||||
_status=$?
|
||||
if [ "$_status" -eq 6 ] && [ ! -e "$FIXTURE/dist" ]; then
|
||||
PASSED=$((PASSED + 1))
|
||||
echo " ok: a failed step's status survives a closed stderr"
|
||||
else
|
||||
FAILED=$((FAILED + 1))
|
||||
echo " FAIL: a failed step's status survives a closed stderr"
|
||||
echo " exit status $_status, wanted 6, and dist/ must be gone"
|
||||
fi
|
||||
|
||||
check_makefile_wiring
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user