Skip to content

Add rust_workspace_doc for merged workspace documentation (#1837) - #4211

Open
havasd wants to merge 1 commit into
bazelbuild:mainfrom
havasd:rust-workspace-doc
Open

Add rust_workspace_doc for merged workspace documentation (#1837)#4211
havasd wants to merge 1 commit into
bazelbuild:mainfrom
havasd:rust-workspace-doc

Conversation

@havasd

@havasd havasd commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Adds a rust_workspace_doc rule that documents every workspace crate transitively reachable from its deps and merges the results into a single documentation tree with a unified search index, like cargo doc in a Cargo workspace.

The implementation uses the rustdoc cross-crate merge flags from RFC 3662 (--merge, --parts-out-dir, --include-parts-dir), which are nightly-only until rust-lang/rust#130676 stabilizes:

  • A rust_workspace_doc_aspect walks the dependency graph and runs one independently cached rustdoc --merge=none action per crate, producing an HTML directory and a cross-crate-info parts directory.
  • A finalize action documents a stub crate with --merge=finalize to produce the merged search index and (by default) a root index page listing all crates (--enable-index-page).
  • A new doc_merger helper assembles the final tree, exported both as a directory and as a <name>.zip suitable for archiving.

A tools/rustdoc_workspace:gen_workspace_docs binary offers a rule-free alternative in the style of gen_rust_project: it applies the aspect to target patterns, discovers the per-crate outputs from the build event stream (including under remote execution, where output paths are reconstructed from BEP pathPrefix entries and downloads are forced with --remote_download_regex), runs the finalize step and assembles the tree into a chosen output directory.

Also:

  • Binary crates are documented like cargo doc --bins: their outputs use a distinct _bin directory suffix and a binary whose crate name collides with another documented crate yields to it. Colliding library crates remain an analysis error.
  • process_wrapper gains a repeated --mkdir flag, used to pre-create dependency directories in each crate's out-dir so rustdoc emits relative cross-crate links into the merged tree.
  • rustdoc_compile_action accepts attr/file/files overrides so aspects can reuse it, and tolerates synthetic crates without output.
  • External crates are skipped by default; the new //rust/settings:rustdoc_workspace_include_external flag opts in.
  • The repeatable //rust/settings:rustdoc_workspace_extra_flag setting adds flags (e.g. -Dwarnings, --document-private-items) to every per-crate rustdoc invocation.
  • On non-nightly toolchains the rule fails with a descriptive error and the aspect produces no outputs, so example targets can be gated with target_compatible_with on the toolchain channel.

…#1837)

Adds a `rust_workspace_doc` rule that documents every workspace crate
transitively reachable from its `deps` and merges the results into a
single documentation tree with a unified search index, like `cargo doc`
in a Cargo workspace.

The implementation uses the rustdoc cross-crate merge flags from
RFC 3662 (`--merge`, `--parts-out-dir`, `--include-parts-dir`), which
are nightly-only until rust-lang/rust#130676 stabilizes:

- A `rust_workspace_doc_aspect` walks the dependency graph and runs one
  independently cached `rustdoc --merge=none` action per crate,
  producing an HTML directory and a cross-crate-info parts directory.
- A finalize action documents a stub crate with `--merge=finalize` to
  produce the merged search index and (by default) a root index page
  listing all crates (`--enable-index-page`).
- A new `doc_merger` helper assembles the final tree, exported both as
  a directory and as a `<name>.zip` suitable for archiving.

A `tools/rustdoc_workspace:gen_workspace_docs` binary offers a
rule-free alternative in the style of `gen_rust_project`: it applies
the aspect to target patterns, discovers the per-crate outputs from the
build event stream (including under remote execution, where output
paths are reconstructed from BEP `pathPrefix` entries and downloads are
forced with `--remote_download_regex`), runs the finalize step and
assembles the tree into a chosen output directory.

Also:
- Binary crates are documented like `cargo doc --bins`: their outputs
  use a distinct `_bin` directory suffix and a binary whose crate name
  collides with another documented crate yields to it. Colliding
  library crates remain an analysis error.
- `process_wrapper` gains a repeated `--mkdir` flag, used to pre-create
  dependency directories in each crate's out-dir so rustdoc emits
  relative cross-crate links into the merged tree.
- `rustdoc_compile_action` accepts `attr`/`file`/`files` overrides so
  aspects can reuse it, and tolerates synthetic crates without output.
- External crates are skipped by default; the new
  `//rust/settings:rustdoc_workspace_include_external` flag opts in.
- The repeatable `//rust/settings:rustdoc_workspace_extra_flag` setting
  adds flags (e.g. `-Dwarnings`, `--document-private-items`) to every
  per-crate rustdoc invocation.
- On non-nightly toolchains the rule fails with a descriptive error and
  the aspect produces no outputs, so example targets can be gated with
  `target_compatible_with` on the toolchain channel.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant