You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
rtk test does not normalise an even, non-zero negation count — returns the child's status where a shell returns 0/1 #4289
rtk test applies the ! negation that the interposed sh -c string used to get from the shell. An odd count inverts the child's status, which is right. An even, non-zero count returns the child's status verbatim instead of normalising it to 0/1, so the answer can be a code no shell would give.
Found while reviewing #4125, on its head. Not a regression — see below — so it did not hold that PR.
Symptom
$ rtk test ! ( ! sh -c 'exit 2' )
exit 2
$ bash -c '! ( ! sh -c "exit 2" )'
exit 1
bash normalises: the result of a negation is a truth value, 0 or 1, never the operand's code. rtk returns 2, which reads as "the command failed with status 2" when what happened is "the doubly-negated condition is false".
The else is correct for negations == 0 and wrong for every even count above it. split_leading_negations peels !s and a wrapping ( … ) in a loop, so negations >= 2 arrives here from ! ! and, since #4125, from ! ( ! … ) as well.
The merge-base answered 0 for the same input — a reported pass for a command that failed, because the joined sh -c string took a different route through the shell. So the current code moved the answer into the right direction (non-zero for a false condition) and stopped short of the right value. Worth fixing on its own terms rather than as a regression.
Test
tests/run_shell_test.rs::grouped_and_negated_commands_keep_their_exit_codes covers eight spellings but cannot see this: its ! ! ( true ) case uses true, whose status is already 0, so normalising and not normalising agree. A case whose child exits non-zero under an even negation count — ! ! sh -c 'exit 2', ! ( ! sh -c 'exit 2' ) — is what pins it, asserted against bash.
rtk test fails to normalize exit code to 0/1 when negation count is even and non-zero, returning raw child status instead of a truth value like bash does.
This looks like a simple fix that could be auto-resolved. Repo maintainers can use /wshm fix to attempt it.
📁 Relevant files
src/main.rs
tests/run_shell_test.rs
Suggested Actions
Apply the fix shape given: add else if negations > 0 { i32::from(code != 0) } branch in src/main.rs Commands::Test arm
Add test case ! ! sh -c 'exit 2' / ! ( ! sh -c 'exit 2' ) to tests/run_shell_test.rs, asserted against bash
Activity
rtk-wshm-sync-bot commentedon Sep 26, 2026
🔍 Automated Triage
bugmediumSummary
rtk testfails to normalize exit code to 0/1 when negation count is even and non-zero, returning raw child status instead of a truth value like bash does.📁 Relevant files
src/main.rstests/run_shell_test.rsSuggested Actions
else if negations > 0 { i32::from(code != 0) }branch in src/main.rs Commands::Test arm! ! sh -c 'exit 2'/! ( ! sh -c 'exit 2' )to tests/run_shell_test.rs, asserted against bashcase(or subshell / brace group) anywhere on a line disables rewriting of every pipeline on that line #4283 (case/subshell disabling rewriting) since both touch negation/grouping parsingTriaged automatically by wshm · This is an automated analysis, not a human review.