Skip to content

Commit ef4325e

Browse files
author
Orion Gonzalez
committed
implemented custom differ
1 parent 7323830 commit ef4325e

File tree

5 files changed

+63
-39
lines changed

5 files changed

+63
-39
lines changed

config.example.toml

+3
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,9 @@
419419
# passed to cargo invocations.
420420
#jobs = 0
421421

422+
# What custom diff tool to use for displaying compiletest tests.
423+
#display-diff-tool = "difft --color=always --background=light --display=side-by-side"
424+
422425
# =============================================================================
423426
# General install configuration options
424427
# =============================================================================

src/bootstrap/src/core/build_steps/test.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1834,6 +1834,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
18341834
if builder.config.cmd.only_modified() {
18351835
cmd.arg("--only-modified");
18361836
}
1837+
if let Some(display_diff_tool) = &builder.config.display_diff_tool {
1838+
cmd.arg("--display-diff-tool").arg(display_diff_tool);
1839+
}
18371840

18381841
let mut flags = if is_rustdoc { Vec::new() } else { vec!["-Crpath".to_string()] };
18391842
flags.push(format!("-Cdebuginfo={}", builder.config.rust_debuginfo_level_tests));

src/bootstrap/src/core/config/config.rs

+6
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,9 @@ pub struct Config {
368368
/// The paths to work with. For example: with `./x check foo bar` we get
369369
/// `paths=["foo", "bar"]`.
370370
pub paths: Vec<PathBuf>,
371+
372+
/// What custom diff tool to use for displaying compiletest tests.
373+
pub display_diff_tool: Option<String>,
371374
}
372375

373376
#[derive(Clone, Debug, Default)]
@@ -892,6 +895,7 @@ define_config! {
892895
android_ndk: Option<PathBuf> = "android-ndk",
893896
optimized_compiler_builtins: Option<bool> = "optimized-compiler-builtins",
894897
jobs: Option<u32> = "jobs",
898+
display_diff_tool: Option<String> = "display-diff-tool",
895899
}
896900
}
897901

@@ -1512,6 +1516,7 @@ impl Config {
15121516
android_ndk,
15131517
optimized_compiler_builtins,
15141518
jobs,
1519+
display_diff_tool,
15151520
} = toml.build.unwrap_or_default();
15161521

15171522
config.jobs = Some(threads_from_config(flags.jobs.unwrap_or(jobs.unwrap_or(0))));
@@ -2158,6 +2163,7 @@ impl Config {
21582163
config.rust_debuginfo_level_tests = debuginfo_level_tests.unwrap_or(DebuginfoLevel::None);
21592164
config.optimized_compiler_builtins =
21602165
optimized_compiler_builtins.unwrap_or(config.channel != "dev");
2166+
config.display_diff_tool = display_diff_tool;
21612167

21622168
let download_rustc = config.download_rustc_commit.is_some();
21632169
// See https://github.com/rust-lang/compiler-team/issues/326

src/tools/compiletest/src/lib.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,9 @@ pub fn parse_config(args: Vec<String>) -> Config {
175175
"git-merge-commit-email",
176176
"email address used for finding merge commits",
177177
"EMAIL",
178-
);
178+
)
179+
.optopt("", "display-diff-tool", "What custom diff tool to use for displaying compiletest tests.", "COMMAND")
180+
;
179181

180182
let (argv0, args_) = args.split_first().unwrap();
181183
if args.len() == 1 || args[1] == "-h" || args[1] == "--help" {
@@ -364,7 +366,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
364366
git_merge_commit_email: matches.opt_str("git-merge-commit-email").unwrap(),
365367

366368
profiler_runtime: matches.opt_present("profiler-runtime"),
367-
diff_command: env::var("COMPILETEST_DIFF_TOOL").ok(),
369+
diff_command: matches.opt_str("display-diff-tool"),
368370
}
369371
}
370372

src/tools/compiletest/src/runtest.rs

+47-37
Original file line numberDiff line numberDiff line change
@@ -2459,7 +2459,7 @@ impl<'test> TestCx<'test> {
24592459
}
24602460
}
24612461

