Skip to content

refactor: move test fixtures out of plugin's build.rs; format generated code (#22) - #28

Merged
erikist merged 2 commits into
mainfrom
factory/22-refactor-move-test-fixtures-out-of
Oct 10, 2026
Merged

erikist merged 2 commits into
mainfrom
factory/22-refactor-move-test-fixtures-out-of

Conversation

@erikist

@erikist erikist commented Oct 10, 2026

Copy link
Copy Markdown
Contributor

Closes #22

Summary

  • Moved protoc-gen-rust-mcp/tests/testdata/{schemapb,mcpgen} and the
    proto-compiling build.rs that fed them into a new, non-published
    workspace crate, test-fixtures/ (publish = false). It depends on
    protoc-gen-rust-mcp as a normal (build-)dependency to run the real
    server::generate_service against the mcpgen fixture — something the
    old build.rs could not do (a build script can't depend on the crate
    it's building), so it used to #[path]-include the plugin's own
    modules instead. protoc-gen-rust-mcp now has no build.rs at all,
    and depends on test-fixtures only as a dev-dependency.
    protoc-gen-rust-mcp/src/schema.rs's tests and
    protoc-gen-rust-mcp/tests/server_integration.rs now use test_fixtures::{schemapb, mcpgen} instead of their own
    include!(concat!(env!("OUT_DIR"), ...)).
  • protox, prost-build, pbjson-build and tonic-prost-build moved
    from protoc-gen-rust-mcp's [build-dependencies] to
    test-fixtures's. A plain cargo build/cargo install -p protoc-gen-rust-mcp no longer compiles them or the two test fixtures.
    Also dropped the now-dead tonic-prost/futures dev-dependencies from
    protoc-gen-rust-mcp (only needed when its tests directly include!d
    the fixture's tonic-generated code; that code now lives in and is only
    used from test-fixtures).
  • generator.rs now runs each generated module through prettyplease
    (format_rust) before prepending the file header — the same approach
    prost-build/tonic-build use for their own generated code (I checked
    prost_build::Config::format's syn::parse_file(buf).unwrap(); prettyplease::unparse(&file) and tonic_build::manual's
    prettyplease::unparse calls in the vendored registry sources to
    confirm the pattern and the header-after-formatting ordering, since
    syn drops a file's leading plain // comments). prettyplease's
    line-wrapping doesn't always agree with rustfmt's on every construct
    (chained calls, where-clause bounds), so make generate's Makefile
    target pipes the final *.mcp.rs output through a real rustfmt --edition 2024 pass to guarantee the issue's rustfmt --check
    criterion. golden.rs does the same to the generator's raw output
    before the byte-for-byte comparison, so it keeps enforcing that the
    committed file matches what make generate produces.
  • One plain // Skipping <method>: ... comment in server.rs became a
    doc comment (///): prettyplease only preserves doc comments or
    comments attached to a node it round-trips, so a plain comment at that
    position would have silently disappeared.
  • Regenerated examples/src/gen/examples/v1/examples.v1.mcp.rs and the
    golden file; the diff is formatting-only (no semantic change — same
    cargo test coverage, including the pbjson-parity test, passes
    unchanged).

Decisions made

  • Where to run prettyplease: inside the library (generator.rs),
    not the protoc-gen-rust-mcp binary's main.rs, so both the real
    generation path and test-fixtures/build.rs's mcpgen-fixture path
    (which calls server::generate_service directly) get the same
    formatting, and so a future API consumer calling generator::generate
    directly gets formatted output too.
  • rustfmt as a final pass, not instead of prettyplease: keeping
    prettyplease matches the Go reference ecosystem's established
    pattern (prost-build/tonic-build) for a library-embeddable formatter
    with no process-spawn dependency, while the extra rustfmt pass in
    make generate (and in golden.rs, to keep the golden-file test
    meaningful) closes the small formatting gap against rustfmt --check
    that prettyplease alone leaves (mostly chained-call and
    where-clause wrapping). rustfmt is already a required toolchain
    component (rust-toolchain.toml) and is run by cargo fmt --all --check, so this adds no new toolchain requirement.
  • Checked versions: prettyplease 0.3.0 (current on crates.io,
    cargo info prettyplease) with syn 3 (features = ["parsing"],
    default-features = false — no need for full, confirmed by
    compiling the real generated module through it). rustc/cargo
    1.99.0 and rustfmt 1.10.0-stable, matching rust-toolchain.toml.

Test evidence

cargo fmt --all --check                                     # clean
cargo clippy --workspace --all-targets -- -D warnings        # clean
cargo build --workspace                                      # ok
cargo test --workspace                                       # all 75 tests pass (8+1+51+1+1+12+1 across crates/binaries, 0 failed)
make generate && git diff --exit-code -- examples/src/gen    # no diff after regenerating (committed file is current)
rustfmt --edition 2024 --check examples/src/gen/examples/v1/examples.v1.mcp.rs   # passes
cargo tree -p protoc-gen-rust-mcp -e build,normal             # no protox, pbjson-build, or tonic-prost-build
cargo build --release -p protoc-gen-rust-mcp                  # no protox/prost-build/pbjson-build/tonic-prost-build compiled

Self-review via the reviewer subagent found no blocking issues; its one
"should fix" item (dead tonic-prost/futures dev-dependencies) is
addressed in the second commit.

Notes for reviewers

  • test-fixtures/testdata/{schemapb,mcpgen} are untouched, byte-identical
    moves of the old protoc-gen-rust-mcp/tests/testdata/* (see the
    rename-detected diff).

  • examples/src/gen/examples/v1/examples.v1.mcp.rs's diff is
    formatting-only (re-wrapped lines, one comment style change); no field
    names, schema text, or logic changed. The pbjson-parity test
    (schema::tests::parity_with_go_example_input_schemas) still passes,
    confirming the embedded schema JSON text itself is byte-identical.

  • Didn't touch .github/workflows/**, AGENTS.md, or docs/GOAL.md.

  • Out of scope / follow-ups: none identified beyond the issue.

  • Factory-authored

sf-factory-bot added 2 commits October 10, 2026 02:45
…ed code (#22)

- Move tests/testdata/{schemapb,mcpgen} and their proto-compiling
  build.rs into a new non-published test-fixtures/ workspace crate that
  depends on protoc-gen-rust-mcp as a normal (build-)dependency.
  protoc-gen-rust-mcp now has no build.rs at all, and no longer pulls in
  protox, prost-build, pbjson-build or tonic-prost-build on a plain
  cargo build/install.
- Run generator.rs's output through prettyplease (as prost-build and
  tonic-build do for their own generated code) before prepending the
  file header, and have `make generate` pipe the final *.mcp.rs output
  through rustfmt, so the committed generated code is rustfmt-clean.
- Regenerate examples/src/gen and the golden file; golden.rs now
  rustfmt's the generator's raw output before comparing, matching what
  make generate produces.
#22)

Both were only needed by tests/server_integration.rs when it directly
include!d the mcpgen fixture's tonic-generated code; now that code lives
in and is only used from test-fixtures, protoc-gen-rust-mcp's own tests
no longer reference either crate directly.
@erikist

erikist commented Oct 10, 2026

Copy link
Copy Markdown
Contributor Author

🔍 Review: LGTM. Verified locally: cargo tree -p protoc-gen-rust-mcp -e build,normal has no protox, pbjson-build or tonic-prost-build; protoc-gen-rust-mcp/build.rs is gone; and rustfmt --check --edition 2024 passes on the regenerated examples.v1.mcp.rs. Using prettyplease in the plugin, plus a rustfmt pass in make generate and the golden test, is a reasonable split, since direct protoc users still get formatted output.

@erikist
erikist merged commit 25145ea into main Oct 10, 2026
6 checks passed
@erikist
erikist deleted the factory/22-refactor-move-test-fixtures-out-of branch October 10, 2026 03:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor: move test fixtures out of the plugin's build.rs; format generated code

1 participant