Skip to content

Commit 98e1c55

Browse files
authored
Rollup merge of rust-lang#149850 - GuillaumeGomez:rm-tidy-rustdoc, r=yotamofek
Remove "tidy" tool for `tests/rustdoc` testsuite As discussed in the [last rustdoc meeting](https://rust-lang.zulipchat.com/#narrow/channel/393423-t-rustdoc.2Fmeetings/topic/2025-12-08/near/562554410), it seems like the current `tidy` tool is not used much for the `rustdoc` testsuite by the rustdoc contributors as it doesn't fit nicely our needs. Until we find something better, we decided to remove it. r? `@yotamofek`
2 parents d641495 + 4d697d2 commit 98e1c55

File tree

7 files changed

+8
-265
lines changed

7 files changed

+8
-265
lines changed

src/tools/compiletest/src/common.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use camino::{Utf8Path, Utf8PathBuf};
99
use semver::Version;
1010

1111
use crate::edition::Edition;
12-
use crate::executor::ColorConfig;
1312
use crate::fatal;
1413
use crate::util::{Utf8PathBufExt, add_dylib_path, string_enum};
1514

@@ -597,11 +596,6 @@ pub struct Config {
597596
/// FIXME: this is *way* too coarse; the user can't select *which* info to verbosely dump.
598597
pub verbose: bool,
599598

600-
/// Whether to use colors in test output.
601-
///
602-
/// Note: the exact control mechanism is delegated to [`colored`].
603-
pub color: ColorConfig,
604-
605599
/// Where to find the remote test client process, if we're using it.
606600
///
607601
/// Note: this is *only* used for target platform executables created by `run-make` test
@@ -623,9 +617,6 @@ pub struct Config {
623617
/// created in `$test_suite_build_root/rustfix_missing_coverage.txt`
624618
pub rustfix_coverage: bool,
625619

626-
/// Whether to run `tidy` (html-tidy) when a rustdoc test fails.
627-
pub has_html_tidy: bool,
628-
629620
/// Whether to run `enzyme` autodiff tests.
630621
pub has_enzyme: bool,
631622

src/tools/compiletest/src/executor.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -341,15 +341,6 @@ pub(crate) struct CollectedTestDesc {
341341
pub(crate) should_fail: ShouldFail,
342342
}
343343

344-
/// Whether console output should be colored or not.
345-
#[derive(Copy, Clone, Default, Debug)]
346-
pub enum ColorConfig {
347-
#[default]
348-
AutoColor,
349-
AlwaysColor,
350-
NeverColor,
351-
}
352-
353344
/// Tests with `//@ should-fail` are tests of compiletest itself, and should
354345
/// be reported as successful if and only if they would have _failed_.
355346
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]

src/tools/compiletest/src/lib.rs

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ use core::panic;
2424
use std::collections::HashSet;
2525
use std::fmt::Write;
2626
use std::io::{self, ErrorKind};
27-
use std::process::{Command, Stdio};
2827
use std::sync::{Arc, OnceLock};
2928
use std::time::SystemTime;
3029
use std::{env, fs, vec};
@@ -43,7 +42,7 @@ use crate::common::{
4342
};
4443
use crate::directives::{AuxProps, DirectivesCache, FileDirectives};
4544
use crate::edition::parse_edition;
46-
use crate::executor::{CollectedTest, ColorConfig};
45+
use crate::executor::CollectedTest;
4746

4847
/// Creates the `Config` instance for this invocation of compiletest.
4948
///
@@ -136,8 +135,9 @@ fn parse_config(args: Vec<String>) -> Config {
136135
"overwrite stderr/stdout files instead of complaining about a mismatch",
137136
)
138137
.optflag("", "fail-fast", "stop as soon as possible after any test fails")
139-
.optopt("", "color", "coloring: auto, always, never", "WHEN")
140138
.optopt("", "target", "the target to build for", "TARGET")
139+
// FIXME: Should be removed once `bootstrap` will be updated to not use this option.
140+
.optopt("", "color", "coloring: auto, always, never", "WHEN")
141141
.optopt("", "host", "the host to build for", "HOST")
142142
.optopt("", "cdb", "path to CDB to use for CDB debuginfo tests", "PATH")
143143
.optopt("", "gdb", "path to GDB to use for GDB debuginfo tests", "PATH")
@@ -274,12 +274,6 @@ fn parse_config(args: Vec<String>) -> Config {
274274
let lldb = matches.opt_str("lldb").map(Utf8PathBuf::from);
275275
let lldb_version =
276276
matches.opt_str("lldb-version").as_deref().and_then(debuggers::extract_lldb_version);
277-
let color = match matches.opt_str("color").as_deref() {
278-
Some("auto") | None => ColorConfig::AutoColor,
279-
Some("always") => ColorConfig::AlwaysColor,
280-
Some("never") => ColorConfig::NeverColor,
281-
Some(x) => panic!("argument for --color must be auto, always, or never, but found `{}`", x),
282-
};
283277
// FIXME: this is very questionable, we really should be obtaining LLVM version info from
284278
// `bootstrap`, and not trying to be figuring out that in `compiletest` by running the
285279
// `FileCheck` binary.
@@ -304,16 +298,6 @@ fn parse_config(args: Vec<String>) -> Config {
304298
let with_rustc_debug_assertions = matches.opt_present("with-rustc-debug-assertions");
305299
let with_std_debug_assertions = matches.opt_present("with-std-debug-assertions");
306300
let mode = matches.opt_str("mode").unwrap().parse().expect("invalid mode");
307-
let has_html_tidy = if mode == TestMode::Rustdoc {
308-
Command::new("tidy")
309-
.arg("--version")
310-
.stdout(Stdio::null())
311-
.status()
312-
.map_or(false, |status| status.success())
313-
} else {
314-
// Avoid spawning an external command when we know html-tidy won't be used.
315-
false
316-
};
317301
let has_enzyme = matches.opt_present("has-enzyme");
318302
let filters = if mode == TestMode::RunMake {
319303
matches
@@ -455,11 +439,9 @@ fn parse_config(args: Vec<String>) -> Config {
455439
adb_device_status,
456440
verbose: matches.opt_present("verbose"),
457441
only_modified: matches.opt_present("only-modified"),
458-
color,
459442
remote_test_client: matches.opt_str("remote-test-client").map(Utf8PathBuf::from),
460443
compare_mode,
461444
rustfix_coverage: matches.opt_present("rustfix-coverage"),
462-
has_html_tidy,
463445
has_enzyme,
464446
channel: matches.opt_str("channel").unwrap(),
465447
git_hash: matches.opt_present("git-hash"),
@@ -1144,10 +1126,6 @@ fn check_for_overlapping_test_paths(found_path_stems: &HashSet<Utf8PathBuf>) {
11441126
}
11451127

11461128
fn early_config_check(config: &Config) {
1147-
if !config.has_html_tidy && config.mode == TestMode::Rustdoc {
1148-
warning!("`tidy` (html-tidy.org) is not installed; diffs will not be generated");
1149-
}
1150-
11511129
if !config.profiler_runtime && config.mode == TestMode::CoverageRun {
11521130
let actioned = if config.bless { "blessed" } else { "checked" };
11531131
warning!("profiler runtime is not available, so `.coverage` files won't be {actioned}");

src/tools/compiletest/src/runtest.rs

Lines changed: 4 additions & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
use std::borrow::Cow;
22
use std::collections::{HashMap, HashSet};
33
use std::ffi::OsString;
4-
use std::fs::{self, File, create_dir_all};
4+
use std::fs::{self, create_dir_all};
55
use std::hash::{DefaultHasher, Hash, Hasher};
66
use std::io::prelude::*;
7-
use std::io::{self, BufReader};
87
use std::process::{Child, Command, ExitStatus, Output, Stdio};
9-
use std::{env, fmt, iter, str};
8+
use std::{env, fmt, io, iter, str};
109

1110
use build_helper::fs::remove_and_create_dir_all;
1211
use camino::{Utf8Path, Utf8PathBuf};
@@ -23,9 +22,9 @@ use crate::directives::TestProps;
2322
use crate::errors::{Error, ErrorKind, load_errors};
2423
use crate::output_capture::ConsoleOut;
2524
use crate::read2::{Truncated, read2_abbreviated};
26-
use crate::runtest::compute_diff::{DiffLine, make_diff, write_diff, write_filtered_diff};
25+
use crate::runtest::compute_diff::{DiffLine, make_diff, write_diff};
2726
use crate::util::{Utf8PathBufExt, add_dylib_path, static_regex};
28-
use crate::{ColorConfig, help, json, stamp_file_path, warning};
27+
use crate::{json, stamp_file_path};
2928

3029
// Helper modules that implement test running logic for each test suite.
3130
// tidy-alphabetical-start
@@ -2165,161 +2164,6 @@ impl<'test> TestCx<'test> {
21652164
if cfg!(target_os = "freebsd") { "ISO-8859-1" } else { "UTF-8" }
21662165
}
21672166

2168-
fn compare_to_default_rustdoc(&self, out_dir: &Utf8Path) {
2169-
if !self.config.has_html_tidy {
2170-
return;
2171-
}
2172-
writeln!(self.stdout, "info: generating a diff against nightly rustdoc");
2173-
2174-
let suffix =
2175-
self.safe_revision().map_or("nightly".into(), |path| path.to_owned() + "-nightly");
2176-
let compare_dir = output_base_dir(self.config, self.testpaths, Some(&suffix));
2177-
remove_and_create_dir_all(&compare_dir).unwrap_or_else(|e| {
2178-
panic!("failed to remove and recreate output directory `{compare_dir}`: {e}")
2179-
});
2180-
2181-
// We need to create a new struct for the lifetimes on `config` to work.
2182-
let new_rustdoc = TestCx {
2183-
config: &Config {
2184-
// FIXME: use beta or a user-specified rustdoc instead of
2185-
// hardcoding the default toolchain
2186-
rustdoc_path: Some("rustdoc".into()),
2187-
// Needed for building auxiliary docs below
2188-
rustc_path: "rustc".into(),
2189-
..self.config.clone()
2190-
},
2191-
..*self
2192-
};
2193-
2194-
let output_file = TargetLocation::ThisDirectory(new_rustdoc.aux_output_dir_name());
2195-
let mut rustc = new_rustdoc.make_compile_args(
2196-
&new_rustdoc.testpaths.file,
2197-
output_file,
2198-
Emit::None,
2199-
AllowUnused::Yes,
2200-
LinkToAux::Yes,
2201-
Vec::new(),
2202-
);
2203-
let aux_dir = new_rustdoc.aux_output_dir();
2204-
new_rustdoc.build_all_auxiliary(&aux_dir, &mut rustc);
2205-
2206-
let proc_res = new_rustdoc.document(&compare_dir, DocKind::Html);
2207-
if !proc_res.status.success() {
2208-
writeln!(self.stderr, "failed to run nightly rustdoc");
2209-
return;
2210-
}
2211-
2212-
#[rustfmt::skip]
2213-
let tidy_args = [
2214-
"--new-blocklevel-tags", "rustdoc-search,rustdoc-toolbar,rustdoc-topbar",
2215-
"--indent", "yes",
2216-
"--indent-spaces", "2",
2217-
"--wrap", "0",
2218-
"--show-warnings", "no",
2219-
"--markup", "yes",
2220-
"--quiet", "yes",
2221-
"-modify",
2222-
];
2223-
let tidy_dir = |dir| {
2224-
for entry in walkdir::WalkDir::new(dir) {
2225-
let entry = entry.expect("failed to read file");
2226-
if entry.file_type().is_file()
2227-
&& entry.path().extension().and_then(|p| p.to_str()) == Some("html")
2228-
{
2229-
let status =
2230-
Command::new("tidy").args(&tidy_args).arg(entry.path()).status().unwrap();
2231-
// `tidy` returns 1 if it modified the file.
2232-
assert!(status.success() || status.code() == Some(1));
2233-
}
2234-
}
2235-
};
2236-
tidy_dir(out_dir);
2237-
tidy_dir(&compare_dir);
2238-
2239-
let pager = {
2240-
let output = Command::new("git").args(&["config", "--get", "core.pager"]).output().ok();
2241-
output.and_then(|out| {
2242-
if out.status.success() {
2243-
Some(String::from_utf8(out.stdout).expect("invalid UTF8 in git pager"))
2244-
} else {
2245-
None
2246-
}
2247-
})
2248-
};
2249-
2250-
let diff_filename = format!("build/tmp/rustdoc-compare-{}.diff", std::process::id());
2251-
2252-
if !write_filtered_diff(
2253-
self,
2254-
&diff_filename,
2255-
out_dir,
2256-
&compare_dir,
2257-
self.config.verbose,
2258-
|file_type, extension| {
2259-
file_type.is_file() && (extension == Some("html") || extension == Some("js"))
2260-
},
2261-
) {
2262-
return;
2263-
}
2264-
2265-
match self.config.color {
2266-
ColorConfig::AlwaysColor => colored::control::set_override(true),
2267-
ColorConfig::NeverColor => colored::control::set_override(false),
2268-
_ => {}
2269-
}
2270-
2271-
if let Some(pager) = pager {
2272-
let pager = pager.trim();
2273-
if self.config.verbose {
2274-
writeln!(self.stderr, "using pager {}", pager);
2275-
}
2276-
let output = Command::new(pager)
2277-
// disable paging; we want this to be non-interactive
2278-
.env("PAGER", "")
2279-
.stdin(File::open(&diff_filename).unwrap())
2280-
// Capture output and print it explicitly so it will in turn be
2281-
// captured by output-capture.
2282-
.output()
2283-
.unwrap();
2284-
assert!(output.status.success());
2285-
writeln!(self.stdout, "{}", String::from_utf8_lossy(&output.stdout));
2286-
writeln!(self.stderr, "{}", String::from_utf8_lossy(&output.stderr));
2287-
} else {
2288-
warning!("no pager configured, falling back to unified diff");
2289-
help!(
2290-
"try configuring a git pager (e.g. `delta`) with \
2291-
`git config --global core.pager delta`"
2292-
);
2293-
let mut out = io::stdout();
2294-
let mut diff = BufReader::new(File::open(&diff_filename).unwrap());
2295-
let mut line = Vec::new();
2296-
loop {
2297-
line.truncate(0);
2298-
match diff.read_until(b'\n', &mut line) {
2299-
Ok(0) => break,
2300-
Ok(_) => {}
2301-
Err(e) => writeln!(self.stderr, "ERROR: {:?}", e),
2302-
}
2303-
match String::from_utf8(line.clone()) {
2304-
Ok(line) => {
2305-
if line.starts_with('+') {
2306-
write!(&mut out, "{}", line.green()).unwrap();
2307-
} else if line.starts_with('-') {
2308-
write!(&mut out, "{}", line.red()).unwrap();
2309-
} else if line.starts_with('@') {
2310-
write!(&mut out, "{}", line.blue()).unwrap();
2311-
} else {
2312-
out.write_all(line.as_bytes()).unwrap();
2313-
}
2314-
}
2315-
Err(_) => {
2316-
write!(&mut out, "{}", String::from_utf8_lossy(&line).reversed()).unwrap();
2317-
}
2318-
}
2319-
}
2320-
};
2321-
}
2322-
23232167
fn get_lines(&self, path: &Utf8Path, mut other_files: Option<&mut Vec<String>>) -> Vec<usize> {
23242168
let content = fs::read_to_string(path.as_std_path()).unwrap();
23252169
let mut ignore = false;

src/tools/compiletest/src/runtest/compute_diff.rs

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
11
use std::collections::VecDeque;
2-
use std::fs::{File, FileType};
3-
4-
use camino::Utf8Path;
5-
6-
use crate::runtest::TestCx;
72

83
#[derive(Debug, PartialEq)]
94
pub enum DiffLine {
@@ -109,55 +104,3 @@ pub(crate) fn write_diff(expected: &str, actual: &str, context_size: usize) -> S
109104
}
110105
output
111106
}
112-
113-
/// Filters based on filetype and extension whether to diff a file.
114-
///
115-
/// Returns whether any data was actually written.
116-
pub(crate) fn write_filtered_diff<Filter>(
117-
cx: &TestCx<'_>,
118-
diff_filename: &str,
119-
out_dir: &Utf8Path,
120-
compare_dir: &Utf8Path,
121-
verbose: bool,
122-
filter: Filter,
123-
) -> bool
124-
where
125-
Filter: Fn(FileType, Option<&str>) -> bool,
126-
{
127-
use std::io::{Read, Write};
128-
let mut diff_output = File::create(diff_filename).unwrap();
129-
let mut wrote_data = false;
130-
for entry in walkdir::WalkDir::new(out_dir.as_std_path()) {
131-
let entry = entry.expect("failed to read file");
132-
let extension = entry.path().extension().and_then(|p| p.to_str());
133-
if filter(entry.file_type(), extension) {
134-
let expected_path = compare_dir
135-
.as_std_path()
136-
.join(entry.path().strip_prefix(&out_dir.as_std_path()).unwrap());
137-
let expected = if let Ok(s) = std::fs::read(&expected_path) { s } else { continue };
138-
let actual_path = entry.path();
139-
let actual = std::fs::read(&actual_path).unwrap();
140-
let diff = unified_diff::diff(
141-
&expected,
142-
&expected_path.to_str().unwrap(),
143-
&actual,
144-
&actual_path.to_str().unwrap(),
145-
3,
146-
);
147-
wrote_data |= !diff.is_empty();
148-
diff_output.write_all(&diff).unwrap();
149-
}
150-
}
151-
152-
if !wrote_data {
153-
writeln!(cx.stdout, "note: diff is identical to nightly rustdoc");
154-
assert!(diff_output.metadata().unwrap().len() == 0);
155-
return false;
156-
} else if verbose {
157-
writeln!(cx.stderr, "printing diff:");
158-
let mut buf = Vec::new();
159-
diff_output.read_to_end(&mut buf).unwrap();
160-
std::io::stderr().lock().write_all(&mut buf).unwrap();
161-
}
162-
true
163-
}

src/tools/compiletest/src/runtest/rustdoc.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@ impl TestCx<'_> {
2828
}
2929
let res = self.run_command_to_procres(&mut cmd);
3030
if !res.status.success() {
31-
self.fatal_proc_rec_general("htmldocck failed!", None, &res, || {
32-
self.compare_to_default_rustdoc(&out_dir);
33-
});
31+
self.fatal_proc_rec("htmldocck failed!", &res);
3432
}
3533
}
3634
}

0 commit comments

Comments
 (0)