diff --git a/Cargo.lock b/Cargo.lock index 65ad130d559..d57d17a3581 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1578,6 +1578,13 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "html-checker" +version = "0.1.0" +dependencies = [ + "walkdir", +] + [[package]] name = "html5ever" version = "0.25.1" diff --git a/Cargo.toml b/Cargo.toml index 327afe35c2f..4c00a7dc99e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,7 @@ members = [ "src/tools/unicode-table-generator", "src/tools/expand-yaml-anchors", "src/tools/jsondocck", + "src/tools/html-checker", ] exclude = [ diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index e2f605257bd..b4c5a2abc9c 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -450,6 +450,7 @@ macro_rules! describe { test::RustdocTheme, test::RustdocUi, test::RustdocJson, + test::HtmlCheck, // Run bootstrap close to the end as it's unlikely to fail test::Bootstrap, // Run run-make last, since these won't pass without make on Windows diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index d2fabf9967f..634332df863 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -501,8 +501,8 @@ fn run(self, builder: &Builder<'_>) { #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct Rustc { - stage: u32, - target: TargetSelection, + pub stage: u32, + pub target: TargetSelection, } impl Step for Rustc { diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 92ac3b364f6..64b3ee7c359 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -9,7 +9,7 @@ use std::fs; use std::iter; use std::path::{Path, PathBuf}; -use std::process::Command; +use std::process::{Command, Stdio}; use build_helper::{self, output, t}; @@ -161,6 +161,49 @@ fn make_run(run: RunConfig<'_>) { } } +fn check_if_tidy_is_installed() -> bool { + Command::new("tidy") + .arg("--version") + .stdout(Stdio::null()) + .status() + .map_or(false, |status| status.success()) +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub struct HtmlCheck { + target: TargetSelection, +} + +impl Step for HtmlCheck { + type Output = (); + const DEFAULT: bool = true; + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + let run = run.path("src/tools/html-checker"); + run.lazy_default_condition(Box::new(check_if_tidy_is_installed)) + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(HtmlCheck { target: run.target }); + } + + fn run(self, builder: &Builder<'_>) { + if !check_if_tidy_is_installed() { + eprintln!("not running HTML-check tool because `tidy` is missing"); + eprintln!( + "Note that `tidy` is not the in-tree `src/tools/tidy` but needs to be installed" + ); + panic!("Cannot run html-check tests"); + } + // Ensure that a few different kinds of documentation are available. + builder.default_doc(&[]); + builder.ensure(crate::doc::Rustc { target: self.target, stage: builder.top_stage }); + + try_run(builder, builder.tool_cmd(Tool::HtmlChecker).arg(builder.doc_out(self.target))); + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct Cargotest { stage: u32, diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 9d75ad0918a..aa7fe658df3 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -376,6 +376,7 @@ fn run(self, builder: &Builder<'_>) -> PathBuf { ExpandYamlAnchors, "src/tools/expand-yaml-anchors", "expand-yaml-anchors"; LintDocs, "src/tools/lint-docs", "lint-docs"; JsonDocCk, "src/tools/jsondocck", "jsondocck"; + HtmlChecker, "src/tools/html-checker", "html-checker"; ); #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)] diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile index 35d274da673..faed1761fa4 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile @@ -12,7 +12,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ cmake \ libssl-dev \ sudo \ - xz-utils + xz-utils \ + tidy # Install dependencies for chromium browser RUN apt-get install -y \ diff --git a/src/tools/html-checker/Cargo.toml b/src/tools/html-checker/Cargo.toml new file mode 100644 index 00000000000..fe35df823b6 --- /dev/null +++ b/src/tools/html-checker/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "html-checker" +version = "0.1.0" +authors = ["Guillaume Gomez "] +edition = "2018" + +[[bin]] +name = "html-checker" +path = "main.rs" + +[dependencies] +walkdir = "2" diff --git a/src/tools/html-checker/main.rs b/src/tools/html-checker/main.rs new file mode 100644 index 00000000000..a93191191cc --- /dev/null +++ b/src/tools/html-checker/main.rs @@ -0,0 +1,96 @@ +use std::env; +use std::path::Path; +use std::process::{Command, Output}; + +fn check_html_file(file: &Path) -> usize { + let to_mute = &[ + // "disabled" on or "autocomplete" on . When the fix is merged upstream, + // this warning can be used again. + "REPEATED_ATTRIBUTE", + // FIXME: mdbook uses "align" attribute on , which is not allowed. + "MISMATCHED_ATTRIBUTE_WARN", + // FIXME: mdbook doesn't add "alt" attribute on images. + "MISSING_ATTRIBUTE", + // FIXME: mdbook doesn't escape `&` (in "&String" for example). + "UNKNOWN_ENTITY", + // Compiler docs have some inlined