Refactor for Testability - Core Architecture
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 5
- Forks
- 1
- Avg merge
- 17h 48m
- Merged PRs (30d)
- 2
Description
Problem
The codebase evolved from bash scripts to Rust CLI, resulting in:
- Monolithic command functions that are hard to test in isolation
- Heavy coupling to external services (GitHub API, Docker, S3, etc.)
- Side effects scattered throughout (file I/O, network calls, command execution)
- Limited ability to test error conditions and edge cases
- No clear separation between business logic and I/O
Current State Analysis
Hard-to-test patterns:
- Commands directly instantiate external clients (Octocrab, ObjectStore, etc.)
- Business logic intertwined with I/O operations
- No dependency injection or trait-based abstractions
- Tests require real git repositories and cargo workspaces
- Parallel execution logic hard to test without real semaphores
Proposed Refactoring Strategy
Phase 1: Extract Core Business Logic
1.1 Create domain models
// src/domain/mod.rs
pub mod package; // Pure Package representations
pub mod dependency; // Dependency graph logic
pub mod change_set; // Changed packages computation
pub mod publish_plan; // What to publish, where, how
1.2 Define service traits
// src/services/traits.rs
pub trait GitService {
fn diff_files(&self, base: &str, head: &str) -> Result<Vec<PathBuf>>;
fn resolve_ref(&self, ref_name: &str) -> Result<String>;
}
pub trait GithubService {
async fn find_release(&self, tag: &str) -> Result<Option<Release>>;
async fn upload_asset(&self, release_id: u64, name: &str, data: Vec<u8>) -> Result<()>;
}
pub trait CargoRegistry {
async fn package_exists(&self, name: &str, version: &str) -> Result<bool>;
async fn publish(&self, package_path: &Path, registry: &str) -> Result<()>;
}
1.3 Implement production and test implementations
Phase 2: Refactor Commands to Use Services
Extract testable functions from monolithic commands. Split into:
- Pure planning functions (no I/O)
- Execution functions using service traits (testable with mocks)
Phase 3: Improve CrateGraph Testability
Make CrateGraph independent of git2 by extracting git operations to a trait.
Implementation Plan
Week 1-2: Foundation
- Create
src/domain/with core business models - Define service traits in
src/services/traits.rs - Create
src/testing/with test utilities and mocks - Add builder patterns for test fixtures
Week 3-4: Refactor CrateGraph
- Extract git operations to
GitServicetrait - Make
CrateGraph::affected_packagesuse trait instead ofgit2::Repository - Write comprehensive tests for dependency graph logic
- Add property-based tests for change detection
Week 5-6: Refactor Publish Command
- Extract publish planning logic (pure functions)
- Implement service interfaces for GitHub, Cargo registry
- Refactor
publish/mod.rsto use services - Write unit tests for publish planning
- Write integration tests with mocked services
Week 7-8: Refactor Tests Command
- Extract test execution planning
- Abstract database and container management
- Implement testable parallel execution
- Add tests for test filtering and selection
Week 9-10: Remaining Commands
- Apply pattern to
check_workspace,fix_lock_files, etc. - Update all commands to use
CommandContext - Ensure 80%+ test coverage for business logic
Success Metrics
- 80%+ unit test coverage for business logic (not including I/O)
- All commands have integration tests with mocked external services
- Test execution time < 30s
- Can test error conditions without real external services
- New features can be developed with TDD
Breaking Changes
- Internal refactoring only; CLI interface remains the same
- May need to update some internal imports if used by external consumers
Labels
refactoring, testing, priority:high
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read the proposed structure in src/domain/, src/services/traits.rs, and src/testing/, then inspect CrateGraph and publish/mod.rs to understand the current command and I/O boundaries. The plan spans service traits, mocks, command refactors, and broad test coverage; done means the listed phases and success metrics are completed without changing the CLI interface.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli, testing-qa, tooling
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 20/100