mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-29 02:03:53 +00:00
Rollup merge of #68791 - mark-i-m:proper-linkcheck, r=ehuss,JohnTitor
implement proper linkchecker hardening r? @JohnTitor This implements proper linkcheck filtering... we might need to fiddle with a bit to adjust what is or isn't filtered, but this seems to work reasonable locally.
This commit is contained in:
commit
4ce157d008
@ -3067,6 +3067,7 @@ name = "rustbook"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"codespan",
|
||||
"codespan-reporting",
|
||||
"failure",
|
||||
"mdbook",
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 92baf7293dd2d418d2ac4b141b0faa822075d9f7
|
||||
Subproject commit 5bd60bc51efaec04e69e2e18b59678e2af066433
|
@ -6,13 +6,14 @@ license = "MIT OR Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[features]
|
||||
linkcheck = ["mdbook-linkcheck", "codespan-reporting"]
|
||||
linkcheck = ["mdbook-linkcheck", "codespan-reporting", "codespan"]
|
||||
|
||||
[dependencies]
|
||||
clap = "2.25.0"
|
||||
failure = "0.1"
|
||||
mdbook-linkcheck = { version = "0.5.0", optional = true }
|
||||
# Keep in sync with mdbook-linkcheck.
|
||||
codespan = { version = "0.5", optional = true }
|
||||
codespan-reporting = { version = "0.5", optional = true }
|
||||
|
||||
|
||||
|
@ -8,11 +8,6 @@ use clap::{App, AppSettings, ArgMatches, SubCommand};
|
||||
use mdbook::errors::Result as Result3;
|
||||
use mdbook::MDBook;
|
||||
|
||||
#[cfg(feature = "linkcheck")]
|
||||
use failure::Error;
|
||||
#[cfg(feature = "linkcheck")]
|
||||
use mdbook::renderer::RenderContext;
|
||||
|
||||
fn main() {
|
||||
let d_message = "-d, --dest-dir=[dest-dir]
|
||||
'The output directory for your book{n}(Defaults to ./book when omitted)'";
|
||||
@ -53,8 +48,18 @@ fn main() {
|
||||
("linkcheck", Some(sub_matches)) => {
|
||||
#[cfg(feature = "linkcheck")]
|
||||
{
|
||||
if let Err(err) = linkcheck(sub_matches) {
|
||||
eprintln!("Error: {}", err);
|
||||
let (diags, files) = linkcheck(sub_matches).expect("Error while linkchecking.");
|
||||
if !diags.is_empty() {
|
||||
let color = codespan_reporting::term::termcolor::ColorChoice::Auto;
|
||||
let mut writer =
|
||||
codespan_reporting::term::termcolor::StandardStream::stderr(color);
|
||||
let cfg = codespan_reporting::term::Config::default();
|
||||
|
||||
for diag in diags {
|
||||
codespan_reporting::term::emit(&mut writer, &cfg, &files, &diag)
|
||||
.expect("Unable to emit linkcheck error.");
|
||||
}
|
||||
|
||||
std::process::exit(101);
|
||||
}
|
||||
}
|
||||
@ -73,14 +78,55 @@ fn main() {
|
||||
}
|
||||
|
||||
#[cfg(feature = "linkcheck")]
|
||||
pub fn linkcheck(args: &ArgMatches<'_>) -> Result<(), Error> {
|
||||
pub fn linkcheck(
|
||||
args: &ArgMatches<'_>,
|
||||
) -> Result<(Vec<codespan_reporting::diagnostic::Diagnostic>, codespan::Files), failure::Error> {
|
||||
use mdbook_linkcheck::Reason;
|
||||
|
||||
let book_dir = get_book_dir(args);
|
||||
let src_dir = book_dir.join("src");
|
||||
let book = MDBook::load(&book_dir).unwrap();
|
||||
let cfg = book.config;
|
||||
let render_ctx = RenderContext::new(&book_dir, book.book, cfg, &book_dir);
|
||||
let cache_file = render_ctx.destination.join("cache.json");
|
||||
let color = codespan_reporting::term::termcolor::ColorChoice::Auto;
|
||||
mdbook_linkcheck::run(&cache_file, color, &render_ctx)
|
||||
let linkck_cfg = mdbook_linkcheck::get_config(&book.config)?;
|
||||
let mut files = codespan::Files::new();
|
||||
let target_files = mdbook_linkcheck::load_files_into_memory(&book.book, &mut files);
|
||||
let cache = mdbook_linkcheck::Cache::default();
|
||||
|
||||
let (links, incomplete) = mdbook_linkcheck::extract_links(target_files, &files);
|
||||
|
||||
let outcome =
|
||||
mdbook_linkcheck::validate(&links, &linkck_cfg, &src_dir, &cache, &files, incomplete)?;
|
||||
|
||||
let mut is_real_error = false;
|
||||
|
||||
for link in outcome.invalid_links.iter() {
|
||||
match &link.reason {
|
||||
Reason::FileNotFound | Reason::TraversesParentDirectories => {
|
||||
is_real_error = true;
|
||||
}
|
||||
Reason::UnsuccessfulServerResponse(status) => {
|
||||
if status.is_client_error() {
|
||||
is_real_error = true;
|
||||
} else {
|
||||
eprintln!("Unsuccessful server response for link `{}`", link.link.uri);
|
||||
}
|
||||
}
|
||||
Reason::Client(err) => {
|
||||
if err.is_timeout() {
|
||||
eprintln!("Timeout for link `{}`", link.link.uri);
|
||||
} else if err.is_server_error() {
|
||||
eprintln!("Server error for link `{}`", link.link.uri);
|
||||
} else {
|
||||
is_real_error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if is_real_error {
|
||||
Ok((outcome.generate_diagnostics(&files, linkck_cfg.warning_policy), files))
|
||||
} else {
|
||||
Ok((vec![], files))
|
||||
}
|
||||
}
|
||||
|
||||
// Build command implementation
|
||||
|
Loading…
Reference in New Issue
Block a user