Purpose: Actionable, ordered task list to implement the Rust parity version (no generic templating; fixed layout). Mirrors JS behavior while adapting to both Cargo and npm packaging via NAPI-RS.
Reference Specs: parity spec (sections indicated as §), JS source inventory.
- Unstarted
- [~] In progress
- Done
- ⚠ Needs decision
- ⏩ Can be parallelized
- 🧪 Testing-focused
- 🔁 Iterative / revisit after benchmarks
- Create repository scaffolding
- Files: Cargo.toml, .gitignore, LICENSE (MIT), README stub, tasks.md (this), parity spec file.
- Configure MSRV (1.89.0) via CI + rust-toolchain.toml.
- Add base dependencies (no unused): git2, semver, clap, anyhow, thiserror, serde, serde_json, toml_edit, tracing, tracing-subscriber, rayon, jiff, reqwest (http requests), demand (prompting, kind of like huh? in go), dashmap (use if need hashmaps), git-conventional. For npm packaging: napi and napi-derive.
- Dev deps: insta, assert_fs, tempfile, proptest, divan, cargo-deny, nextest.
- Set up CI workflow skeleton (Linux only first, then all OS).
- Implement defaults map exactly matching JS config.ts (types + emojis + semver).
- Support config file
novalyn.toml. - Support fallback
[package.metadata.novalyn]in Cargo.toml. - Implement environment token resolution precedence (NOVALYN_TOKENS_GITHUB > GITHUB_TOKEN > GH_TOKEN).
- Implement overlay merge order: defaults < file(s) < CLI overrides.
- Support disabling a type via boolean false (TOML loader logic).
- Validate
newVersion(semver parse). - Warn on unknown keys (collect & log).
- Expose
ResolvedConfigwith normalized paths, resolved repo data (placeholder until repo module ready).
🧪 Tests:
- Default config equality snapshot.
- Override precedence (CLI wins).
- Boolean disabling of type.
- Token env override test.
- Implement remote URL parsing (GitHub/GitLab/Bitbucket patterns).
- Infer provider + domain from origin; fallback to config override.
- Implement reference URL mapping spec (commit/issue/pull).
- Implement compare link function (provider differences).
- Add formatting helpers:
format_reference,format_compare_link(implemented + tests; integrate during rendering phase).
🧪 Tests:
- Parse SSH style URL.
- Parse HTTPS URL with .git suffix.
- Compare link generation per provider.
- Implement repo detection + error if not a git repo.
- Implement last tag discovery (semver tags; accept both vX.Y.Z and X.Y.Z; prefer latest by commit date).
- Implement current ref (tag or branch HEAD).
- Commit enumeration between (from, to].
- Provide RawCommit struct (id, short_id, summary, body, author, timestamp).
- Dirty working tree detection.
- Utility: add & commit, create annotated/signed tag (shell fallback for signed).
🧪 Tests:
- No tags scenario.
- Single tag detection.
- Dirty tree detection.
- Implement conventional header parsing: type, optional scope, optional !, description (case-insensitive type).
- Manual fallback if git-conventional crate unavailable.
- Implement breaking footer detection (BREAKING CHANGE: / BREAKING-CHANGE:).
- Implement issue / PR reference scanning (#\d+).
- Implement Co-authored-by detection accumulating authors.
- Scope mapping via config.scopeMap.
- Normalize type to lowercase (§ commands/default.ts behavior).
- Filter commits: remove disabled types; filter
chore(deps)unless breaking (mirror JS logic).
🧪 Tests:
- Header with scope + bang.
- Footer-only breaking.
- Multiple issue references.
- Co-authored-by accumulation.
- chore(deps) filtered when not breaking.
- Determine major/minor/patch flags using type semver + breaking flag.
- Pre-1.0 adjustment: major→minor, minor→patch.
- [~] Default to "patch" if zero bump-worthy changes (JS parity) – adjusted to no version bump when zero commits (idempotent rerun); revisit for parity decision.
- Apply explicit newVersion override if provided after inference.
- [⚠] Implement suffix logic (optional; deferred to backlog).
- Implement Cargo.toml version bump via toml_edit (preserve formatting).
🧪 Tests:
- Major inference via breaking.
- Minor inference via feat only.
- Patch inference via fix only.
- 0.x adjustments.
- Explicit newVersion override.
- Idempotent (same version returns false result). (Covered via override/empty commit test producing patch bump.)
- Implement simple token replacement for commitMessage/tagMessage/tagBody.
- Support tokens: {{newVersion}}, {{previousVersion}}, {{date}}.
- Unknown tokens remain as-is.
- Date format: YYYY-MM-DD (UTC).
🧪 Tests:
- All tokens replaced.
- Unknown token retention.
- Date stable formatting. (explicit test interpolation_date_format)
- Aggregate primary + co-authors.
- Deduplicate (name+email).
- Exclude authors (exact match list).
- hideAuthorEmail support.
- noAuthors flag suppression.
- Preserve first-seen order.
🧪 Tests:
- Exclusion logic.
- hideAuthorEmail formatting.
- Dedup.
- Section ordering = order of active types in config.
- Include only non-empty sections.
- Commit line formatting with or without scope.
- Append references (linked if provider resolved).
- Add compare link (if previous tag exists).
- Contributors section conditionally.
- Consistent trailing newline.
- Deterministic ordering: chronological ensured; tie-break test added.
- Provide function
render_release_block.
🧪 Tests:
- Snapshot standard release block.
- Empty sections trimmed (implicit via non-empty sections logic; add explicit snapshot later).
- Compare link presence (covered indirectly in render logic; add explicit test later).
- Contributors ordering (implicit insertion order; dedicated test pending).
- Read existing file if present; else bootstrap "# Changelog".
- Locate first release header; prepend new block above it.
- Idempotence check: if same version already at top and identical body, skip write.
- Provide
write_or_update_changelog(diff summary pending -> backlog note).
🧪 Tests:
- Prepend first release.
- Subsequent release insertion.
- Idempotent rerun no duplication.
- Orchestrate steps: config load → git range → parse → classify → bump → render → write → tag (GitHub sync pending).
- Dry run support (skip writes/tag).
- Exit code mapping (0 success, 3 no-change).
- Summary output (basic version + commit count; tag implicit; enhancement backlog).
- Respect clean flag (implemented).
🧪 Tests:
- Dry run leaves files unchanged.
- Exit code 3 scenario (no-change path) with idempotent version.
- Signed tag attempt (simulate annotated path success).
- Implement GET release by tag; create or update. (basic happy path)
- Fallback manual URL when token absent or error.
- [~] Redact token in logs. (token never logged; explicit redaction still to add if future logging)
- Provide status struct to caller.
- Optionally
--githubsubcommand to resync existing tag with current body.
🧪 Tests (network mock or feature-gated):
- Manual fallback without token.
- Update path after create.
- Implement
show(print inferred next version). - Implement
generate(print block; optional --write). - Implement
release(full pipeline minus GitHub sync). - Implement
github(sync only) if maintained. - Global flags: implemented --from, --to, --new-version, --sign (placeholder), --no-authors, --exclude-author, --cwd, --dry-run, --clean, --output, -v/--verbose, --yes (with confirmation prompts).
- Verbosity flags or RUST_LOG integration (tracing subscriber added).
- Helpful
--helpdocs per subcommand (clap derived; test added).
🧪 Tests:
- CLI argument parsing snapshot (help snapshot).
- Unknown subcommand error.
80.1. [ ] Add napi and napi-derive dependencies conditionally via feature flag. 80.2. [ ] Create NAPI bindings module exposing core functionality. 80.3. [ ] Implement JavaScript-compatible API surface (async where needed). 80.4. [ ] Add package.json with proper npm metadata and binary configuration. 80.5. [ ] Set up NAPI-RS build pipeline for cross-platform binaries. 80.6. [ ] Create TypeScript definitions for the npm package. 80.7. [ ] Add npm-specific documentation and examples.
🧪 Tests:
- NAPI bindings compile and expose expected API.
- npm package installation and basic usage.
- Cross-platform binary compatibility.
- Implement threshold env override & CLI override (optional).
- Use rayon for parse/classify only when commit_count >= threshold.
- Maintain original index for stable ordering.
- Provide debug logs indicating mode.
🧪 Tests:
- Output identical sequential vs parallel (snapshot diff).
- Force parallel with small set (env var) still identical.
- Integrate tracing subscriber (env filter).
- Add spans: collect_commits, parse_classify, infer_version, render, write, tag (github_sync to add on invocation path).
- Debug-level per-commit classification log.
- Provide minimal JSON log format stub (optional backlog).
🧪 Tests:
- Smoke log initialization (no panic).
- Verbose toggle effect.
- Define Error enum (Config, Git, Network, IO, Semantic).
- Map to exit codes.
- Wrap CLI main with error -> stderr formatted line.
- Avoid panics outside unrecoverable invariants.
🧪 Tests:
- Config parse failure case.
- No git repo detection.
- Normalize unicode (NFC) for consistent grouping.
- Provide optional aliasing (fully implemented with GitHub integration for email->handle mapping, enabled by default).
- Benchmark synthetic commit generation utility.
- Implement parse_seq_vs_parallel benchmark (using divan).
- Implement render_block benchmark (vary commit counts).
- Implement version_inference benchmark.
- Document baseline results.
- Evaluate dashmap effect; remove if <5% improvement (then: update Cargo.toml).
- README: parity statement, quick start, differences vs JS (available via both Cargo and npm).
- CONTRIBUTING: dev setup, MSRV, tests, benchmarks, release instructions.
- PERF docs: initial benchmark table.
- PARITY_SPEC inclusion & cross-link tasks.md.
- Changelog bootstrapped by tool itself for first release.
- Clippy: deny(warnings).
- cargo-deny: license & advisories clean (config added; check pending install).
- No unwrap() outside tests (or justify).
- Determinism test repeated run identical output.
- Validate no leftover TODO markers for MVP (or track in backlog list).
- Document and enforce dev workflow (fmt, clippy, nextest) (see Section 25).
- Add matrix (linux, macOS, windows).
- Add MSRV job.
- Add cache (actions-rs or dtolnay/rust-toolchain + Swatinem/rust-cache).
- Add test coverage (cargo-tarpaulin).
- Optional scheduled dependency audit.
- Ensure tool self-generates initial CHANGELOG.md via
release --dry-run. - Tag v0.1.0 (manual first).
- Publish crate (cargo publish) – optional if scope private initially.
- Publish npm package (npm publish) via NAPI-RS build.
- Verify install instructions (cargo install and npm install).
- Announce parity & solicit feedback before adding new features.
- Workspace multi-crate support.
- JSON export mode.
- Pre-release channels.
- Template customization extension (if user demand).
- Git hosting expansions beyond basic provider inference logic.
- Hook/plugin architecture.
- After benchmarks: remove dashmap if not beneficial.
- Evaluate need for reqwest until GitHub sync matured.
- Confirm no accidental heavy transitive crates (document compile times).
- Matches JS output for a sampled repository (diff = empty).
- Parallel vs sequential identical.
- Signed tag path error messaging clear (if GPG absent).
- New version bump logic conforms to 0.x rules & explicit override.
- Idempotent rerun no duplication.
- Contributors section correctness (exclusions, email hiding).
- Compare link correct for GitHub & GitLab test remotes.
- All tests green on all CI platforms.
- No extraneous dependencies (review completed).
A. Config + Repo + Interpolation (Tasks 6–19, 41–44)
B. Git + Parsing + Classification (20–34)
C. Semver + Cargo Bump (35–40)
D. Rendering + Changelog (51–63)
E. Release Pipeline + CLI (64–80)
F. GitHub Sync (69–73)
G. Parallelization + Benchmarks (81–84, 95–100)
H. Docs + QA + CI (101–115, 106–110, 111–115)
Milestone 1 (Core Parse): Tasks 6–34 complete, basic CLI show/generate prints block.
Milestone 2 (Versioning): Tasks 35–44 integrated; show command reports version.
Milestone 3 (Changelog): Tasks 51–63; generate updates file.
Milestone 4 (Release Pipeline): Tasks 64–80; release end-to-end (no GitHub).
Milestone 5 (GitHub Sync + Authors Polish): Tasks 45–50, 69–73.
Milestone 6 (Performance & Parallel): Tasks 81–84, 95–100 done, dashmap decision.
Milestone 7 (Docs & CI & QA): Tasks 101–115, 106–110, 111–115.
Milestone 8 (Release v0.1.0): Tasks 116–120 + final checklist.
- Divergent Output: Keep golden snapshot from JS tool early; diff after each milestone.
- Ordering Drift: Preserve original commit index; assert in test.
- Semver Edge Drift: Build matrix comparing JS vs Rust inference using exported commit JSON fixtures.
- Performance Regression: Store baseline benchmark results in PERF doc; compare in CI (optional threshold assertion).
- Scope Creep: Any new feature must enter backlog; not merged into MVP branches.
Add new potential features to a BACKLOG.md with: ID, description, rationale, requested-by, complexity estimate.
Guidelines (non-functional tasks, but enforceable via CI/hooks):
A. Pre-commit local checklist
- cargo fmt --all (format code)
- cargo clippy --all-targets --all-features -- -D warnings
- cargo nextest run
- cargo test --doc (doc tests separately if any)
- cargo deny check (optional fast path)
B. Optional git hook (.git/hooks/pre-commit example) – add later to repo docs:
#!/usr/bin/env bash
set -euo pipefail
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo nextest run
C. CI Enhancements (tie to tasks 106–111, 111–115):
- Add clippy & fmt check steps before tests.
- Cache target to speed nextest.
- Future: coverage (llvm-cov) gate.
D. Fast feedback loop:
- Use cargo watch -x 'clippy -- -D warnings' -x 'nextest run' for iterative dev.
E. Panics policy:
- Outside tests: avoid unwrap/expect; map errors. (Tied to task 108).
F. Pending automation tasks:
- Add justfile with common recipes (just test, just lint).
- Add CONTRIBUTING.md referencing this section.
(End of tasks.md)