Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions src/bin/cargo/commands/doc.rs
Copy link
Copy Markdown
Member

@weihanglo weihanglo May 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems good to me.

Namely, it becomes possible to compute the JSON docs for the whole workspace at once and then retrieve the artefacts directly from the build directory.

I don't understand this. build directory layout is private, and I don't know there is really a way to retrieve artifacts from there. That said, this doesn't block this from merging. Thanks for the PR!

View changes since the review

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::command_prelude::*;

use cargo::ops::{self, DocOptions};
use cargo::ops::{self, DocOptions, OutputFormat};

pub fn cli() -> Command {
subcommand("doc")
Expand All @@ -16,6 +16,11 @@ pub fn cli() -> Command {
"Don't build documentation for dependencies",
))
.arg(flag("document-private-items", "Document private items"))
.arg(
opt("output-format", "The output type to write (unstable)")
.value_name("FMT")
.value_parser(OutputFormat::POSSIBLE_VALUES),
)
.arg_message_format()
.arg_silent_suggestion()
.arg_package_spec(
Expand Down Expand Up @@ -47,17 +52,24 @@ pub fn cli() -> Command {

pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult {
let ws = args.workspace(gctx)?;
let output_format = if let Some(output_format) = args._value_of("output-format") {
gctx.cli_unstable()
.fail_if_stable_opt("--output-format", 13283)?;
output_format.parse()?
} else {
OutputFormat::Html
};
let intent = UserIntent::Doc {
deps: !args.flag("no-deps"),
json: false,
json: matches!(output_format, OutputFormat::Json),
};
let mut compile_opts =
args.compile_options(gctx, intent, Some(&ws), ProfileChecking::Custom)?;
compile_opts.rustdoc_document_private_items = args.flag("document-private-items");

let doc_opts = DocOptions {
open_result: args.flag("open"),
output_format: ops::OutputFormat::Html,
output_format,
compile_opts,
};
ops::doc(&ws, &doc_opts)?;
Expand Down
39 changes: 39 additions & 0 deletions tests/testsuite/build_dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,45 @@ fn cargo_rustdoc_json_should_output_to_target_dir() {
]);
}

#[cargo_test(nightly, reason = "--output-format is unstable")]
fn cargo_doc_json_should_output_to_target_dir() {
let p = project()
.file("src/lib.rs", "")
.file(
".cargo/config.toml",
r#"
[build]
target-dir = "target-dir"
build-dir = "build-dir"
"#,
)
.build();

p.cargo("-Zbuild-dir-new-layout -Zunstable-options doc --no-deps --output-format json")
.masquerade_as_nightly_cargo(&["new build-dir layout", "rustdoc-output-format"])
.enable_mac_dsym()
.run();

let docs_dir = p.root().join("target-dir/doc");

assert_exists(&docs_dir);
assert_exists(&docs_dir.join("foo.json"));

p.root().join("build-dir").assert_build_dir_layout(str![
r#"
[ROOT]/foo/build-dir/.rustc_info.json
[ROOT]/foo/build-dir/.rustdoc_fingerprint.json
[ROOT]/foo/build-dir/CACHEDIR.TAG
[ROOT]/foo/build-dir/debug/.cargo-build-lock
[ROOT]/foo/build-dir/debug/build/foo/[HASH]/fingerprint/doc-lib-foo
[ROOT]/foo/build-dir/debug/build/foo/[HASH]/fingerprint/doc-lib-foo.json
[ROOT]/foo/build-dir/debug/build/foo/[HASH]/fingerprint/invoked.timestamp
[ROOT]/foo/build-dir/debug/build/foo/[HASH]/out/foo.json

"#
]);
}

#[cargo_test]
fn cargo_package_should_build_in_build_dir_and_output_to_target_dir() {
let p = project()
Expand Down
39 changes: 39 additions & 0 deletions tests/testsuite/build_dir_legacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,45 @@ fn cargo_rustdoc_json_should_output_to_target_dir() {
]);
}

#[cargo_test(nightly, reason = "--output-format is unstable")]
fn cargo_doc_json_should_output_to_target_dir() {
let p = project()
.file("src/lib.rs", "")
.file(
".cargo/config.toml",
r#"
[build]
target-dir = "target-dir"
build-dir = "build-dir"
"#,
)
.build();

p.cargo("doc --no-deps -Zunstable-options --output-format json")
.masquerade_as_nightly_cargo(&["rustdoc-output-format"])
.enable_mac_dsym()
.run();

let docs_dir = p.root().join("target-dir/doc");

assert_exists(&docs_dir);
assert_exists(&docs_dir.join("foo.json"));

p.root().join("build-dir").assert_build_dir_layout(str![
r#"
[ROOT]/foo/build-dir/.rustc_info.json
[ROOT]/foo/build-dir/.rustdoc_fingerprint.json
[ROOT]/foo/build-dir/CACHEDIR.TAG
[ROOT]/foo/build-dir/debug/.cargo-build-lock
[ROOT]/foo/build-dir/debug/.fingerprint/foo-[HASH]/doc-lib-foo
[ROOT]/foo/build-dir/debug/.fingerprint/foo-[HASH]/doc-lib-foo.json
[ROOT]/foo/build-dir/debug/.fingerprint/foo-[HASH]/invoked.timestamp
[ROOT]/foo/build-dir/debug/build/foo-[HASH]/out/foo.json

"#
]);
}

#[cargo_test]
fn cargo_package_should_build_in_build_dir_and_output_to_target_dir() {
let p = project()
Expand Down
Loading
Loading