2462-
fn compare_output(&self, kind: &str, actual: &str, expected: &str) -> usize {
2462+
fn compare_output(&self, stream: &str, actual: &str, expected: &str) -> usize {
24632463
let are_different = match (self.force_color_svg(), expected.find('\n'), actual.find('\n')) {
24642464
// FIXME: We ignore the first line of SVG files
24652465
// because the width parameter is non-deterministic.
@@ -2499,56 +2499,66 @@ impl<'test> TestCx<'test> {
24992499
(expected, actual)
25002500
};
25012501

2502+
// Write the actual output to a file in build/
2503+
let test_name = self.config.compare_mode.as_ref().map_or("", |m| m.to_str());
2504+
let actual_path = self
2505+
.output_base_name()
2506+
.with_extra_extension(self.revision.unwrap_or(""))
2507+
.with_extra_extension(test_name)
2508+
.with_extra_extension(stream);
2509+
2510+
if let Err(err) = fs::write(&actual_path, &actual) {
2511+
self.fatal(&format!("failed to write {stream} to `{actual_path:?}`: {err}",));
2512+
}
2513+
println!("Saved the actual {stream} to {actual_path:?}");
2514+
2515+
let expected_path =
2516+
expected_output_path(self.testpaths, self.revision, &self.config.compare_mode, stream);
2517+
25022518
if !self.config.bless {
25032519
if expected.is_empty() {
2504-
println!("normalized {}:\n{}\n", kind, actual);
2520+
println!("normalized {}:\n{}\n", stream, actual);
25052521
} else {
2506-
println!("diff of {}:\n", kind);
2507-
print!("{}", write_diff(expected, actual, 3));
2522+
println!("diff of {stream}:\n");
2523+
if let Some(diff_command) = self.config.diff_command.as_deref() {
2524+
let mut args = diff_command.split_whitespace();
2525+
let name = args.next().unwrap();
2526+
match Command::new(name)
2527+
.args(args)
2528+
.args([&expected_path, &actual_path])
2529+
.output()
2530+
{
2531+
Err(err) => {
2532+
self.fatal(&format!(
2533+
"failed to call custom diff command `{diff_command}`: {err}"
2534+
));
2535+
}
2536+
Ok(output) => {
2537+
let output = String::from_utf8_lossy_owned(output.stdout).unwrap();
2538+
print!("{output}");
2539+
}
2540+
}
2541+
} else {
2542+
print!("{}", write_diff(expected, actual, 3));
2543+
}
25082544
}
2509-
}
2510-
2511-
let mode = self.config.compare_mode.as_ref().map_or("", |m| m.to_str());
2512-
let output_file = self
2513-
.output_base_name()
2514-
.with_extra_extension(self.revision.unwrap_or(""))
2515-
.with_extra_extension(mode)
2516-
.with_extra_extension(kind);
2517-
2518-
let mut files = vec![output_file];
2519-
if self.config.bless {
2545+
} else {
25202546
// Delete non-revision .stderr/.stdout file if revisions are used.
25212547
// Without this, we'd just generate the new files and leave the old files around.
25222548
if self.revision.is_some() {
25232549
let old =
2524-
expected_output_path(self.testpaths, None, &self.config.compare_mode, kind);
2550+
expected_output_path(self.testpaths, None, &self.config.compare_mode, stream);
25252551
self.delete_file(&old);
25262552
}
2527-
files.push(expected_output_path(
2528-
self.testpaths,
2529-
self.revision,
2530-
&self.config.compare_mode,
2531-
kind,
2532-
));
2533-
}
25342553

2535-
for output_file in &files {
2536-
if actual.is_empty() {
2537-
self.delete_file(output_file);
2538-
} else if let Err(err) = fs::write(&output_file, &actual) {
2539-
self.fatal(&format!(
2540-
"failed to write {} to `{}`: {}",
2541-
kind,
2542-
output_file.display(),
2543-
err,
2544-
));
2554+
if let Err(err) = fs::write(&expected_path, &actual) {
2555+
self.fatal(&format!("failed to write {stream} to `{expected_path:?}`: {err}"));
25452556
}
2557+
println!("Blessing the {stream} of {test_name} in {expected_path:?}");
25462558
}
25472559

2548-
println!("\nThe actual {0} differed from the expected {0}.", kind);
2549-
for output_file in files {
2550-
println!("Actual {} saved to {}", kind, output_file.display());
2551-
}
2560+
println!("\nThe actual {0} differed from the expected {0}.", stream);
2561+
25522562
if self.config.bless { 0 } else { 1 }
25532563
}
25542564

0 commit comments

Comments
 (0)