Skip to content

chore: vendor bats test helpers instead of git submodules#859

Merged
jdx merged 1 commit intomainfrom
chore/remove-submodules
Apr 23, 2026
Merged

chore: vendor bats test helpers instead of git submodules#859
jdx merged 1 commit intomainfrom
chore/remove-submodules

Conversation

@jdx
Copy link
Copy Markdown
Owner

@jdx jdx commented Apr 23, 2026

Summary

  • Inlines bats-core, bats-assert, bats-file, and bats-support into the repo so cloning no longer needs --recurse-submodules or mise run init.
  • Drops submodules: recursive from every CI workflow (ci, docs, release, release-plz, autofix) and removes self.submodules = true from flake.nix.
  • Deletes .gitmodules and mise-tasks/init; updates CONTRIBUTING.md clone instructions.

Test plan

  • CI workflows succeed without submodule checkout
  • mise run test:bats runs end-to-end locally

🤖 Generated with Claude Code


Note

Medium Risk
Moderate risk because it replaces submodule-based test dependencies with vendored copies and updates CI/automation checkout behavior, which can break test execution or licensing/packaging expectations, but it does not change production runtime code.

Overview
Removes git submodule usage for Bats-based tests and vendors the Bats tooling and helper libraries directly into test/, eliminating the need for --recurse-submodules during cloning.

Updates automation to match this new layout: all GitHub Actions workflows drop submodules: recursive, flake.nix no longer enables submodules, mise build no longer depends on an init task, and contributor docs are updated; .gitmodules and mise-tasks/init are deleted accordingly.

Reviewed by Cursor Bugbot for commit 124429e. Bugbot is set up for automated code reviews on this repo. Configure here.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 23, 2026

Greptile Summary

This PR vendors the bats-core, bats-assert, bats-file, and bats-support test helpers directly into the repository, eliminating all git submodule usage. All CI workflows, the Nix flake, the mise-tasks/build dependency list, and contributor documentation are updated accordingly. The change is clean and mechanical with no logic modifications.

Confidence Score: 5/5

Safe to merge — purely mechanical removal of git submodules in favour of vendored copies with no logic changes.

All findings are informational. Every submodule reference has been consistently removed across CI workflows, flake.nix, mise-tasks, and contributor docs. The vendored files replace the submodules at the same paths, so test execution paths are unchanged.

No files require special attention.

Important Files Changed

Filename Overview
.github/workflows/ci.yml Removes submodules: recursive from all six checkout steps; no other changes
.gitmodules Deleted; all four submodule declarations removed as content is now vendored
flake.nix Removes self.submodules = true from inputs; correct since test helpers are now vendored and no longer need submodule checkout
mise-tasks/build Drops the init task dependency; correct now that submodule initialisation is no longer needed
mise-tasks/init Deleted; the git submodule update --init --recursive script is no longer needed
CONTRIBUTING.md Clone instruction updated to remove --recurse-submodules flag
test/bats/bin/bats Vendored bats-core entrypoint script, replacing former submodule
test/test_helper/bats-assert/load.bash Vendored bats-assert helper, replacing former submodule

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Developer clones repo] --> B["git clone https://github.com/jdx/hk.git"]
    B --> C[test/bats/ already present\nbats-core vendored]
    B --> D[test/test_helper/ already present\nbats-assert, bats-file, bats-support vendored]
    C --> E[mise run test:bats]
    D --> E

    CI[CI Workflow] --> F["actions/checkout\nno submodules flag needed"]
    F --> E

    subgraph Before
        G["git clone --recurse-submodules ..."] --> H["mise run init\ngit submodule update --init --recursive"]
        H --> I[test helpers available]
    end

    subgraph After
        B
        C
        D
    end
Loading

Reviews (3): Last reviewed commit: "chore: vendor bats test helpers instead ..." | Re-trigger Greptile

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pul l request vendors the bats-core testing framework and its helper libraries (bats-assert, bats-file, and bats-support) directly into the repository, removing the previous reliance on Git submodules. The review identified several technical issues within the vendored scripts: a bug in bats-exec-suite that incorrectly bundles com m and flags when running in parallel, a failure in the process-tracking logic of bats-exec-test that breaks timeouts, a regression in log filename form atting that introduces spaces, and a syntax error in the regex assertion logic. These issues should be addressed to ensure the testing infrastructure rem ains reliable and portable.

# shellcheck disable=SC2086,SC2068
# we need to handle the quoting of ${flags[@]} ourselves,
# because parallel can only quote it as one
"${parallel_binary_name}" --keep-order --jobs "$num_jobs" -- "bats-exec-file" "$(printf "%q " "${flags[@]}")" "{#}" "{}" "$TESTS_LIST_FILE" <<< "$(printf "%s\n" "${BATS_UNIQUE_TEST_FILENAMES[@]}")" 2>&1 || bats_exec_suite_status=1
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Bundling the flags array into a single quoted string using printf "%q " before passing it to parallel will cause all flags to be treated as a single argument by the worker processes. This will break option parsing in bats-exec-file. The flags should be passed as separate arguments to allow parallel to handle them correctly.

  "${parallel_binary_name}" --keep-order --jobs "$num_jobs" -- "bats-exec-file" "${flags[@]}" "{#}" "{}" "$TESTS_LIST_FILE" <<< "$(printf "%s\n" "${BATS_UNIQUE_TEST_FILENAMES[@]}")" 2>&1 || bats_exec_suite_status=1

printf "%d\n" "${row[$pid_col]}"
fi
done
} < <(ps -ef "$parent_pid")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The command ps -ef "$parent_pid" will only return information about the parent process itself on most systems, not its children. Since the subsequent loop checks for processes whose PPID matches $parent_pid, it will fail to find any child processes. This breaks the timeout mechanism which relies on identifying and killing child processes. It should be ps -ef to scan the full process list.

  } < <(ps -ef)

export BATS_RUNLOG_FILE='/dev/null'
else
# use UTC (-u) to avoid problems with TZ changes
BATS_RUNLOG_DATE=$(date -u '+%Y-%m-%d %H:%M:%S UTC')
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The date format used for log filenames contains spaces and special characters. This can lead to issues with filename handling in scripts and is a regression from the upstream bats-core format (%Y-%m-%dT%H:%M:%S). It is safer to avoid spaces in filenames to ensure portability and prevent potential parsing errors in other shell utilities.

  BATS_RUNLOG_DATE=$(date -u +%Y-%m-%dT%H:%M:%S)

local -r value="${1}"
local -r pattern="${2}"

if [[ '' =~ ${pattern} ]]; (( ${?} == 2 )); then
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There is a semicolon instead of a logical OR (||) between the regex test and the exit status check. This is inconsistent with the implementation in refute_regex.bash and appears to be a typo introduced during vendoring. Using || ensures that the error block is only entered if the regex evaluation fails with an exit status of 2 (invalid regex).

	if [[ '' =~ ${pattern} ]] || (( ${?} == 2 )); then

@jdx jdx force-pushed the chore/remove-submodules branch from d81ae2d to 3db4dc0 Compare April 23, 2026 18:43
Inline bats-core, bats-assert, bats-file, and bats-support into the
repo instead of pulling them in as git submodules. This removes the
need for `git clone --recurse-submodules` (or `mise-tasks/init`) and
drops the `submodules: recursive` checkout step from every CI workflow.

- Remove `.gitmodules` and delete the submodule gitlinks; commit the
  vendored source directly under `test/bats` and `test/test_helper/*`.
- Remove `mise-tasks/init` (only ran `git submodule update`).
- Strip `submodules: recursive` / `self.submodules = true` from
  workflows, `flake.nix`, and `CONTRIBUTING.md`.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@jdx jdx force-pushed the chore/remove-submodules branch from 3db4dc0 to 124429e Compare April 23, 2026 18:46
@jdx jdx enabled auto-merge (squash) April 23, 2026 18:49
@jdx jdx merged commit 25d55a2 into main Apr 23, 2026
20 checks passed
@jdx jdx deleted the chore/remove-submodules branch April 23, 2026 19:10
@jdx jdx mentioned this pull request Apr 23, 2026
jdx added a commit that referenced this pull request Apr 24, 2026
### 🐛 Bug Fixes

- **(git)** skip untracked scan when HK_STASH_UNTRACKED=false by
[@jdx](https://github.com/jdx) in
[#861](#861)
- **(run)** add post-commit and pre-rebase subcommands by
[@jdx](https://github.com/jdx) in
[#858](#858)

### 📚 Documentation

- **(install)** recommend global hooks as primary setup path by
[@jdx](https://github.com/jdx) in
[#855](#855)
- add cross-site announcement banner by [@jdx](https://github.com/jdx)
in [#857](#857)
- respect banner expires field by [@jdx](https://github.com/jdx) in
[#862](#862)

### 🔍 Other Changes

- vendor bats test helpers instead of git submodules by
[@jdx](https://github.com/jdx) in
[#859](#859)

### 📦️ Dependency Updates

- bump communique to 1.0.3 by [@jdx](https://github.com/jdx) in
[#863](#863)
- update anthropics/claude-code-action digest to e58dfa5 by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#864](#864)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk release bookkeeping only: version numbers, generated
CLI/docs, and lockfile dependency bumps with no runtime logic changes.
> 
> **Overview**
> **Release prep for `v1.44.1`.** Updates `Cargo.toml`/`Cargo.lock`
(including `libc`) and all version references in generated CLI docs
(`docs/cli/*`, `hk.usage.kdl`).
> 
> Refreshes documentation examples to reference the new `v1.44.1` Pkl
package URLs and adds the `1.44.1` entry to `CHANGELOG.md`.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
d7637d4. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: mise-en-dev <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant