mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-28 11:20:36 +00:00
Check target-dependant doc folders
When checking the fingerprint for rustdoc and applying the corresponding logic, we don't only need to consider the `target/doc` folder (Host target) but also triple targets. So now the actual compilation targets are checked during the rustdoc_fingerprint processing and they're treated as the Host/doc folder.
This commit is contained in:
parent
d2572a2800
commit
7c45021328
@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::hash_map::{Entry, HashMap};
|
use std::collections::hash_map::{Entry, HashMap};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
use std::str::{self, FromStr};
|
use std::str::{self, FromStr};
|
||||||
|
|
||||||
/// Information about the platform target gleaned from querying rustc.
|
/// Information about the platform target gleaned from querying rustc.
|
||||||
@ -755,28 +755,20 @@ impl RustcTargetData {
|
|||||||
/// Structure used to deal with Rustdoc fingerprinting
|
/// Structure used to deal with Rustdoc fingerprinting
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct RustDocFingerprint {
|
pub struct RustDocFingerprint {
|
||||||
rustc_vv: String,
|
pub rustc_vv: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RustDocFingerprint {
|
impl RustDocFingerprint {
|
||||||
/// Read the `RustDocFingerprint` info from the fingerprint file.
|
/// Read the `RustDocFingerprint` info from the fingerprint file.
|
||||||
fn read<'a, 'cfg>(cx: &Context<'a, 'cfg>) -> CargoResult<Self> {
|
fn read<'a, 'cfg>(cx: &Context<'a, 'cfg>) -> CargoResult<Self> {
|
||||||
let rustdoc_data = paths::read(
|
let rustdoc_data = paths::read(&cx.files().host_root().join(".rustdoc_fingerprint.json"))?;
|
||||||
&cx.files()
|
|
||||||
.host_root()
|
|
||||||
.join(".rustdoc_fingerprint")
|
|
||||||
.with_extension("json"),
|
|
||||||
)?;
|
|
||||||
serde_json::from_str(&rustdoc_data).map_err(|e| anyhow::anyhow!("{:?}", e))
|
serde_json::from_str(&rustdoc_data).map_err(|e| anyhow::anyhow!("{:?}", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write the `RustDocFingerprint` info into the fingerprint file.
|
/// Write the `RustDocFingerprint` info into the fingerprint file.
|
||||||
fn write<'a, 'cfg>(&self, cx: &Context<'a, 'cfg>) -> CargoResult<()> {
|
fn write<'a, 'cfg>(&self, cx: &Context<'a, 'cfg>) -> CargoResult<()> {
|
||||||
paths::write(
|
paths::write(
|
||||||
&cx.files()
|
&cx.files().host_root().join(".rustdoc_fingerprint.json"),
|
||||||
.host_root()
|
|
||||||
.join(".rustdoc_fingerprint.json")
|
|
||||||
.with_extension("json"),
|
|
||||||
serde_json::to_string(&self)?.as_bytes(),
|
serde_json::to_string(&self)?.as_bytes(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -793,14 +785,28 @@ impl RustDocFingerprint {
|
|||||||
let actual_rustdoc_target_data = RustDocFingerprint {
|
let actual_rustdoc_target_data = RustDocFingerprint {
|
||||||
rustc_vv: cx.bcx.rustc().verbose_version.clone(),
|
rustc_vv: cx.bcx.rustc().verbose_version.clone(),
|
||||||
};
|
};
|
||||||
let doc_dir = cx.files().host_root().join("doc");
|
|
||||||
|
// Collect all of the target doc paths for which the docs need to be compiled for.
|
||||||
|
let doc_dirs: Vec<PathBuf> = cx
|
||||||
|
.compilation
|
||||||
|
.root_output
|
||||||
|
.iter()
|
||||||
|
.map(|(ck, _)| match ck {
|
||||||
|
CompileKind::Host => cx.files().host_root().to_path_buf(),
|
||||||
|
CompileKind::Target(t) => cx.files().host_root().join(Path::new(t.rustc_target())),
|
||||||
|
})
|
||||||
|
.map(|path| path.join("doc"))
|
||||||
|
.collect();
|
||||||
|
|
||||||
// Check wether `.rustdoc_fingerprint.json` exists
|
// Check wether `.rustdoc_fingerprint.json` exists
|
||||||
match Self::read(cx) {
|
match Self::read(cx) {
|
||||||
Ok(fingerprint) => {
|
Ok(fingerprint) => {
|
||||||
// Check if rustc_version matches the one we just used. Otherways,
|
// Check if rustc_version matches the one we just used. Otherways,
|
||||||
// remove the `doc` folder to trigger a re-compilation of the docs.
|
// remove the `doc` folder to trigger a re-compilation of the docs.
|
||||||
if fingerprint.rustc_vv != actual_rustdoc_target_data.rustc_vv {
|
if fingerprint.rustc_vv != actual_rustdoc_target_data.rustc_vv {
|
||||||
paths::remove_dir_all(&doc_dir)?;
|
doc_dirs
|
||||||
|
.iter()
|
||||||
|
.try_for_each(|path| paths::remove_dir_all(&path))?;
|
||||||
actual_rustdoc_target_data.write(cx)?
|
actual_rustdoc_target_data.write(cx)?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -810,7 +816,9 @@ impl RustDocFingerprint {
|
|||||||
// exists neither, we simply do nothing and continue.
|
// exists neither, we simply do nothing and continue.
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
// We don't care if this suceeds as explained above.
|
// We don't care if this suceeds as explained above.
|
||||||
let _ = paths::remove_dir_all(doc_dir);
|
let _ = doc_dirs
|
||||||
|
.iter()
|
||||||
|
.try_for_each(|path| paths::remove_dir_all(&path));
|
||||||
actual_rustdoc_target_data.write(cx)?
|
actual_rustdoc_target_data.write(cx)?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
//! Tests for the `cargo doc` command.
|
//! Tests for the `cargo doc` command.
|
||||||
|
|
||||||
|
use cargo::core::compiler::RustDocFingerprint;
|
||||||
use cargo_test_support::paths::CargoPathExt;
|
use cargo_test_support::paths::CargoPathExt;
|
||||||
use cargo_test_support::registry::Package;
|
use cargo_test_support::registry::Package;
|
||||||
use cargo_test_support::{basic_lib_manifest, basic_manifest, git, project};
|
use cargo_test_support::{basic_lib_manifest, basic_manifest, git, project};
|
||||||
use cargo_test_support::{is_nightly, rustc_host};
|
use cargo_test_support::{is_nightly, rustc_host};
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
@ -1641,15 +1641,7 @@ fn crate_versions_flag_is_overridden() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cargo_test]
|
#[cargo_test]
|
||||||
fn doc_fingerprint_versioning_consistent() {
|
fn doc_fingerprint_is_versioning_consistent() {
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
|
||||||
pub struct RustDocFingerprint {
|
|
||||||
rustc_vv: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that using different Rustc versions forces a
|
|
||||||
// doc re-compilation producing new html, css & js files.
|
|
||||||
|
|
||||||
// Random rustc verbose version
|
// Random rustc verbose version
|
||||||
let old_rustc_verbose_version = format!(
|
let old_rustc_verbose_version = format!(
|
||||||
"\
|
"\
|
||||||
@ -1730,3 +1722,95 @@ LLVM version: 9.0
|
|||||||
(String::from_utf8_lossy(&output.stdout).as_ref())
|
(String::from_utf8_lossy(&output.stdout).as_ref())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cargo_test]
|
||||||
|
fn doc_fingerprint_respects_target_paths() {
|
||||||
|
// Random rustc verbose version
|
||||||
|
let old_rustc_verbose_version = format!(
|
||||||
|
"\
|
||||||
|
rustc 1.41.1 (f3e1a954d 2020-02-24)
|
||||||
|
binary: rustc
|
||||||
|
commit-hash: f3e1a954d2ead4e2fc197c7da7d71e6c61bad196
|
||||||
|
commit-date: 2020-02-24
|
||||||
|
host: {}
|
||||||
|
release: 1.41.1
|
||||||
|
LLVM version: 9.0
|
||||||
|
",
|
||||||
|
rustc_host()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create the dummy project.
|
||||||
|
let dummy_project = project()
|
||||||
|
.file(
|
||||||
|
"Cargo.toml",
|
||||||
|
r#"
|
||||||
|
[package]
|
||||||
|
name = "foo"
|
||||||
|
version = "1.2.4"
|
||||||
|
authors = []
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.file("src/lib.rs", "//! These are the docs!")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
dummy_project
|
||||||
|
.cargo("doc --target x86_64-unknown-linux-gnu")
|
||||||
|
.run();
|
||||||
|
|
||||||
|
let fingerprint: RustDocFingerprint =
|
||||||
|
serde_json::from_str(&dummy_project.read_file("target/.rustdoc_fingerprint.json"))
|
||||||
|
.expect("JSON Serde fail");
|
||||||
|
|
||||||
|
// Check that the fingerprint contains the actual rustc version
|
||||||
|
// which has been used to compile the docs.
|
||||||
|
let output = std::process::Command::new("rustc")
|
||||||
|
.arg("-vV")
|
||||||
|
.output()
|
||||||
|
.expect("Failed to get actual rustc verbose version");
|
||||||
|
assert_eq!(
|
||||||
|
fingerprint.rustc_vv,
|
||||||
|
(String::from_utf8_lossy(&output.stdout).as_ref())
|
||||||
|
);
|
||||||
|
|
||||||
|
// As the test shows above. Now we have generated the `doc/` folder and inside
|
||||||
|
// the rustdoc fingerprint file is located with the correct rustc version.
|
||||||
|
// So we will remove it and create a new fingerprint with an old rustc version
|
||||||
|
// inside it. We will also place a bogus file inside of the `doc/` folder to ensure
|
||||||
|
// it gets removed as we expect on the next doc compilation.
|
||||||
|
dummy_project.change_file(
|
||||||
|
"target/.rustdoc_fingerprint.json",
|
||||||
|
&old_rustc_verbose_version,
|
||||||
|
);
|
||||||
|
|
||||||
|
fs::write(
|
||||||
|
dummy_project
|
||||||
|
.build_dir()
|
||||||
|
.join("x86_64-unknown-linux-gnu/doc/bogus_file"),
|
||||||
|
String::from("This is a bogus file and should be removed!"),
|
||||||
|
)
|
||||||
|
.expect("Error writing test bogus file");
|
||||||
|
|
||||||
|
// Now if we trigger another compilation, since the fingerprint contains an old version
|
||||||
|
// of rustc, cargo should remove the entire `/doc` folder (including the fingerprint)
|
||||||
|
// and generating another one with the actual version.
|
||||||
|
// It should also remove the bogus file we created above.
|
||||||
|
dummy_project
|
||||||
|
.cargo("doc --target x86_64-unknown-linux-gnu")
|
||||||
|
.run();
|
||||||
|
|
||||||
|
assert!(!dummy_project
|
||||||
|
.build_dir()
|
||||||
|
.join("x86_64-unknown-linux-gnu/doc/bogus_file")
|
||||||
|
.exists());
|
||||||
|
|
||||||
|
let fingerprint: RustDocFingerprint =
|
||||||
|
serde_json::from_str(&dummy_project.read_file("target/.rustdoc_fingerprint.json"))
|
||||||
|
.expect("JSON Serde fail");
|
||||||
|
|
||||||
|
// Check that the fingerprint contains the actual rustc version
|
||||||
|
// which has been used to compile the docs.
|
||||||
|
assert_eq!(
|
||||||
|
fingerprint.rustc_vv,
|
||||||
|
(String::from_utf8_lossy(&output.stdout).as_ref())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user