Improve test coverage: 37 new command contract tests + fix nuke-without-kill re-init#32
Conversation
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>
Codecov Report❌ Patch coverage is
... and 5 files with indirect coverage changes 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
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 .togit 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>
bashandbone
left a comment
There was a problem hiding this comment.
Really strong work on this PR; identifying important bugs and filling testing gaps.
|
@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>
... Fixed in 4123e53. |
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)completemefor bash/zsh/fish/nushell; asserts non-empty output and subcommand name presenceadd --no-init— config-only add without cloning; subsequentinitmaterializes itnuke-it-from-orbit—--allclears every submodule; reinit (without--kill) restores the clone and preserves sparse-checkout patternsgenerate-config—--from-setupreads.gitmodules;--forceoverwrites existing file (no-force fails)change— path relocation (delete+re-clone), URL swap,activetoggle, sparse-path replace vs. append, multiple fields in one callchange-global— persistsupdate/fetchfields; errors without argsdelete,disable,change,nukeall fail with an informative messageadd,check,init,reset,sync,update,list,disable,delete)add; multiple adds all survive;deletepreserves sibling sectionsBug fixes (discovered by the new tests)
nuke-without-killfails to re-initialize — three-layer bug1.
--branch .is invalid forgit submodule add"."is the.gitmodulesencoding forCurrentInSuperproject; passing it as a--branchargument causesfatal: '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/configand.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_nameand the CLI fallback now remove both.3. git2
Repositoryobject caches stale submodule stateEven after filesystem cleanup, the in-memory
git2::Repositorystill believed the submodule existed and refused to re-add it.delete_submodule_by_namenow callsgit_ops.reopen()— a new method onGitOpsManager— 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/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)/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)/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/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)/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)/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/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)/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)/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.