|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +Zerv is a dynamic versioning CLI tool written in Rust that generates versions for any commit from git and other version control systems. It supports multiple version formats (SemVer, PEP440, CalVer) and is designed for CI/CD builds. |
| 8 | + |
| 9 | +## Essential Commands |
| 10 | + |
| 11 | +### Development Setup |
| 12 | + |
| 13 | +```bash |
| 14 | +make setup_dev # Install pre-commit hooks and cargo-tarpaulin |
| 15 | +``` |
| 16 | + |
| 17 | +### Testing |
| 18 | + |
| 19 | +```bash |
| 20 | +make test_easy # Quick tests: Docker Git + Docker tests skipped (fast, coverage gaps) |
| 21 | +make test # Full test suite: Docker Git + Docker tests enabled (full coverage) |
| 22 | +make test_flaky # Run 5 iterations to detect flaky tests |
| 23 | +``` |
| 24 | + |
| 25 | +### Building and Running |
| 26 | + |
| 27 | +```bash |
| 28 | +make run # Run the CLI with cargo run |
| 29 | +cargo build # Build debug version |
| 30 | +cargo build --release # Build optimized release version |
| 31 | +``` |
| 32 | + |
| 33 | +### Code Quality |
| 34 | + |
| 35 | +```bash |
| 36 | +make lint # Check code formatting and clippy warnings |
| 37 | +make update # Update Rust toolchain and dependencies |
| 38 | +``` |
| 39 | + |
| 40 | +### Coverage |
| 41 | + |
| 42 | +```bash |
| 43 | +make test # Generates coverage reports |
| 44 | +make open_coverage # Open HTML coverage report |
| 45 | +``` |
| 46 | + |
| 47 | +### Documentation |
| 48 | + |
| 49 | +```bash |
| 50 | +make docs # Generate documentation via cargo xtask |
| 51 | +``` |
| 52 | + |
| 53 | +## High-Level Architecture |
| 54 | + |
| 55 | +### Pipeline Architecture |
| 56 | + |
| 57 | +The core processing follows a clear pipeline pattern: |
| 58 | + |
| 59 | +``` |
| 60 | +Input → VCS Detection → Version Parsing → Transformation → Format Output |
| 61 | +``` |
| 62 | + |
| 63 | +**Key Modules:** |
| 64 | + |
| 65 | +- **`src/vcs/`**: Version Control System abstraction (currently Git only) |
| 66 | + - Detects VCS repositories and extracts metadata |
| 67 | + - `VcsData` struct contains tag versions, distance, commits, branches, timestamps |
| 68 | + |
| 69 | +- **`src/version/`**: Version format implementations |
| 70 | + - `VersionObject`: Universal internal representation |
| 71 | + - `PEP440`: Python versioning standard |
| 72 | + - `SemVer`: Semantic versioning |
| 73 | + - `Zerv`: Custom component-based format with variable references |
| 74 | + |
| 75 | +- **`src/pipeline/`**: Data transformation layer |
| 76 | + - `parse_version_from_tag()`: Extracts version from git tags |
| 77 | + - `vcs_data_to_zerv_vars()`: Converts VCS metadata to Zerv variables |
| 78 | + |
| 79 | +- **`src/schema/`**: Schema and preset management |
| 80 | + - Presets for common versioning schemes (standard, calver) |
| 81 | + - RON-based schema parsing for custom formats |
| 82 | + |
| 83 | +- **`src/cli/`**: Command-line interface (in development) |
| 84 | + - Main commands: `version`, `check` |
| 85 | + - Output formatting and display logic |
| 86 | + |
| 87 | +### State-Based Versioning Tiers |
| 88 | + |
| 89 | +Zerv uses a three-tier system based on repository state: |
| 90 | + |
| 91 | +- **Tier 1** (Tagged, clean): `major.minor.patch` |
| 92 | +- **Tier 2** (Distance, clean): `major.minor.patch.post<distance>+branch.<commit>` |
| 93 | +- **Tier 3** (Dirty): `major.minor.patch.dev<timestamp>+branch.<commit>` |
| 94 | + |
| 95 | +### Test Infrastructure |
| 96 | + |
| 97 | +The project has extensive test utilities in `src/test_utils/`: |
| 98 | + |
| 99 | +- **Environment-aware Git testing**: Uses `DockerGit` locally, `NativeGit` in CI |
| 100 | +- **`GitOperations` trait**: Unified interface for both implementations |
| 101 | +- **`GitRepoFixture`**: Creates isolated test repositories with specific states |
| 102 | +- **`TestDir`**: Temporary directory management with automatic cleanup |
| 103 | + |
| 104 | +## Testing Standards |
| 105 | + |
| 106 | +### Environment Variables |
| 107 | + |
| 108 | +- `ZERV_TEST_NATIVE_GIT=true`: Use native Git (set in CI for platform testing) |
| 109 | +- `ZERV_TEST_DOCKER=true`: Enable Docker-dependent tests (requires Docker) |
| 110 | + |
| 111 | +### Git Testing Pattern |
| 112 | + |
| 113 | +ALWAYS use the environment-aware pattern: |
| 114 | + |
| 115 | +```rust |
| 116 | +use crate::test_utils::{GitOperations, get_git_impl}; |
| 117 | + |
| 118 | +let git_impl = get_git_impl(); // Returns DockerGit or NativeGit based on environment |
| 119 | +git_impl.init_repo(&test_dir)?; |
| 120 | +``` |
| 121 | + |
| 122 | +### Docker Test Gating |
| 123 | + |
| 124 | +For Docker-dependent tests: |
| 125 | + |
| 126 | +```rust |
| 127 | +use crate::test_utils::should_run_docker_tests; |
| 128 | + |
| 129 | +#[test] |
| 130 | +fn test_docker_functionality() { |
| 131 | + if !should_run_docker_tests() { |
| 132 | + return; // Skip when Docker tests are disabled |
| 133 | + } |
| 134 | + // Test code here |
| 135 | +} |
| 136 | +``` |
| 137 | + |
| 138 | +### Flaky Test Prevention |
| 139 | + |
| 140 | +- Use `GitOperations` trait methods for atomic operations |
| 141 | +- Create fresh Git implementations for each test directory |
| 142 | +- Include detailed error messages with context |
| 143 | +- Verify intermediate states (e.g., `.git` directory exists) |
| 144 | +- Never reuse Git implementations across different directories |
| 145 | + |
| 146 | +## Coding Standards |
| 147 | + |
| 148 | +### Error Handling |
| 149 | + |
| 150 | +- **ALWAYS** use `zerv::error::ZervError` for custom errors |
| 151 | +- Use `io::Error::other()` instead of `io::Error::new(io::ErrorKind::Other, ...)` |
| 152 | +- Include context in error messages for debugging |
| 153 | +- Proper error propagation with `?` operator |
| 154 | + |
| 155 | +### Constants Usage |
| 156 | + |
| 157 | +**MANDATORY**: Always use constants instead of bare strings: |
| 158 | + |
| 159 | +```rust |
| 160 | +// GOOD |
| 161 | +use crate::utils::constants::{fields, formats, sources, schema_names}; |
| 162 | +match field_name.as_str() { |
| 163 | + fields::MAJOR => // ... |
| 164 | + fields::MINOR => // ... |
| 165 | +} |
| 166 | + |
| 167 | +// BAD - Never use bare strings |
| 168 | +match field_name.as_str() { |
| 169 | + "major" => // ... |
| 170 | +} |
| 171 | +``` |
| 172 | + |
| 173 | +### Code Reuse |
| 174 | + |
| 175 | +Before implementing new test utilities: |
| 176 | + |
| 177 | +- Check `src/test_utils/` for existing infrastructure |
| 178 | +- Reuse `TestDir`, `GitOperations` trait, and other helpers |
| 179 | +- Use `get_git_impl()` for environment-aware Git operations |
| 180 | +- Avoid duplicating code across files |
| 181 | + |
| 182 | +### Performance Standards |
| 183 | + |
| 184 | +- Parse 1000+ versions in <100ms |
| 185 | +- Minimal VCS command calls (batch when possible) |
| 186 | +- Use compiled regex patterns for speed |
| 187 | +- Zero-copy string operations where possible |
| 188 | + |
| 189 | +## CI/CD |
| 190 | + |
| 191 | +### Multi-Platform Testing |
| 192 | + |
| 193 | +- **Linux**: Native Git + Docker tests enabled |
| 194 | +- **macOS**: Native Git + Docker tests skipped |
| 195 | +- **Windows**: Native Git + Docker tests skipped |
| 196 | + |
| 197 | +### Pre-commit Hooks |
| 198 | + |
| 199 | +The project uses pre-commit hooks for: |
| 200 | + |
| 201 | +- Code formatting (rustfmt) |
| 202 | +- Linting (clippy) |
| 203 | +- Running tests |
| 204 | + |
| 205 | +### GitHub Actions |
| 206 | + |
| 207 | +Main workflows: |
| 208 | + |
| 209 | +- `ci-test.yml`: Runs tests across Linux, macOS, Windows |
| 210 | +- `ci-pre-commit.yml`: Validates formatting and linting |
| 211 | +- `cd.yml`: Release automation |
| 212 | +- `security.yml`: Security scanning with SonarCloud |
| 213 | + |
| 214 | +## Important Files |
| 215 | + |
| 216 | +### Development Documentation |
| 217 | + |
| 218 | +Read `.dev/00-README.md` FIRST before any coding task. All `.dev/` documents use sequential numbering (00, 01, 02...) where higher numbers indicate more recent plans. |
| 219 | + |
| 220 | +### Cursor Rules (Apply to Claude Code) |
| 221 | + |
| 222 | +Key rules in `.cursor/rules/`: |
| 223 | + |
| 224 | +- `dev-workflow.mdc`: Development workflow and git practices |
| 225 | +- `testing-standards.mdc`: Comprehensive testing requirements |
| 226 | +- `cli-implementation.mdc`: CLI standards and patterns |
| 227 | +- `docker-git-testing.mdc`: Docker testing architecture |
| 228 | + |
| 229 | +## Running Tests for Specific Features |
| 230 | + |
| 231 | +```bash |
| 232 | +# Run all tests |
| 233 | +cargo test |
| 234 | + |
| 235 | +# Run git-related tests |
| 236 | +cargo test git |
| 237 | + |
| 238 | +# Run specific test file |
| 239 | +cargo test --test integration_test_name |
| 240 | + |
| 241 | +# Run with features |
| 242 | +cargo test --features test-utils |
| 243 | + |
| 244 | +# Run a single test |
| 245 | +cargo test test_name -- --exact |
| 246 | +``` |
| 247 | + |
| 248 | +## Configuration |
| 249 | + |
| 250 | +Centralized config in `src/config.rs`: |
| 251 | + |
| 252 | +- Loads environment variables (`ZERV_TEST_NATIVE_GIT`, `ZERV_TEST_DOCKER`) |
| 253 | +- Validates boolean parsing |
| 254 | +- Single source of truth for environment configuration |
0 commit comments