Skip to content

More intra-doc links, add explicit exception list to linkchecker #74485

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jul 19, 2020
Prev Previous commit
Next Next commit
Add explicit exception list to linkchecker
  • Loading branch information
Manishearth committed Jul 18, 2020
commit a9680938d0840066cb79a50248fb8a099e61389e
62 changes: 40 additions & 22 deletions src/tools/linkchecker/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,31 @@ use std::rc::Rc;

use crate::Redirect::*;

// Add linkcheck exceptions here
// If at all possible you should use intra-doc links to avoid linkcheck issues. These
// are cases where that does not work
const LINKCHECK_EXCEPTIONS: &[(&str, &[&str])] = &[
// These are methods on slice, and `Self` does not work on primitive impls
// in intra-doc links (intra-doc links are weird)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😆

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually meant to say "primitive impls are weird" lol

// https://github.com/rust-lang/rust/issues/62834 is necessary to be
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you meant the issue on primitive types.

Suggested change
// https://github.com/rust-lang/rust/issues/62834 is necessary to be
// https://github.com/rust-lang/rust/issues/63351 is necessary to be

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, in my mind the generic issue is also what blocks slice, but your thing works

// able to link to slices
(
"std/io/struct.IoSlice.html",
&[
"#method.as_mut_ptr",
"#method.sort_by_key",
"#method.make_ascii_uppercase",
"#method.make_ascii_lowercase",
],
),
// These try to link to std::collections, but are defined in alloc
// https://github.com/rust-lang/rust/issues/74481
("std/collections/btree_map/struct.BTreeMap.html", &["#insert-and-complex-keys"]),
("std/collections/btree_set/struct.BTreeSet.html", &["#insert-and-complex-keys"]),
("alloc/collections/btree_map/struct.BTreeMap.html", &["#insert-and-complex-keys"]),
("alloc/collections/btree_set/struct.BTreeSet.html", &["#insert-and-complex-keys"]),
];

macro_rules! t {
($e:expr) => {
match $e {
Expand Down Expand Up @@ -111,30 +136,20 @@ fn walk(cache: &mut Cache, root: &Path, dir: &Path, errors: &mut bool) {
}
}

fn is_exception(file: &Path, link: &str) -> bool {
if let Some(entry) = LINKCHECK_EXCEPTIONS.iter().find(|&(f, _)| file.ends_with(f)) {
entry.1.contains(&link)
} else {
false
}
}

fn check(cache: &mut Cache, root: &Path, file: &Path, errors: &mut bool) -> Option<PathBuf> {
// Ignore non-HTML files.
if file.extension().and_then(|s| s.to_str()) != Some("html") {
return None;
}

// Unfortunately we're not 100% full of valid links today to we need a few
// exceptions to get this past `make check` today.
// FIXME(#32129)
if file.ends_with("std/io/struct.IoSlice.html")
{
return None;
}

// FIXME(#32130)
if file.ends_with("alloc/collections/btree_map/struct.BTreeMap.html")
|| file.ends_with("alloc/collections/btree_set/struct.BTreeSet.html")
|| file.ends_with("std/collections/btree_map/struct.BTreeMap.html")
|| file.ends_with("std/collections/btree_set/struct.BTreeSet.html")
|| file.ends_with("std/collections/hash_set/struct.HashSet.html")
{
return None;
}

let res = load_file(cache, root, file, SkipRedirect);
let (pretty_file, contents) = match res {
Ok(res) => res,
Expand Down Expand Up @@ -249,17 +264,20 @@ fn check(cache: &mut Cache, root: &Path, file: &Path, errors: &mut bool) -> Opti
let entry = &mut cache.get_mut(&pretty_path).unwrap();
entry.parse_ids(&pretty_path, &contents, errors);

if !entry.ids.contains(*fragment) {
if !entry.ids.contains(*fragment) && !is_exception(file, &format!("#{}", fragment))
{
*errors = true;
print!("{}:{}: broken link fragment ", pretty_file.display(), i + 1);
println!("`#{}` pointing to `{}`", fragment, pretty_path.display());
};
}
} else {
*errors = true;
print!("{}:{}: broken link - ", pretty_file.display(), i + 1);
let pretty_path = path.strip_prefix(root).unwrap_or(&path);
println!("{}", pretty_path.display());
if !is_exception(file, pretty_path.to_str().unwrap()) {
*errors = true;
print!("{}:{}: broken link - ", pretty_file.display(), i + 1);
println!("{}", pretty_path.display());
}
}
});
Some(pretty_file)
Expand Down