Skip to content

Commit 225d510

Browse files
committed
feat: rebuild(-ish) rustdoc json for different version of same crates
1 parent ed8daa9 commit 225d510

6 files changed

Lines changed: 45 additions & 22 deletions

File tree

src/cargo/core/compiler/build_runner/compilation_files.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -523,18 +523,33 @@ impl<'a, 'gctx: 'a> CompilationFiles<'a, 'gctx> {
523523
vec![]
524524
}
525525
CompileMode::Doc => {
526-
let path = if bcx.build_config.intent.wants_doc_json_output() {
527-
self.output_dir(unit)
528-
.join(format!("{}.json", unit.target.crate_name()))
526+
let wants_json_doc = bcx.build_config.intent.wants_doc_json_output();
527+
528+
let path = if wants_json_doc {
529+
// Always use 'new' layout for '--output-format=json'.
530+
let crate_name = unit.target.crate_name();
531+
self.out_dir_new_layout(unit)
532+
.join(format!("{crate_name}.json"))
529533
} else {
530534
self.output_dir(unit)
531535
.join(unit.target.crate_name())
532536
.join("index.html")
533537
};
534538

539+
// Uplift if output is json, from 'new' layout location for backward compatibility
540+
// See #16773.
541+
let hardlink = if wants_json_doc {
542+
Some(
543+
self.output_dir(unit)
544+
.join(format!("{}.json", unit.target.crate_name())),
545+
)
546+
} else {
547+
None
548+
};
549+
535550
let mut outputs = vec![OutputFile {
536551
path,
537-
hardlink: None,
552+
hardlink,
538553
export_path: None,
539554
flavor: FileFlavor::Normal,
540555
}];

src/cargo/core/compiler/mod.rs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -868,7 +868,16 @@ fn prepare_rustdoc(build_runner: &BuildRunner<'_, '_>, unit: &Unit) -> CargoResu
868868
add_cap_lints(bcx, unit, &mut rustdoc);
869869

870870
unit.kind.add_target_arg(&mut rustdoc);
871-
let doc_dir = build_runner.files().output_dir(unit);
871+
872+
let doc_dir = if build_runner.bcx.build_config.intent.wants_doc_json_output() {
873+
// Always use new layout for '--output-format=json'.
874+
// In fix for https://github.com/rust-lang/cargo/issues/16291
875+
876+
build_runner.files().out_dir_new_layout(unit)
877+
} else {
878+
build_runner.files().output_dir(unit)
879+
};
880+
872881
rustdoc.arg("-o").arg(&doc_dir);
873882
rustdoc.args(&features_args(unit));
874883
rustdoc.args(&check_cfg_args(unit));
@@ -972,6 +981,7 @@ fn rustdoc(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResult<W
972981
let mut rustdoc = prepare_rustdoc(build_runner, unit)?;
973982

974983
let crate_name = unit.target.crate_name();
984+
let is_json_output = build_runner.bcx.build_config.intent.wants_doc_json_output();
975985
let doc_dir = build_runner.files().output_dir(unit);
976986
// Create the documentation directory ahead of time as rustdoc currently has
977987
// a bug where concurrent invocations will race to create this directory if
@@ -1055,13 +1065,15 @@ fn rustdoc(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResult<W
10551065
}
10561066
}
10571067

1058-
let crate_dir = doc_dir.join(&crate_name);
1059-
if crate_dir.exists() {
1060-
// Remove output from a previous build. This ensures that stale
1061-
// files for removed items are removed.
1062-
debug!("removing pre-existing doc directory {:?}", crate_dir);
1063-
paths::remove_dir_all(crate_dir)?;
1064-
}
1068+
if !is_json_output {
1069+
let crate_dir = doc_dir.join(&crate_name);
1070+
if crate_dir.exists() {
1071+
// Remove output from a previous build. This ensures that stale
1072+
// files for removed items are removed.
1073+
debug!("removing pre-existing doc directory {:?}", crate_dir);
1074+
paths::remove_dir_all(&crate_dir)?;
1075+
}
1076+
};
10651077
state.running(&rustdoc);
10661078
let timestamp = paths::set_invocation_time(&fingerprint_dir)?;
10671079

src/cargo/core/compiler/rustdoc.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -250,12 +250,6 @@ pub fn add_output_format(
250250
build_runner: &BuildRunner<'_, '_>,
251251
rustdoc: &mut ProcessBuilder,
252252
) -> CargoResult<()> {
253-
let gctx = build_runner.bcx.gctx;
254-
if !gctx.cli_unstable().unstable_options {
255-
tracing::debug!("`unstable-options` is ignored, required -Zunstable-options flag");
256-
return Ok(());
257-
}
258-
259253
if build_runner.bcx.build_config.intent.wants_doc_json_output() {
260254
rustdoc.arg("-Zunstable-options");
261255
rustdoc.arg("--output-format=json");

tests/testsuite/build_dir.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,7 @@ fn cargo_rustdoc_json_should_output_to_target_dir() {
535535
[ROOT]/foo/build-dir/debug/build/foo/[HASH]/fingerprint/doc-lib-foo
536536
[ROOT]/foo/build-dir/debug/build/foo/[HASH]/fingerprint/doc-lib-foo.json
537537
[ROOT]/foo/build-dir/debug/build/foo/[HASH]/fingerprint/invoked.timestamp
538+
[ROOT]/foo/build-dir/debug/build/foo/[HASH]/out/foo.json
538539
539540
"#
540541
]);

tests/testsuite/build_dir_legacy.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,7 @@ fn cargo_rustdoc_json_should_output_to_target_dir() {
492492
[ROOT]/foo/build-dir/debug/.fingerprint/foo-[HASH]/doc-lib-foo
493493
[ROOT]/foo/build-dir/debug/.fingerprint/foo-[HASH]/doc-lib-foo.json
494494
[ROOT]/foo/build-dir/debug/.fingerprint/foo-[HASH]/invoked.timestamp
495+
[ROOT]/foo/build-dir/debug/build/foo-[HASH]/out/foo.json
495496
496497
"#
497498
]);

tests/testsuite/rustdoc.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ fn rustdoc_simple_json() {
4646
.masquerade_as_nightly_cargo(&["rustdoc-output-format"])
4747
.with_stderr_data(str![[r#"
4848
[DOCUMENTING] foo v0.0.1 ([ROOT]/foo)
49-
[RUNNING] `rustdoc [..] --crate-name foo [..]-o [ROOT]/foo/target/doc [..] --output-format=json[..]
49+
[RUNNING] `rustdoc [..] --crate-name foo [..]-o [ROOT]/foo/target/debug/build/foo-[HASH]/out [..] --output-format=json[..]
5050
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
5151
[GENERATED] [ROOT]/foo/target/doc/foo.json
5252
@@ -63,7 +63,7 @@ fn rustdoc_json_with_new_layout() {
6363
.masquerade_as_nightly_cargo(&["rustdoc-output-format"])
6464
.with_stderr_data(str![[r#"
6565
[DOCUMENTING] foo v0.0.1 ([ROOT]/foo)
66-
[RUNNING] `rustdoc [..] --crate-name foo [..]-o [ROOT]/foo/target/doc [..] --output-format=json[..]
66+
[RUNNING] `rustdoc [..] --crate-name foo [..]-o [ROOT]/foo/target/debug/build/foo/[HASH]/out [..] --output-format=json[..]
6767
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
6868
[GENERATED] [ROOT]/foo/target/doc/foo.json
6969
@@ -434,6 +434,6 @@ fn rustdoc_json_same_crate_different_version() {
434434
.run();
435435

436436
let dep_json = fs::read_to_string(entry.root().join("target/doc/dep.json")).unwrap();
437-
assert!(!dep_json.contains("dep_v1_fn"));
438-
assert!(dep_json.contains("dep_v2_fn"));
437+
assert!(dep_json.contains("dep_v1_fn"));
438+
assert!(!dep_json.contains("dep_v2_fn"));
439439
}

0 commit comments

Comments
 (0)