Skip to content

Commit 027ac4a

Browse files
committed
Add unstable "--output-format" option to "doc" & "rustdoc"
This commits enables the mimicking of "--output-format" option of "rustdoc". We achieved this by: * Handle "--output-format" arguments, accepts "html" or "json". * If "--ouput-format=json" we append the following to compile_opts.target_rustc_args: 1. "-Zunstable-commands" 2. "--output-format
1 parent 928b956 commit 027ac4a

File tree

16 files changed

+138
-6
lines changed

16 files changed

+138
-6
lines changed

src/bin/cargo/commands/doc.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::command_prelude::*;
22

3-
use cargo::ops::{self, DocOptions};
3+
use cargo::ops::{self, DocOptions, OutputFormat};
44

55
pub fn cli() -> Command {
66
subcommand("doc")
@@ -35,6 +35,7 @@ pub fn cli() -> Command {
3535
.arg_features()
3636
.arg_target_triple("Build for the target triple")
3737
.arg_target_dir()
38+
.arg(opt("output-format", "the output type to write (unstable)").value_name("PATH"))
3839
.arg_manifest_path()
3940
.arg_message_format()
4041
.arg_ignore_rust_version()
@@ -48,12 +49,21 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
4849
let mode = CompileMode::Doc {
4950
deps: !args.flag("no-deps"),
5051
};
52+
5153
let mut compile_opts =
5254
args.compile_options(config, mode, Some(&ws), ProfileChecking::Custom)?;
5355
compile_opts.rustdoc_document_private_items = args.flag("document-private-items");
56+
let output_format = args.output_format()?;
57+
if output_format.eq(&OutputFormat::Json) {
58+
compile_opts.target_rustc_args = Some(vec![
59+
"-Zunstable-options".to_string(),
60+
"--output-format=json".to_string(),
61+
]);
62+
}
5463

5564
let doc_opts = DocOptions {
5665
open_result: args.flag("open"),
66+
output_format,
5767
compile_opts,
5868
};
5969
ops::doc(&ws, &doc_opts)?;

src/bin/cargo/commands/rustdoc.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use cargo::ops::{self, DocOptions};
1+
use cargo::ops::{self, DocOptions, OutputFormat};
22

33
use crate::command_prelude::*;
44

@@ -35,6 +35,7 @@ pub fn cli() -> Command {
3535
.arg_features()
3636
.arg_target_triple("Build for the target triple")
3737
.arg_target_dir()
38+
.arg(opt("output-format", "the output type to write (unstable)").value_name("PATH"))
3839
.arg_manifest_path()
3940
.arg_message_format()
4041
.arg_unit_graph()
@@ -51,14 +52,23 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
5152
Some(&ws),
5253
ProfileChecking::Custom,
5354
)?;
54-
let target_args = values(args, "args");
55+
let mut target_args = values(args, "args");
56+
57+
let output_format = args.output_format()?;
58+
if output_format.eq(&OutputFormat::Json) {
59+
target_args.push("-Zunstable-options".to_string());
60+
target_args.push("--output-format=json".to_string());
61+
}
62+
5563
compile_opts.target_rustdoc_args = if target_args.is_empty() {
5664
None
5765
} else {
5866
Some(target_args)
5967
};
68+
6069
let doc_opts = DocOptions {
6170
open_result: args.flag("open"),
71+
output_format,
6272
compile_opts,
6373
};
6474
ops::doc(&ws, &doc_opts)?;

src/cargo/ops/cargo_doc.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,33 @@ use std::path::Path;
66
use std::path::PathBuf;
77
use std::process::Command;
88

9+
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
10+
pub enum OutputFormat {
11+
#[default]
12+
Html,
13+
Json,
14+
}
15+
916
/// Strongly typed options for the `cargo doc` command.
1017
#[derive(Debug)]
1118
pub struct DocOptions {
1219
/// Whether to attempt to open the browser after compiling the docs
1320
pub open_result: bool,
21+
/// Same as `rustdoc --output-format`
22+
pub output_format: OutputFormat,
1423
/// Options to pass through to the compiler
1524
pub compile_opts: ops::CompileOptions,
1625
}
1726

1827
/// Main method for `cargo doc`.
1928
pub fn doc(ws: &Workspace<'_>, options: &DocOptions) -> CargoResult<()> {
29+
if options.open_result && options.output_format.eq(&OutputFormat::Json) {
30+
anyhow::bail!("\"--open\" is not allowed with \"json\" output format.");
31+
}
32+
2033
let compilation = ops::compile(ws, &options.compile_opts)?;
2134

22-
if options.open_result {
35+
if options.open_result && options.output_format.eq(&OutputFormat::Html) {
2336
let name = &compilation
2437
.root_crate_names
2538
.get(0)

src/cargo/ops/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ pub use self::cargo_compile::{
55
compile, compile_with_exec, compile_ws, create_bcx, print, resolve_all_features, CompileOptions,
66
};
77
pub use self::cargo_compile::{CompileFilter, FilterRule, LibRule, Packages};
8-
pub use self::cargo_doc::{doc, DocOptions};
8+
pub use self::cargo_doc::{doc, DocOptions, OutputFormat};
99
pub use self::cargo_fetch::{fetch, FetchOptions};
1010
pub use self::cargo_generate_lockfile::generate_lockfile;
1111
pub use self::cargo_generate_lockfile::update_lockfile;

src/cargo/util/command_prelude.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use crate::core::compiler::{BuildConfig, MessageFormat, TimingOutput};
22
use crate::core::resolver::CliFeatures;
33
use crate::core::{Edition, Workspace};
4-
use crate::ops::{CompileFilter, CompileOptions, NewOptions, Packages, VersionControl};
4+
use crate::ops::{
5+
CompileFilter, CompileOptions, NewOptions, OutputFormat, Packages, VersionControl,
6+
};
57
use crate::util::important_paths::find_root_manifest_for_wd;
68
use crate::util::interning::InternedString;
79
use crate::util::restricted_names::is_glob_pattern;
@@ -366,6 +368,21 @@ pub trait ArgMatchesExt {
366368
Ok(ws)
367369
}
368370

371+
fn output_format(&self) -> CargoResult<OutputFormat> {
372+
let arg: OutputFormat = match self._value_of("output-format") {
373+
None => OutputFormat::default(),
374+
Some(arg) => match arg {
375+
"html" => OutputFormat::Html,
376+
"json" => OutputFormat::Json,
377+
_ => anyhow::bail!(
378+
"Allowed values are for \"--output-format\" are \"html\" or \"json\""
379+
),
380+
},
381+
};
382+
383+
Ok(arg)
384+
}
385+
369386
fn jobs(&self) -> CargoResult<Option<JobsConfig>> {
370387
let arg = match self._value_of("jobs") {
371388
None => None,

src/doc/man/cargo-doc.md

+1
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ and supports common Unix glob patterns.
112112
{{#options}}
113113
{{> options-jobs }}
114114
{{> options-keep-going }}
115+
{{> options-output-format }}
115116
{{/options}}
116117

117118
{{> section-environment }}

src/doc/man/cargo-rustdoc.md

+1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ if its name is the same as the lib target. Binaries are skipped if they have
100100
{{#options}}
101101
{{> options-jobs }}
102102
{{> options-keep-going }}
103+
{{> options-output-format }}
103104
{{/options}}
104105

105106
{{> section-environment }}

src/doc/man/generated_txt/cargo-doc.txt

+3
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,9 @@ OPTIONS
305305
than aborting the build on the first one that fails to build.
306306
Unstable, requires -Zunstable-options.
307307

308+
--output-format
309+
The output type to write. Unstable, requires -Zunstable-options.
310+
308311
ENVIRONMENT
309312
See the reference
310313
<https://doc.rust-lang.org/cargo/reference/environment-variables.html>

src/doc/man/generated_txt/cargo-rustdoc.txt

+3
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,9 @@ OPTIONS
321321
than aborting the build on the first one that fails to build.
322322
Unstable, requires -Zunstable-options.
323323

324+
--output-format
325+
The output type to write. Unstable, requires -Zunstable-options.
326+
324327
ENVIRONMENT
325328
See the reference
326329
<https://doc.rust-lang.org/cargo/reference/environment-variables.html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{{#option "`--output-format`"}}
2+
The output type to write.
3+
Unstable, requires `-Zunstable-options`.
4+
{{/option}}

src/doc/src/commands/cargo-doc.md

+5
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,11 @@ the build on the first one that fails to build. Unstable, requires
368368
<code>-Zunstable-options</code>.</dd>
369369

370370

371+
<dt class="option-term" id="option-cargo-doc---output-format"><a class="option-anchor" href="#option-cargo-doc---output-format"></a><code>--output-format</code></dt>
372+
<dd class="option-desc">The output type to write.
373+
Unstable, requires <code>-Zunstable-options</code>.</dd>
374+
375+
371376
</dl>
372377

373378
## ENVIRONMENT

src/doc/src/commands/cargo-rustdoc.md

+5
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,11 @@ the build on the first one that fails to build. Unstable, requires
387387
<code>-Zunstable-options</code>.</dd>
388388

389389

390+
<dt class="option-term" id="option-cargo-rustdoc---output-format"><a class="option-anchor" href="#option-cargo-rustdoc---output-format"></a><code>--output-format</code></dt>
391+
<dd class="option-desc">The output type to write.
392+
Unstable, requires <code>-Zunstable-options</code>.</dd>
393+
394+
390395
</dl>
391396

392397
## ENVIRONMENT

src/etc/man/cargo-doc.1

+6
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,12 @@ Build as many crates in the dependency graph as possible, rather than aborting
371371
the build on the first one that fails to build. Unstable, requires
372372
\fB\-Zunstable\-options\fR\&.
373373
.RE
374+
.sp
375+
\fB\-\-output\-format\fR
376+
.RS 4
377+
The output type to write.
378+
Unstable, requires \fB\-Zunstable\-options\fR\&.
379+
.RE
374380
.SH "ENVIRONMENT"
375381
See \fIthe reference\fR <https://doc.rust\-lang.org/cargo/reference/environment\-variables.html> for
376382
details on environment variables that Cargo reads.

src/etc/man/cargo-rustdoc.1

+6
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,12 @@ Build as many crates in the dependency graph as possible, rather than aborting
390390
the build on the first one that fails to build. Unstable, requires
391391
\fB\-Zunstable\-options\fR\&.
392392
.RE
393+
.sp
394+
\fB\-\-output\-format\fR
395+
.RS 4
396+
The output type to write.
397+
Unstable, requires \fB\-Zunstable\-options\fR\&.
398+
.RE
393399
.SH "ENVIRONMENT"
394400
See \fIthe reference\fR <https://doc.rust\-lang.org/cargo/reference/environment\-variables.html> for
395401
details on environment variables that Cargo reads.

tests/testsuite/doc.rs

+30
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,36 @@ fn simple() {
3838
assert!(p.root().join("target/doc/foo/index.html").is_file());
3939
}
4040

41+
#[cargo_test(nightly, reason = "--output-format is unstable")]
42+
fn simple_json() {
43+
let p = project()
44+
.file(
45+
"Cargo.toml",
46+
r#"
47+
[package]
48+
name = "foo"
49+
version = "0.0.1"
50+
authors = []
51+
build = "build.rs"
52+
"#,
53+
)
54+
.file("build.rs", "fn main() {}")
55+
.file("src/lib.rs", "pub fn foo() {}")
56+
.build();
57+
58+
p.cargo("doc --output-format json")
59+
.with_stderr(
60+
"\
61+
[..] foo v0.0.1 ([CWD])
62+
[..] foo v0.0.1 ([CWD])
63+
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
64+
",
65+
)
66+
.run();
67+
assert!(p.root().join("target/doc").is_dir());
68+
assert!(p.root().join("target/doc/foo.json").is_file());
69+
}
70+
4171
#[cargo_test]
4272
fn doc_no_libs() {
4373
let p = project()

tests/testsuite/rustdoc.rs

+18
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,24 @@ fn rustdoc_simple() {
2020
.run();
2121
}
2222

23+
#[cargo_test(nightly, reason = "--output-format is unstable")]
24+
fn rustdoc_simple_json() {
25+
let p = project().file("src/lib.rs", "").build();
26+
27+
p.cargo("rustdoc --output-format json -v")
28+
.with_stderr(
29+
"\
30+
[DOCUMENTING] foo v0.0.1 ([CWD])
31+
[RUNNING] `rustdoc [..]--crate-name foo src/lib.rs [..]\
32+
-o [CWD]/target/doc \
33+
[..] \
34+
-L dependency=[CWD]/target/debug/deps [..]`
35+
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
36+
",
37+
)
38+
.run();
39+
}
40+
2341
#[cargo_test]
2442
fn rustdoc_args() {
2543
let p = project().file("src/lib.rs", "").build();

0 commit comments

Comments
 (0)