Skip to content

Improve test coverage: 37 new command contract tests + fix nuke-without-kill re-init#32

Merged
bashandbone merged 5 commits intomainfrom
copilot/create-test-development-plan
Mar 19, 2026
Merged

Improve test coverage: 37 new command contract tests + fix nuke-without-kill re-init#32
bashandbone merged 5 commits intomainfrom
copilot/create-test-development-plan

Conversation

Copy link
Contributor

Copilot AI commented Mar 18, 2026

Coverage was ~53%. Adds 37 integration tests targeting the highest-value gaps — command output contracts, config accuracy, and complex workflows — and fixes three real bugs uncovered in the process.

New tests (tests/command_contract_tests.rs)

  • Shell completionscompleteme for bash/zsh/fish/nushell; asserts non-empty output and subcommand name presence
  • add --no-init — config-only add without cloning; subsequent init materializes it
  • nuke-it-from-orbit--all clears every submodule; reinit (without --kill) restores the clone and preserves sparse-checkout patterns
  • generate-config--from-setup reads .gitmodules; --force overwrites existing file (no-force fails)
  • change — path relocation (delete+re-clone), URL swap, active toggle, sparse-path replace vs. append, multiple fields in one call
  • change-global — persists update/fetch fields; errors without args
  • Error contracts — nonexistent targets for delete, disable, change, nuke all fail with an informative message
  • Output phrase contracts — exact strings asserted for every command (add, check, init, reset, sync, update, list, disable, delete)
  • Config persistence — all fields written by add; multiple adds all survive; delete preserves sibling sections

Bug fixes (discovered by the new tests)

nuke-without-kill fails to re-initialize — three-layer bug

1. --branch . is invalid for git submodule add

"." is the .gitmodules encoding for CurrentInSuperproject; passing it as a --branch argument causes fatal: 'HEAD' is not a valid branch name. The CLI fallback now skips the flag when the branch resolves to ".".

2. git2 uses path as key, cleanup used name

git2::Repository::submodule() keys .git/config and .git/modules/ by path (e.g. lib/reinit), not by name (e.g. reinit-lib). After a delete, the name-based cleanup left stale path-based artifacts that caused git2's subsequent add to fail. delete_submodule_by_name and the CLI fallback now remove both.

# Before fix: stale after delete
.git/config         → [submodule "lib/reinit"]   ← not cleaned
.git/modules/       → lib/reinit/                ← not cleaned

# After fix: both key forms removed

3. git2 Repository object caches stale submodule state

Even after filesystem cleanup, the in-memory git2::Repository still believed the submodule existed and refused to re-add it. delete_submodule_by_name now calls git_ops.reopen() — a new method on GitOpsManager — to reopen the repository from disk after a destructive operation.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • invalid-host
    • Triggering command: /usr/bin/ssh /usr/bin/ssh -o SendEnv=GIT_PROTOCOL git@invalid-host git-upload-pack 'user/repo.git' user.email test@example.com git /usr/libexec/gccgit low /home/REDACTED/.ru-m git clea�� low /home/REDACTED/.ruInitial commit k/_temp/ghcca-node/node/bin/git gnu -plugin /usr/local/sbin/user.email git (dns block)
    • Triggering command: /home/REDACTED/work/submod/submod/target/debug/submod /home/REDACTED/work/submod/submod/target/debug/submod add git@invalid-host:user/repo.git --name invalid-test --path lib/invalid p/bin/git README.md basename nfig/composer/ve--revs git init�� /tmp/.tmpv1ER8k/--delta-base-offset it git HEAD refs/heads/main /home/REDACTED/wors/-/ / git (dns block)
    • Triggering command: /usr/bin/ssh /usr/bin/ssh -o SendEnv=GIT_PROTOCOL git@invalid-host git-upload-pack 'user/repo.git' -fdx (dns block)
  • nonexistent.domain.invalid
    • Triggering command: /home/REDACTED/work/submod/submod/target/debug/submod /home/REDACTED/work/submod/submod/target/debug/submod add REDACTED --name invalid-test --path lib/invalid /usr/lib/git-core/git s/rustcRJ12FY/sygit s/error_handlingconfig s/error_handlinguser.email git rev-�� --git-dir s/error_handling_tests-1388c0cc70dcfabb.43s2t6zslib/large k/_temp/ghcca-node/node/bin/git s/error_handlinggit s/error_handlingrm s/error_handling--cached git (dns block)
    • Triggering command: /usr/lib/git-core/git-remote-http /usr/lib/git-core/git-remote-http origin REDACTED git conf�� user.email test@example.com nfig/composer/vendor/bin/git (dns block)
    • Triggering command: /home/REDACTED/work/submod/submod/target/debug/submod /home/REDACTED/work/submod/submod/target/debug/submod add REDACTED --name invalid-test --path lib/invalid /home/REDACTED/work/_temp/ghcca-node/node/bin/git user.email test@example.comconfig /usr/local/.ghcuuser.email git conf�� user.name Test User /home/REDACTED/.dotnet/tools/git user.email test@example.comconfig nfig/composer/ve--remove-section git (dns block)
  • nonexistent.invalid.domain.test
    • Triggering command: /home/REDACTED/work/submod/submod/target/debug/submod /home/REDACTED/work/submod/submod/target/debug/submod add REDACTED --name timeout-test --path lib/timeout k/_temp/ghcca-node/node/bin/git (dns block)
    • Triggering command: /usr/lib/git-core/git-remote-http /usr/lib/git-core/git-remote-http origin REDACTED git conf�� protocol.file.allow always /usr/local/.ghcup/bin/git target/debug/depgit target/debug/deprm target/debug/dep--cached git conf�� user.email test@example.com k/submod/submod/target/debug/submod target/debug/depgit target/debug/depsubmodule cal/bin/cc k/submod/submod/--name (dns block)
    • Triggering command: /home/REDACTED/work/submod/submod/target/debug/submod /home/REDACTED/work/submod/submod/target/debug/submod add REDACTED --name timeout-test --path lib/timeout it origin main p/bin/git git init�� e /home/REDACTED/work/submod/submod/--all rgo/bin/git --all --kill ndor/bin/git git (dns block)

If you need me to access, download, or install something from one of these locations, you can either:


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits March 18, 2026 22:49
Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com>
…it bugs

- Add tests/command_contract_tests.rs with 37 new integration tests covering:
  completeme shell completions, add --no-init, nuke --all/reinit, generate-config
  --from-setup/--force, change path/url/active/sparse-paths, error contracts
  for nonexistent targets, output phrase contracts for all commands, and
  config accuracy/persistence tests

- Fix nuke-without-kill re-init failures (cascade of three bugs):
  1. git_ops/mod.rs: skip --branch . (CurrentInSuperproject token) in CLI
     fallback — passing "." as a --branch arg to git submodule add is invalid
  2. git_ops/mod.rs: cleanup both name-based AND path-based .git/config entries
     and .git/modules/ directories in CLI fallback (git2 uses path as key)
  3. git_manager.rs: add comprehensive path-based cleanup in
     delete_submodule_by_name and call git_ops.reopen() afterward so the
     in-memory git2 Repository object reflects the updated on-disk state
- git_ops/mod.rs: expose workdir() and reopen() on GitOpsManager

Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com>
Copilot AI changed the title [WIP] Triage testing gaps and create development plan Improve test coverage: 37 new command contract tests + fix nuke-without-kill re-init Mar 18, 2026
Copilot AI requested a review from bashandbone March 18, 2026 23:15
@bashandbone bashandbone marked this pull request as ready for review March 18, 2026 23:31
Copilot AI review requested due to automatic review settings March 18, 2026 23:31
@codecov
Copy link

codecov bot commented Mar 18, 2026

Codecov Report

❌ Patch coverage is 81.53846% with 12 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/git_ops/mod.rs 82.05% 7 Missing ⚠️
src/git_manager.rs 80.76% 5 Missing ⚠️
Files with missing lines Coverage Δ
src/git_manager.rs 88.91% <80.76%> (+15.37%) ⬆️
src/git_ops/mod.rs 75.73% <82.05%> (+1.10%) ⬆️

... and 5 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR expands integration coverage around the submod CLI’s command/output contracts and fixes a re-init failure in the nuke-it-from-orbit (without --kill) workflow by improving submodule cleanup and refreshing git2 repository state.

Changes:

  • Add a large new integration test suite validating command output phrases, error contracts, config persistence, and multi-step workflows.
  • Fix submodule re-init after delete/nuke by cleaning both name-based and path-based git artifacts and reopening the git2 repository state.
  • Adjust git CLI fallback to avoid passing an invalid --branch . to git submodule add.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.

File Description
tests/command_contract_tests.rs Adds extensive integration tests covering command behavior, output contracts, and config accuracy/persistence.
src/git_ops/mod.rs Adds workdir()/reopen(), improves cleanup of path-keyed submodule artifacts, and skips invalid --branch . in CLI fallback.
src/git_manager.rs Strengthens delete cleanup for path-keyed artifacts and calls git_ops.reopen() post-delete to avoid git2 cached state issues.
Cargo.lock Removes an unused dependency entry (serde_json).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copy link
Owner

@bashandbone bashandbone left a comment

Choose a reason for hiding this comment

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

Really strong work on this PR; identifying important bugs and filling testing gaps.

@bashandbone
Copy link
Owner

@copilot The build is failing in CI with linting errors:

error[E0308]: mismatched types
    --> src/git_manager.rs:1341:16
     |
1341 |         if let Err(e) = self.git_ops.reopen() {
     |                ^^^^^^   --------------------- this expression has type `()`
     |                |
     |                expected `()`, found `Result<_, _>`
     |
     = note: expected unit type `()`
                     found enum `Result<_, _>`

For more information about this error, try `rustc --explain E0308`.

Please run clippy/rustfmt and make sure to resolve all errors and warnings.

…smatch

reopen() was returning () but git_manager.rs used `if let Err(e) = reopen()`
which requires a Result. Now returns Err if git2 (required backend) fails to
reopen; gix reopen failures are non-fatal and logged as warnings.

Addresses reviewer feedback to propagate reopen errors instead of silently
ignoring them.

Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 18, 2026

@copilot The build is failing in CI with linting errors:

...

Fixed in 4123e53. reopen() now returns Result<()> — it returns an error if the git2 backend (required) fails to reopen, while gix failures (optional backend) are logged as warnings and treated as non-fatal. This both fixes the type mismatch and addresses the reviewer's concern about silent error masking.

@bashandbone bashandbone merged commit 87f3089 into main Mar 19, 2026
7 checks passed
@bashandbone bashandbone deleted the copilot/create-test-development-plan branch March 19, 2026 01:22
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.

3 participants