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
- `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)
- A run's scratch-directory cleanup can no longer widen to every concurrent run's: the safety guard accepted any path containing `/bashunit/run/`, which includes the per-OS parent that all runs on a machine share, so a run whose random token came out empty would have deleted the others' directories along with its own. Both the run and the parallel trees now require the token segment (#1165)
Expand Down
22 changes: 16 additions & 6 deletions src/cli/init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,26 @@ SH
local env_file=".env"
local env_line="BASHUNIT_BOOTSTRAP=$bootstrap_file"
if [ -f "$env_file" ]; then
if grep -q "^BASHUNIT_BOOTSTRAP=" "$env_file"; then
if bashunit::check_os::is_macos; then
sed -i '' -e "s/^BASHUNIT_BOOTSTRAP=/#&/" "$env_file"
else
sed -i -e "s/^BASHUNIT_BOOTSTRAP=/#&/" "$env_file"
# Already pointing where this run would point it: leave the file alone.
# Commenting the line out and appending an identical one made every re-init
# add a dead line, so a third run left three (#1175). -Fx so a dot in the
# path is compared literally.
if grep -Fxq "$env_line" "$env_file"; then
echo "> $env_file already sets BASHUNIT_BOOTSTRAP"
else
if grep -q "^BASHUNIT_BOOTSTRAP=" "$env_file"; then
if bashunit::check_os::is_macos; then
sed -i '' -e "s/^BASHUNIT_BOOTSTRAP=/#&/" "$env_file"
else
sed -i -e "s/^BASHUNIT_BOOTSTRAP=/#&/" "$env_file"
fi
fi
echo "$env_line" >>"$env_file"
echo "> Updated $env_file"
fi
echo "$env_line" >>"$env_file"
else
echo "$env_line" >"$env_file"
echo "> Created $env_file"
fi

echo "> bashunit initialized in $tests_dir"
Expand Down
39 changes: 39 additions & 0 deletions tests/acceptance/bashunit_init_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,42 @@ function test_bashunit_init_updates_env() {
assert_file_contains .env "BASHUNIT_BOOTSTRAP=custom/bootstrap.sh"
popd >/dev/null
}

# `bashunit init` is run more than once in practice -- re-scaffolding, or a
# setup script that is not guarded. The files it writes are idempotent; .env
# was not: every run commented out the previous BASHUNIT_BOOTSTRAP and appended
# a fresh copy, so a third run left three lines, two of them dead (#1175).
function test_bashunit_init_does_not_duplicate_the_bootstrap_setting() {
pushd "$TMP_DIR" >/dev/null
"$BASHUNIT_PATH" init >"$TMP_DIR/init.log"
"$BASHUNIT_PATH" init >>"$TMP_DIR/init.log"
"$BASHUNIT_PATH" init >>"$TMP_DIR/init.log"

local active commented
active=$("$GREP" -c '^BASHUNIT_BOOTSTRAP=' .env || true)
commented=$("$GREP" -c '^#BASHUNIT_BOOTSTRAP=' .env || true)
popd >/dev/null

assert_same 1 "$active"
assert_same 0 "$commented"
}

# Whatever else lives in .env is the user's and predates bashunit.
function test_bashunit_init_keeps_the_rest_of_an_existing_env_file() {
pushd "$TMP_DIR" >/dev/null
printf '%s\n' 'MY_SECRET=keepme' >.env
"$BASHUNIT_PATH" init >"$TMP_DIR/init.log"
popd >/dev/null

assert_file_contains "$TMP_DIR/.env" "MY_SECRET=keepme"
}

# The three scaffolded files are announced; the .env write was not, so a user
# reviewing what init touched before committing would miss it.
function test_bashunit_init_reports_the_env_file_it_writes() {
pushd "$TMP_DIR" >/dev/null
"$BASHUNIT_PATH" init >"$TMP_DIR/init.log"
popd >/dev/null

assert_file_contains "$TMP_DIR/init.log" ".env"
}
Loading