1 Commits
Author SHA1 Message Date
sneak e6a18c92aa fix: discard-dist-on-failure keeps the step's status when its message cannot be written (closes #342)
check / check (push) Canceled after 0s
e2e / e2e-chrome (push) Canceled after 0s
e2e / e2e-firefox (push) Canceled after 0s
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. The message is now written with SIGPIPE ignored and its failure
ignored, after the step has run. An interrupt while a step runs now exits with
130 once the step has ended, removing nothing: under bash, a step that caught
the interrupt and exited with a status, as check-censored does, used to get
dist/ removed. A failed check-censored --require-dist still removes dist/. The
header states both. Also the README bullet's missing period.

Model: opus-5-5
2026-10-07 01:35:27 +00:00
3 changed files with 72 additions and 8 deletions
+9 -6
View File
@@ -49,12 +49,15 @@ but the review is broader than any of them.
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.
or 141 instead. An interrupt while a step runs now removes nothing and says
nothing whichever shell `/bin/sh` is, even when the step catches it and exits
with a status of its own, as `script/check-censored` does: the wrapper exits
with 130 once the step has ended. Under bash such a step used to have `dist/`
removed. A failed `check-censored --require-dist` still removes `dist/` like
any other step, because a `dist/` not cleared of the name `RULES.md` bars must
not ship. The header states both. `script/test-verify-build` runs the wrapper
with stderr closed and with stderr a pipe nobody reads, and interrupts it
under dash and under bash.
- 2026-10-06: `script/bootstrap` no longer reports success while node cannot
find a package listed in `dependencies` or `devDependencies` of `package.json`
+9 -2
View File
@@ -12,8 +12,10 @@
#
# 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
# succeeds removes nothing. An interrupt (Ctrl-C) while a step runs removes
# nothing and says nothing, even when the step catches it and exits with a
# status of its own: the wrapper exits with 130 once the step has ended. An
# interrupt 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
@@ -63,6 +65,11 @@ main() {
exit 1
}
# An interrupt is not a build failure: once the step has ended, exit
# without removing anything, even if the step caught the interrupt and
# exited with a status of its own. bash as /bin/sh would otherwise carry on.
trap 'exit 130' INT
_status=0
"$@" || _status=$?
+54
View File
@@ -931,6 +931,60 @@ run_cases() {
echo " exit status $_status, wanted 6, and dist/ must be gone"
fi
# The same with stderr a pipe nobody reads any more, where the write would
# kill the wrapper with SIGPIPE. The FIFO's only reader opens it, exits and
# is waited for before the wrapper runs, so the pipe never has a reader.
build_fixture
mkfifo "$WORK/stderr-fifo"
_status=0
(
: <"$WORK/stderr-fifo" &
exec 3>"$WORK/stderr-fifo"
wait "$!"
cd "$FIXTURE" &&
"$FIXTURE/script/discard-dist-on-failure" sh -c 'exit 6' 2>&3
) || _status=$?
if [ "$_status" -eq 6 ] && [ ! -e "$FIXTURE/dist" ]; then
PASSED=$((PASSED + 1))
echo " ok: a failed step's status survives a pipe nobody reads"
else
FAILED=$((FAILED + 1))
echo " FAIL: a failed step's status survives a pipe nobody reads"
echo " exit status $_status, wanted 6, and dist/ must be gone"
fi
# An interrupt while a step runs removes nothing and says nothing, even
# when the step catches it and exits with a status of its own, as
# script/check-censored does. The step interrupts the wrapper and then
# itself, as Ctrl-C interrupts every process of the build at once. Run
# under dash and under bash, which /bin/sh may each be: bash carries on
# after such a step unless the wrapper stops it.
for _shell in dash bash; do
_name="an interrupt under $_shell removes nothing"
if ! command -v "$_shell" >/dev/null 2>&1; then
SKIPPED=$((SKIPPED + 1))
SKIPPED_NAMES="$SKIPPED_NAMES## - $_name ($_shell not found)$NEWLINE"
echo " SKIP ($_shell not found): $_name"
continue
fi
build_fixture
_status=0
_out="$(cd "$FIXTURE" && "$_shell" \
"$FIXTURE/script/discard-dist-on-failure" \
sh -c 'trap "exit 4" INT; kill -INT "$PPID" $$; exit 5' 2>&1)" ||
_status=$?
if [ "$_status" -eq 130 ] && [ -z "$_out" ] &&
[ -f "$FIXTURE/dist/chrome/src/popup/index.js" ]; then
PASSED=$((PASSED + 1))
echo " ok: $_name"
else
FAILED=$((FAILED + 1))
echo " FAIL: $_name"
echo " exit status $_status, wanted 130; dist/ must be intact" \
"and nothing said. Output: $_out"
fi
done
check_makefile_wiring
}