Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- Performance: `--coverage` is roughly 5x faster and `--coverage-report-html` roughly 19x — a run over this repo went from 16.2s to 2.9s, and a 128-file HTML report from 58.7s to 3.1s. The report phase emits each format in one awk invocation per run instead of Bash loops and forks per file and per row, and the capture path writes records straight to disk, normalizes a path with one fork instead of four, and reads each cache once (#1092, #1096, #1098, #1099, #1102, #1104, #1110, #1117)

### Fixed
- A report path that is a directory (`--report-junit build/` with the filename forgotten) fails fast with `is a directory, not a file` instead of passing validation, failing inside the writer with a raw bash message naming a bashunit source file, and exiting 0 with no report written. Affects every report flag and the `bench` equivalents (#1177)
- `bashunit init` no longer adds a dead `BASHUNIT_BOOTSTRAP` line to `.env` on every run: it commented out the existing setting and appended a fresh copy even when the value was unchanged, so a third run left three lines, two of them inert. It also now reports what it did to `.env`, the one file it wrote without saying so (#1175)
- A coverage run that tracked no executable line at all no longer reports it as `Coverage 0% is below minimum N%`: that 0% is arithmetic rather than a measurement, and the message sent the reader to their tests when the cause is almost always a `--coverage-paths` that matched nothing. The gate still fails, now naming the real problem (#1171)
- A run whose scratch directory goes missing now says so once, on stderr, naming the directory, instead of recovering silently — the recovery added for that case left no trace at all, which is worse for diagnosis than the misleading error it replaced (#1167)
Expand Down
24 changes: 24 additions & 0 deletions src/main/validate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,32 @@ function bashunit::main::require_non_negative_int_or_exit() {
# raw redirect error on a run that had already reported success (#875).
# Arguments: $1 - path, $2 - the setting name to quote in the error
##
##
# Exits with the same shape as the writability errors, but says which mistake
# it was: "cannot be written" sends the reader to permissions, and a directory
# is almost always a forgotten filename.
# Arguments: $1 - path, $2 - setting name
##
function bashunit::main::report_path_is_a_directory() {
printf "%sError: %s is a directory, not a file: '%s'.%s\n" \
"$_BASHUNIT_COLOR_FAILED" "${2:-path}" "$1" "$_BASHUNIT_COLOR_DEFAULT" >&2
exit 1
}


function bashunit::main::require_writable_path_or_exit() {
local path=$1
local parent=${1%/*}
[ "$parent" = "$1" ] && parent="."
[ -z "$parent" ] && parent="/"

# A directory satisfies both -e and -w, so it used to pass here and fail much
# later inside the writer -- with a raw bash message naming a bashunit source
# file, and an exit status of 0 (#1177).
if [ -d "$path" ]; then
bashunit::main::report_path_is_a_directory "$path" "${2:-}"
fi

if [ -e "$path" ]; then
[ -w "$path" ] && return 0
elif [ -d "$parent" ] && [ -w "$parent" ]; then
Expand Down Expand Up @@ -72,6 +92,10 @@ function bashunit::main::require_creatable_path_or_exit() {
done
[ -z "$ancestor" ] && ancestor="/"

if [ -d "$path" ]; then
bashunit::main::report_path_is_a_directory "$path" "${2:-}"
fi

if [ -d "$ancestor" ] && [ -w "$ancestor" ] &&
{ [ ! -e "$path" ] || [ -w "$path" ]; }; then
return 0
Expand Down
17 changes: 17 additions & 0 deletions tests/acceptance/bashunit_bench_reports_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,23 @@ function test_an_unwritable_report_path_fails_fast() {
assert_contains "cannot be written" "$output"
}

# A directory satisfies both `-e` and `-w`, so it passed the writability check
# and the run continued to the writer, which failed with a raw bash message
# naming a bashunit source file -- and the run still exited 0. A CI job
# publishing that report would find no file and nothing red to explain it
# (#1177).
function test_a_report_path_that_is_a_directory_fails_fast() {
local dir
dir="$(bashunit::temp_dir)"

local ec=0
local output
output=$(./bashunit bench --report-json "$dir" "$FIXTURE" 2>&1) || ec=$?

assert_general_error "" "" "$ec"
assert_contains "is a directory" "$output"
}

function test_the_flags_are_advertised_by_bench_help() {
local output
output=$(./bashunit bench --help 2>&1)
Expand Down
Loading