rustdoc: clean up and further test mergeable CCI
This fixes a limitation that prevented me from adding it to Cargo. The rust compiler-docs bundle is built by running multiple `cargo` commands in succession, and I want to support that, so I'm stuck putting the doc parts all in one directory, so that subsequent `cargo` runs can pick up the previous runs' data. It's less clean, but it should still be usable in hermetic build environments if you give every crate its own directory (which you needed to do before, oddly enough).
This commit is contained in:
parent
24be917c03
commit
0786642d61
7 changed files with 92 additions and 17 deletions
|
|
@ -975,15 +975,16 @@ fn parse_extern_html_roots(
|
|||
Ok(externs)
|
||||
}
|
||||
|
||||
/// Path directly to crate-info file.
|
||||
/// Path directly to crate-info directory.
|
||||
///
|
||||
/// For example, `/home/user/project/target/doc.parts/<crate>/crate-info`.
|
||||
/// For example, `/home/user/project/target/doc.parts`.
|
||||
/// Each crate has its info stored in a file called `CRATENAME.json`.
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct PathToParts(pub(crate) PathBuf);
|
||||
|
||||
impl PathToParts {
|
||||
fn from_flag(path: String) -> Result<PathToParts, String> {
|
||||
let mut path = PathBuf::from(path);
|
||||
let path = PathBuf::from(path);
|
||||
// check here is for diagnostics
|
||||
if path.exists() && !path.is_dir() {
|
||||
Err(format!(
|
||||
|
|
@ -992,20 +993,22 @@ impl PathToParts {
|
|||
))
|
||||
} else {
|
||||
// if it doesn't exist, we'll create it. worry about that in write_shared
|
||||
path.push("crate-info");
|
||||
Ok(PathToParts(path))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Reports error if --include-parts-dir / crate-info is not a file
|
||||
/// Reports error if --include-parts-dir is not a directory
|
||||
fn parse_include_parts_dir(m: &getopts::Matches) -> Result<Vec<PathToParts>, String> {
|
||||
let mut ret = Vec::new();
|
||||
for p in m.opt_strs("include-parts-dir") {
|
||||
let p = PathToParts::from_flag(p)?;
|
||||
// this is just for diagnostic
|
||||
if !p.0.is_file() {
|
||||
return Err(format!("--include-parts-dir expected {} to be a file", p.0.display()));
|
||||
if !p.0.is_dir() {
|
||||
return Err(format!(
|
||||
"--include-parts-dir expected {} to be a directory",
|
||||
p.0.display()
|
||||
));
|
||||
}
|
||||
ret.push(p);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
//! or contains "invocation-specific".
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::ffi::OsString;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::fs::File;
|
||||
use std::io::{self, Write as _};
|
||||
use std::iter::once;
|
||||
|
|
@ -83,9 +83,11 @@ pub(crate) fn write_shared(
|
|||
};
|
||||
|
||||
if let Some(parts_out_dir) = &opt.parts_out_dir {
|
||||
create_parents(&parts_out_dir.0)?;
|
||||
let mut parts_out_file = parts_out_dir.0.clone();
|
||||
parts_out_file.push(&format!("{crate_name}.json"));
|
||||
create_parents(&parts_out_file)?;
|
||||
try_err!(
|
||||
fs::write(&parts_out_dir.0, serde_json::to_string(&info).unwrap()),
|
||||
fs::write(&parts_out_file, serde_json::to_string(&info).unwrap()),
|
||||
&parts_out_dir.0
|
||||
);
|
||||
}
|
||||
|
|
@ -237,13 +239,25 @@ impl CrateInfo {
|
|||
pub(crate) fn read_many(parts_paths: &[PathToParts]) -> Result<Vec<Self>, Error> {
|
||||
parts_paths
|
||||
.iter()
|
||||
.map(|parts_path| {
|
||||
let path = &parts_path.0;
|
||||
let parts = try_err!(fs::read(path), &path);
|
||||
let parts: CrateInfo = try_err!(serde_json::from_slice(&parts), &path);
|
||||
Ok::<_, Error>(parts)
|
||||
.fold(Ok(Vec::new()), |acc, parts_path| {
|
||||
let mut acc = acc?;
|
||||
let dir = &parts_path.0;
|
||||
acc.append(&mut try_err!(std::fs::read_dir(dir), dir.as_path())
|
||||
.filter_map(|file| {
|
||||
let to_crate_info = |file: Result<std::fs::DirEntry, std::io::Error>| -> Result<Option<CrateInfo>, Error> {
|
||||
let file = try_err!(file, dir.as_path());
|
||||
if file.path().extension() != Some(OsStr::new("json")) {
|
||||
return Ok(None);
|
||||
}
|
||||
let parts = try_err!(fs::read(file.path()), file.path());
|
||||
let parts: CrateInfo = try_err!(serde_json::from_slice(&parts), file.path());
|
||||
Ok(Some(parts))
|
||||
};
|
||||
to_crate_info(file).transpose()
|
||||
})
|
||||
.collect::<Result<Vec<CrateInfo>, Error>>()?);
|
||||
Ok(acc)
|
||||
})
|
||||
.collect::<Result<Vec<CrateInfo>, Error>>()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
4
tests/run-make/rustdoc-merge-directory/dep1.rs
Normal file
4
tests/run-make/rustdoc-merge-directory/dep1.rs
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
//@ hasraw crates.js 'dep1'
|
||||
//@ hasraw search.index/name/*.js 'Dep1'
|
||||
//@ has dep1/index.html
|
||||
pub struct Dep1;
|
||||
4
tests/run-make/rustdoc-merge-directory/dep2.rs
Normal file
4
tests/run-make/rustdoc-merge-directory/dep2.rs
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
//@ hasraw crates.js 'dep1'
|
||||
//@ hasraw search.index/name/*.js 'Dep1'
|
||||
//@ has dep2/index.html
|
||||
pub struct Dep2;
|
||||
4
tests/run-make/rustdoc-merge-directory/dep_missing.rs
Normal file
4
tests/run-make/rustdoc-merge-directory/dep_missing.rs
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
//@ !hasraw crates.js 'dep_missing'
|
||||
//@ !hasraw search.index/name/*.js 'DepMissing'
|
||||
//@ has dep_missing/index.html
|
||||
pub struct DepMissing;
|
||||
46
tests/run-make/rustdoc-merge-directory/rmake.rs
Normal file
46
tests/run-make/rustdoc-merge-directory/rmake.rs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
// Running --merge=finalize without an input crate root should not trigger ICE.
|
||||
// Issue: https://github.com/rust-lang/rust/issues/146646
|
||||
|
||||
//@ needs-target-std
|
||||
|
||||
use run_make_support::{htmldocck, path, rustdoc};
|
||||
|
||||
fn main() {
|
||||
let out_dir = path("out");
|
||||
let merged_dir = path("merged");
|
||||
let parts_out_dir = path("parts");
|
||||
|
||||
rustdoc()
|
||||
.input("dep1.rs")
|
||||
.out_dir(&out_dir)
|
||||
.arg("-Zunstable-options")
|
||||
.arg(format!("--parts-out-dir={}", parts_out_dir.display()))
|
||||
.arg("--merge=none")
|
||||
.run();
|
||||
assert!(parts_out_dir.join("dep1.json").exists());
|
||||
|
||||
rustdoc()
|
||||
.input("dep2.rs")
|
||||
.out_dir(&out_dir)
|
||||
.arg("-Zunstable-options")
|
||||
.arg(format!("--parts-out-dir={}", parts_out_dir.display()))
|
||||
.arg("--merge=none")
|
||||
.run();
|
||||
assert!(parts_out_dir.join("dep2.json").exists());
|
||||
|
||||
// dep_missing is different, because --parts-out-dir is not supplied
|
||||
rustdoc().input("dep_missing.rs").out_dir(&out_dir).run();
|
||||
assert!(parts_out_dir.join("dep2.json").exists());
|
||||
|
||||
let output = rustdoc()
|
||||
.arg("-Zunstable-options")
|
||||
.out_dir(&out_dir)
|
||||
.arg(format!("--include-parts-dir={}", parts_out_dir.display()))
|
||||
.arg("--merge=finalize")
|
||||
.run();
|
||||
output.assert_stderr_not_contains("error: the compiler unexpectedly panicked. this is a bug.");
|
||||
|
||||
htmldocck().arg(&out_dir).arg("dep1.rs").run();
|
||||
htmldocck().arg(&out_dir).arg("dep2.rs").run();
|
||||
htmldocck().arg(out_dir).arg("dep_missing.rs").run();
|
||||
}
|
||||
|
|
@ -16,7 +16,7 @@ fn main() {
|
|||
.arg(format!("--parts-out-dir={}", parts_out_dir.display()))
|
||||
.arg("--merge=none")
|
||||
.run();
|
||||
assert!(parts_out_dir.join("crate-info").exists());
|
||||
assert!(parts_out_dir.join("sierra.json").exists());
|
||||
|
||||
let output = rustdoc()
|
||||
.arg("-Zunstable-options")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue