Skip to content

feat(cli): --changed to run only the tests touched since a git ref #1010

Description

@Chemaclass

Problem

On a large suite, the fastest feedback loop is "run only what my branch touched", and bashunit cannot express it. Today the options are --rerun-failed (needs a previous failing run) or a hand-rolled git diff | xargs ./bashunit, which breaks on renames, deletions and quoting.

src/helper/git.sh exists but only holds get_latest_tag, so there is no git plumbing to build on yet.

Proposal

--changed [<ref>]     Run only test files changed since <ref> (default: origin/HEAD, then HEAD)

Selection set:

  1. Test files added or modified in git diff --name-only --diff-filter=d <ref>...HEAD, plus uncommitted changes in the working tree and index.
  2. Filtered to files that match the test-file pattern and live under the given path argument.

Deleted test files are dropped (--diff-filter=d). Behaviour when not inside a git work tree, or when <ref> does not resolve: exit non-zero with a clear message rather than silently running everything (#871 class of bug).

Explicitly out of scope for this issue: mapping source changes to the tests that cover them. That needs a @covers-style annotation and should be its own issue if wanted.

Where to change

  • src/helper/git.sh — add bashunit::helper::git::changed_files and bashunit::helper::git::is_repo.
  • src/helper/discovery.sh:208 load_test_files — intersect discovery with the changed set.
  • src/main/test.sh, src/config/env.sh (BASHUNIT_CHANGED), .env.example.

Acceptance criteria

  • --changed with no argument diffs against origin/HEAD when it resolves, otherwise HEAD
  • --changed main diffs against main
  • Uncommitted and staged modifications to a test file are included
  • Deleted test files are excluded (no "file not found" error)
  • Renamed test files select the new path only
  • Combines with --filter / --tag (intersection)
  • Outside a git work tree: non-zero exit with an explicit message, not a full run
  • An unresolvable ref: non-zero exit with the ref quoted in the message
  • No changed test files: "No tests found" path, current exit code preserved
  • Acceptance test builds a throwaway git repo in a temp dir (bashunit::temp_dir), not the bashunit repo itself

Repo checklist (agent)

  • TDD: RED → GREEN → REFACTOR. Write the failing test first.
  • Bash 3.0+ only: no printf -v, no += append, no declare -A, no [[ ]], no ${var,,}, no &>>, no ${arr[-1]}. Expanding a possibly-empty array under set -u needs ${arr[@]+"${arr[@]}"}.
  • A new CLI flag must be wired in all of these or a parity test fails:
  • Gates: make sa, make lint, ./bashunit tests/, ./bashunit --parallel tests/. Never run shfmt -w.
  • Docs: update docs/command-line.md. Editing docs/assertions.md invalidates the bashunit doc acceptance snapshot — regenerate it.
  • CHANGELOG.md: add one line under ## Unreleased.
  • Fixtures under tests/acceptance/fixtures/ must not end in *test.sh.
  • One issue = one PR.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions