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. 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
This commit is contained in:
@@ -915,6 +915,76 @@ 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
|
||||
|
||||
# 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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user