Skip to content

Split src/render/markdown.rs into a render/markdown/ module #30

@Metbcy

Description

@Metbcy

Context

src/render/markdown.rs is 58 KB — the largest file in the crate. It renders the PR comment that's the primary UX of bomdrift, and it has accumulated a section per finding kind plus several format/escape helpers. The v0.9.8 code review flagged this as the next-highest-ROI file split (after lib.rs, which v0.9.8 already handled).

Scope

Behavior-preserving refactor. Move the file to:

src/render/markdown/
├── mod.rs        # public render() entrypoint + section ordering
├── summary.rs    # the top-of-comment summary table
├── vulns.rs      # CVE / EPSS / KEV finding rows
├── typosquat.rs  # typosquat finding rows
├── version_jump.rs
├── maintainer_age.rs
├── license.rs    # license violations + license-changed-without-version
├── plugin.rs     # plugin findings (v0.9.6+)
├── vex.rs        # VEX badges (consume) + emit pointers (v0.9+)
├── suppress.rs   # baseline suppression + comment-driven suppress hints
└── footer.rs     # platform-aware footer (GitHub / GitLab / Bitbucket / Azure DevOps)

(Adjust the exact split if a different cut feels more natural — the goal is a more navigable structure, not pedantically following this list.)

Acceptance criteria

  • Behavior-preserving: cargo test --release --all-features passes without modification beyond import-path updates. (You can verify with git diff main..HEAD -- tests/ showing only use line changes.)
  • Public surface unchanged: bomdrift::render::markdown::render(...) still works, called the same way from src/run.rs.
  • clippy --all-targets --all-features -- -D warnings clean.
  • cargo fmt --all -- --check clean.
  • Output is byte-identical for the same input — the existing render-twice-byte-equal regression tests should still pass.
  • No file in src/render/markdown/ exceeds ~25 KB.

Tips

  • The render-twice-byte-equal test in src/render/markdown.rs (or wherever it lives now) is the canary. Run it after each module move to catch any subtle ordering or formatting drift.
  • Enrichment is the input across most submodules; pass it & rather than per-finding-kind to keep call sites consistent.
  • The Platform enum routes footer rendering — keep that in footer.rs.

A note on commit signing

main requires verified signatures (the repo ships cosign-signed releases — we hold our own commits to the same bar).

You usually don't need to set up signing as a contributor — when a maintainer merges via "Merge" or "Squash", GitHub auto-signs the resulting commit and your unsigned PR-branch commits are fine. The friendlier path for everyone.

If you'd like your individual commits to land verbatim on main (so your name shows up in git blame), set up local signing once and your PR can be rebase-merged:

git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true

Then add the same SSH public key under GitHub → Settings → SSH and GPG keys → Signing keys.

See CONTRIBUTING.md → Commit signing on main for the full picture. Either way, please don't sweat it — if your PR is otherwise great, the maintainer will pick a merge mode that works.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthelp wantedExtra attention is needed

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions