@@ -14,12 +14,14 @@ use structopt::StructOpt;
14
14
use thiserror:: Error ;
15
15
16
16
use rustfmt_lib:: {
17
- load_config, CliOptions , Config , Edition , EmitMode , FileLines , FileName ,
18
- FormatReportFormatterBuilder , Input , Session , Verbosity ,
17
+ load_config, write_all_files, CliOptions , Config , Edition , EmitMode , EmitterConfig , FileLines ,
18
+ FileName , FormatReport , FormatReportFormatterBuilder , Input , RustFormatterBuilder , Session ,
19
+ Verbosity ,
19
20
} ;
20
21
21
22
fn main ( ) {
22
23
env_logger:: init ( ) ;
24
+
23
25
let opt: Opt = Opt :: from_args ( ) ;
24
26
25
27
let exit_code = match execute ( opt) {
@@ -127,6 +129,32 @@ struct Opt {
127
129
files : Vec < PathBuf > ,
128
130
}
129
131
132
+ impl Opt {
133
+ fn verbosity ( & self ) -> Verbosity {
134
+ if self . verbose {
135
+ Verbosity :: Verbose
136
+ } else if self . quiet {
137
+ Verbosity :: Quiet
138
+ } else {
139
+ Verbosity :: Normal
140
+ }
141
+ }
142
+
143
+ fn emitter_config ( & self , default_emit_mode : EmitMode ) -> EmitterConfig {
144
+ let emit_mode = if self . check {
145
+ EmitMode :: Diff
146
+ } else {
147
+ self . emit . map_or ( default_emit_mode, Emit :: to_emit_mode)
148
+ } ;
149
+ EmitterConfig {
150
+ emit_mode,
151
+ verbosity : self . verbosity ( ) ,
152
+ print_filename : self . files_with_diff ,
153
+ ..EmitterConfig :: default ( )
154
+ }
155
+ }
156
+ }
157
+
130
158
#[ derive( Debug , Clone ) ]
131
159
struct InlineConfig ( HashMap < String , String > , bool /* is help */ ) ;
132
160
@@ -307,29 +335,13 @@ impl From<IoError> for OperationError {
307
335
308
336
impl CliOptions for Opt {
309
337
fn apply_to ( & self , config : & mut Config ) {
310
- if self . verbose {
311
- config. set ( ) . verbose ( Verbosity :: Verbose ) ;
312
- } else if self . quiet {
313
- config. set ( ) . verbose ( Verbosity :: Quiet ) ;
314
- }
315
338
config. set ( ) . file_lines ( self . file_lines . clone ( ) ) ;
316
- if self . recursive {
317
- config. set ( ) . recursive ( true ) ;
318
- }
319
339
if self . error_on_unformatted {
320
340
config. set ( ) . error_on_unformatted ( true ) ;
321
341
}
322
342
if let Some ( ref edition) = self . edition {
323
343
config. set ( ) . edition ( ( * edition) . clone ( ) ) ;
324
344
}
325
- if self . check {
326
- config. set ( ) . emit_mode ( EmitMode :: Diff ) ;
327
- } else if let Some ( emit) = self . emit {
328
- config. set ( ) . emit_mode ( emit. to_emit_mode ( ) ) ;
329
- }
330
- if self . files_with_diff {
331
- config. set ( ) . print_misformatted_file_names ( true ) ;
332
- }
333
345
if let Some ( ref inline_configs) = self . inline_config {
334
346
for inline_config in inline_configs {
335
347
for ( k, v) in & inline_config. 0 {
@@ -392,17 +404,8 @@ fn format_string(input: String, opt: Opt) -> Result<i32> {
392
404
// try to read config from local directory
393
405
let ( mut config, _) = load_config ( Some ( Path :: new ( "." ) ) , Some ( & opt) ) ?;
394
406
395
- if opt. check {
396
- config. set ( ) . emit_mode ( EmitMode :: Diff ) ;
397
- } else {
398
- config
399
- . set ( )
400
- . emit_mode ( opt. emit . map_or ( EmitMode :: Stdout , Emit :: to_emit_mode) ) ;
401
- }
402
- config. set ( ) . verbose ( Verbosity :: Quiet ) ;
403
-
404
407
// parse file_lines
405
- config. set ( ) . file_lines ( opt. file_lines ) ;
408
+ config. set ( ) . file_lines ( opt. file_lines . clone ( ) ) ;
406
409
for f in config. file_lines ( ) . files ( ) {
407
410
match * f {
408
411
FileName :: Stdin => { }
@@ -411,15 +414,20 @@ fn format_string(input: String, opt: Opt) -> Result<i32> {
411
414
}
412
415
413
416
let out = & mut stdout ( ) ;
414
- let mut session = Session :: new ( config, Some ( out) ) ;
415
- format_and_emit_report ( & mut session, Input :: Text ( input) ) ;
416
-
417
- let exit_code = if session. has_operational_errors ( ) || session. has_parsing_errors ( ) {
418
- 1
419
- } else {
420
- 0
421
- } ;
422
- Ok ( exit_code)
417
+ let mut session = RustFormatterBuilder :: default ( )
418
+ . recursive ( opt. recursive )
419
+ . verbosity ( Verbosity :: Quiet )
420
+ . build ( ) ;
421
+ let mut format_report = FormatReport :: new ( ) ;
422
+ // FIXME: Add error handling.
423
+ format_and_emit_report (
424
+ & mut session,
425
+ Input :: Text ( input) ,
426
+ & config,
427
+ & mut format_report,
428
+ ) ;
429
+ let has_diff = write_all_files ( format_report, out, opt. emitter_config ( EmitMode :: Stdout ) ) ?;
430
+ Ok ( if opt. check && has_diff { 1 } else { 0 } )
423
431
}
424
432
425
433
enum FileConfig {
@@ -484,21 +492,24 @@ fn format(opt: Opt) -> Result<i32> {
484
492
485
493
let ( config, config_path) = load_config ( None , Some ( & opt) ) ?;
486
494
487
- if config . verbose ( ) == Verbosity :: Verbose {
495
+ if opt . verbose {
488
496
if let Some ( path) = config_path. as_ref ( ) {
489
497
println ! ( "Using rustfmt config file {}" , path. display( ) ) ;
490
498
}
491
499
}
492
500
493
- let out = & mut stdout ( ) ;
494
- let mut session = Session :: new ( config, Some ( out) ) ;
501
+ let mut session = RustFormatterBuilder :: default ( )
502
+ . recursive ( opt. recursive )
503
+ . verbosity ( opt. verbosity ( ) )
504
+ . build ( ) ;
505
+ let mut format_report = FormatReport :: new ( ) ;
495
506
496
507
for pair in FileConfigPairIter :: new ( & opt, config_path. is_some ( ) ) {
497
508
let file = pair. file ;
498
509
499
510
if let FileConfig :: Local ( local_config, config_path) = pair. config {
500
511
if let Some ( path) = config_path {
501
- if local_config . verbose ( ) == Verbosity :: Verbose {
512
+ if opt . verbose {
502
513
println ! (
503
514
"Using rustfmt config file {} for {}" ,
504
515
path. display( ) ,
@@ -507,54 +518,50 @@ fn format(opt: Opt) -> Result<i32> {
507
518
}
508
519
}
509
520
510
- session. override_config ( local_config, |sess| {
511
- format_and_emit_report ( sess, Input :: File ( file. to_path_buf ( ) ) )
512
- } ) ;
521
+ format_and_emit_report (
522
+ & mut session,
523
+ Input :: File ( file. to_path_buf ( ) ) ,
524
+ & local_config,
525
+ & mut format_report,
526
+ ) ;
513
527
} else {
514
- format_and_emit_report ( & mut session, Input :: File ( file. to_path_buf ( ) ) ) ;
528
+ format_and_emit_report (
529
+ & mut session,
530
+ Input :: File ( file. to_path_buf ( ) ) ,
531
+ & config,
532
+ & mut format_report,
533
+ ) ;
515
534
}
516
535
}
517
536
518
- let exit_code = if session. has_operational_errors ( )
519
- || session. has_parsing_errors ( )
520
- || ( ( session. has_diff ( ) || session. has_check_errors ( ) ) && opt. check )
521
- {
522
- 1
523
- } else {
524
- 0
525
- } ;
526
- Ok ( exit_code)
537
+ if format_report. has_errors ( ) {
538
+ eprintln ! (
539
+ "{}" ,
540
+ FormatReportFormatterBuilder :: new( & format_report)
541
+ . enable_colors( true )
542
+ . build( )
543
+ ) ;
544
+ }
545
+
546
+ let out = & mut stdout ( ) ;
547
+ let has_diff = write_all_files ( format_report, out, opt. emitter_config ( EmitMode :: Files ) ) ?;
548
+
549
+ Ok ( if opt. check && has_diff { 1 } else { 0 } )
527
550
}
528
551
529
- fn format_and_emit_report < T : Write > ( session : & mut Session < ' _ , T > , input : Input ) {
530
- match session. format ( input) {
552
+ fn format_and_emit_report (
553
+ session : & mut Session ,
554
+ input : Input ,
555
+ config : & Config ,
556
+ format_report : & mut FormatReport ,
557
+ ) {
558
+ match session. format ( input, config) {
531
559
Ok ( report) => {
532
- if report. has_warnings ( ) {
533
- eprintln ! (
534
- "{}" ,
535
- FormatReportFormatterBuilder :: new( & report)
536
- . enable_colors( should_print_with_colors( session) )
537
- . build( )
538
- ) ;
539
- }
540
- }
541
- Err ( msg) => {
542
- eprintln ! ( "Error writing files: {}" , msg) ;
543
- session. add_operational_error ( ) ;
560
+ format_report. merge ( report) ;
544
561
}
545
- }
546
- }
547
-
548
- fn should_print_with_colors < T : Write > ( session : & mut Session < ' _ , T > ) -> bool {
549
- match term:: stderr ( ) {
550
- Some ( ref t)
551
- if session. config . color ( ) . use_colored_tty ( )
552
- && t. supports_color ( )
553
- && t. supports_attr ( term:: Attr :: Bold ) =>
554
- {
555
- true
562
+ Err ( err) => {
563
+ eprintln ! ( "{}" , err) ;
556
564
}
557
- _ => false ,
558
565
}
559
566
}
560
567
@@ -567,31 +574,6 @@ mod test {
567
574
let _ = env_logger:: builder ( ) . is_test ( true ) . try_init ( ) ;
568
575
}
569
576
570
- #[ test]
571
- fn format_lines_errors_are_reported ( ) {
572
- init_log ( ) ;
573
- let long_identifier = String :: from_utf8 ( vec ! [ b'a' ; 239 ] ) . unwrap ( ) ;
574
- let input = Input :: Text ( format ! ( "fn {}() {{}}" , long_identifier) ) ;
575
- let mut config = Config :: default ( ) ;
576
- config. set ( ) . error_on_line_overflow ( true ) ;
577
- let mut session = Session :: < io:: Stdout > :: new ( config, None ) ;
578
- session. format ( input) . unwrap ( ) ;
579
- assert ! ( session. has_formatting_errors( ) ) ;
580
- }
581
-
582
- #[ test]
583
- fn format_lines_errors_are_reported_with_tabs ( ) {
584
- init_log ( ) ;
585
- let long_identifier = String :: from_utf8 ( vec ! [ b'a' ; 97 ] ) . unwrap ( ) ;
586
- let input = Input :: Text ( format ! ( "fn a() {{\n \t {}\n }}" , long_identifier) ) ;
587
- let mut config = Config :: default ( ) ;
588
- config. set ( ) . error_on_line_overflow ( true ) ;
589
- config. set ( ) . hard_tabs ( true ) ;
590
- let mut session = Session :: < io:: Stdout > :: new ( config, None ) ;
591
- session. format ( input) . unwrap ( ) ;
592
- assert ! ( session. has_formatting_errors( ) ) ;
593
- }
594
-
595
577
struct TempFile {
596
578
path : PathBuf ,
597
579
}
@@ -704,7 +686,7 @@ mod test {
704
686
let output = child
705
687
. wait_with_output ( )
706
688
. expect ( "Failed to wait on rustfmt child" ) ;
707
- assert ! ( output. status. success( ) ) ;
689
+ assert ! ( ! output. status. success( ) ) ;
708
690
assert_eq ! ( std:: str :: from_utf8( & output. stdout) . unwrap( ) , "stdin\n " ) ;
709
691
}
710
692
0 commit comments