@@ -13,6 +13,7 @@ use crate::header::TestProps;
1313use crate :: json;
1414use crate :: util:: get_pointer_width;
1515use crate :: util:: { logv, PathBufExt } ;
16+ use crate :: ColorConfig ;
1617use regex:: { Captures , Regex } ;
1718use rustfix:: { apply_suggestions, get_suggestions_from_json, Filter } ;
1819
@@ -2440,37 +2441,92 @@ impl<'test> TestCx<'test> {
24402441 }
24412442 } )
24422443 } ;
2443- let mut diff = Command :: new ( "diff" ) ;
2444- // diff recursively, showing context, and excluding .css files
2445- diff. args ( & [ "-u" , "-r" , "-x" , "*.css" ] ) . args ( & [ & compare_dir, out_dir] ) ;
24462444
2447- let output = if let Some ( pager) = pager {
2448- let diff_pid = diff. stdout ( Stdio :: piped ( ) ) . spawn ( ) . expect ( "failed to run `diff`" ) ;
2445+ let diff_filename = format ! ( "build/tmp/rustdoc-compare-{}.diff" , std:: process:: id( ) ) ;
2446+
2447+ {
2448+ let mut diff_output = File :: create ( & diff_filename) . unwrap ( ) ;
2449+ for entry in walkdir:: WalkDir :: new ( out_dir) {
2450+ let entry = entry. expect ( "failed to read file" ) ;
2451+ let extension = entry. path ( ) . extension ( ) . and_then ( |p| p. to_str ( ) ) ;
2452+ if entry. file_type ( ) . is_file ( )
2453+ && ( extension == Some ( "html" . into ( ) ) || extension == Some ( "js" . into ( ) ) )
2454+ {
2455+ let expected_path =
2456+ compare_dir. join ( entry. path ( ) . strip_prefix ( & out_dir) . unwrap ( ) ) ;
2457+ let expected =
2458+ if let Ok ( s) = std:: fs:: read ( & expected_path) { s } else { continue } ;
2459+ let actual_path = entry. path ( ) ;
2460+ let actual = std:: fs:: read ( & actual_path) . unwrap ( ) ;
2461+ diff_output
2462+ . write_all ( & unified_diff:: diff (
2463+ & expected,
2464+ & expected_path. to_string_lossy ( ) ,
2465+ & actual,
2466+ & actual_path. to_string_lossy ( ) ,
2467+ 3 ,
2468+ ) )
2469+ . unwrap ( ) ;
2470+ }
2471+ }
2472+ }
2473+
2474+ match self . config . color {
2475+ ColorConfig :: AlwaysColor => colored:: control:: set_override ( true ) ,
2476+ ColorConfig :: NeverColor => colored:: control:: set_override ( false ) ,
2477+ _ => { }
2478+ }
2479+
2480+ if let Some ( pager) = pager {
24492481 let pager = pager. trim ( ) ;
24502482 if self . config . verbose {
24512483 eprintln ! ( "using pager {}" , pager) ;
24522484 }
24532485 let output = Command :: new ( pager)
24542486 // disable paging; we want this to be non-interactive
24552487 . env ( "PAGER" , "" )
2456- . stdin ( diff_pid . stdout . unwrap ( ) )
2488+ . stdin ( File :: open ( & diff_filename ) . unwrap ( ) )
24572489 // Capture output and print it explicitly so it will in turn be
24582490 // captured by libtest.
24592491 . output ( )
24602492 . unwrap ( ) ;
24612493 assert ! ( output. status. success( ) ) ;
2462- output
2494+ println ! ( "{}" , String :: from_utf8_lossy( & output. stdout) ) ;
2495+ eprintln ! ( "{}" , String :: from_utf8_lossy( & output. stderr) ) ;
24632496 } else {
2464- eprintln ! ( "warning: no pager configured, falling back to `diff --color`" ) ;
2497+ use colored:: Colorize ;
2498+ eprintln ! ( "warning: no pager configured, falling back to unified diff" ) ;
24652499 eprintln ! (
24662500 "help: try configuring a git pager (e.g. `delta`) with `git config --global core.pager delta`"
24672501 ) ;
2468- let output = diff. arg ( "--color" ) . output ( ) . unwrap ( ) ;
2469- assert ! ( output. status. success( ) || output. status. code( ) == Some ( 1 ) ) ;
2470- output
2502+ let mut out = io:: stdout ( ) ;
2503+ let mut diff = BufReader :: new ( File :: open ( & diff_filename) . unwrap ( ) ) ;
2504+ let mut line = Vec :: new ( ) ;
2505+ loop {
2506+ line. truncate ( 0 ) ;
2507+ match diff. read_until ( b'\n' , & mut line) {
2508+ Ok ( 0 ) => break ,
2509+ Ok ( _) => { }
2510+ Err ( e) => eprintln ! ( "ERROR: {:?}" , e) ,
2511+ }
2512+ match String :: from_utf8 ( line. clone ( ) ) {
2513+ Ok ( line) => {
2514+ if line. starts_with ( "+" ) {
2515+ write ! ( & mut out, "{}" , line. green( ) ) . unwrap ( ) ;
2516+ } else if line. starts_with ( "-" ) {
2517+ write ! ( & mut out, "{}" , line. red( ) ) . unwrap ( ) ;
2518+ } else if line. starts_with ( "@" ) {
2519+ write ! ( & mut out, "{}" , line. blue( ) ) . unwrap ( ) ;
2520+ } else {
2521+ out. write_all ( line. as_bytes ( ) ) . unwrap ( ) ;
2522+ }
2523+ }
2524+ Err ( _) => {
2525+ write ! ( & mut out, "{}" , String :: from_utf8_lossy( & line) . reversed( ) ) . unwrap ( ) ;
2526+ }
2527+ }
2528+ }
24712529 } ;
2472- println ! ( "{}" , String :: from_utf8_lossy( & output. stdout) ) ;
2473- eprintln ! ( "{}" , String :: from_utf8_lossy( & output. stderr) ) ;
24742530 }
24752531
24762532 fn run_rustdoc_json_test ( & self ) {
0 commit comments