@@ -45,6 +45,10 @@ pub struct Opts {
4545 #[ structopt( long = "manifest-path" , value_name = "manifest-path" ) ]
4646 manifest_path : Option < String > ,
4747
48+ /// Specify message-format: short|json|human
49+ #[ structopt( long = "message-format" , value_name = "message-format" ) ]
50+ message_format : Option < String > ,
51+
4852 /// Options passed to rustfmt
4953 // 'raw = true' to make `--` explicit.
5054 #[ structopt( name = "rustfmt_options" , raw( raw = "true" ) ) ]
@@ -100,6 +104,14 @@ fn execute() -> i32 {
100104 }
101105
102106 let strategy = CargoFmtStrategy :: from_opts ( & opts) ;
107+ let mut rustfmt_args = opts. rustfmt_options ;
108+ if let Some ( message_format) = opts. message_format {
109+ if let Err ( msg) = convert_message_format_to_rustfmt_args ( & message_format, & mut rustfmt_args)
110+ {
111+ print_usage_to_stderr ( & msg) ;
112+ return FAILURE ;
113+ }
114+ }
103115
104116 if let Some ( specified_manifest_path) = opts. manifest_path {
105117 if !specified_manifest_path. ends_with ( "Cargo.toml" ) {
@@ -110,16 +122,61 @@ fn execute() -> i32 {
110122 handle_command_status ( format_crate (
111123 verbosity,
112124 & strategy,
113- opts . rustfmt_options ,
125+ rustfmt_args ,
114126 Some ( & manifest_path) ,
115127 ) )
116128 } else {
117- handle_command_status ( format_crate (
118- verbosity,
119- & strategy,
120- opts. rustfmt_options ,
121- None ,
122- ) )
129+ handle_command_status ( format_crate ( verbosity, & strategy, rustfmt_args, None ) )
130+ }
131+ }
132+
133+ fn convert_message_format_to_rustfmt_args (
134+ message_format : & str ,
135+ rustfmt_args : & mut Vec < String > ,
136+ ) -> Result < ( ) , String > {
137+ let mut contains_emit_mode = false ;
138+ let mut contains_check = false ;
139+ let mut contains_list_files = false ;
140+ for arg in rustfmt_args. iter ( ) {
141+ if arg. starts_with ( "--emit" ) {
142+ contains_emit_mode = true ;
143+ }
144+ if arg == "--check" {
145+ contains_check = true ;
146+ }
147+ if arg == "-l" || arg == "--files-with-diff" {
148+ contains_list_files = true ;
149+ }
150+ }
151+ match message_format {
152+ "short" => {
153+ if !contains_list_files {
154+ rustfmt_args. push ( String :: from ( "-l" ) ) ;
155+ }
156+ Ok ( ( ) )
157+ }
158+ "json" => {
159+ if contains_emit_mode {
160+ return Err ( String :: from (
161+ "cannot include --emit arg when --message-format is set to json" ,
162+ ) ) ;
163+ }
164+ if contains_check {
165+ return Err ( String :: from (
166+ "cannot include --check arg when --message-format is set to json" ,
167+ ) ) ;
168+ }
169+ rustfmt_args. push ( String :: from ( "--emit" ) ) ;
170+ rustfmt_args. push ( String :: from ( "json" ) ) ;
171+ Ok ( ( ) )
172+ }
173+ "human" => Ok ( ( ) ) ,
174+ _ => {
175+ return Err ( format ! (
176+ "invalid --message-format value: {}. Allowed values are: short|json|human" ,
177+ message_format
178+ ) ) ;
179+ }
123180 }
124181}
125182
@@ -483,6 +540,8 @@ mod cargo_fmt_tests {
483540 assert_eq ! ( empty, o. packages) ;
484541 assert_eq ! ( empty, o. rustfmt_options) ;
485542 assert_eq ! ( false , o. format_all) ;
543+ assert_eq ! ( None , o. manifest_path) ;
544+ assert_eq ! ( None , o. message_format) ;
486545 }
487546
488547 #[ test]
@@ -494,6 +553,8 @@ mod cargo_fmt_tests {
494553 "p1" ,
495554 "-p" ,
496555 "p2" ,
556+ "--message-format" ,
557+ "short" ,
497558 "--" ,
498559 "--edition" ,
499560 "2018" ,
@@ -504,6 +565,7 @@ mod cargo_fmt_tests {
504565 assert_eq ! ( vec![ "p1" , "p2" ] , o. packages) ;
505566 assert_eq ! ( vec![ "--edition" , "2018" ] , o. rustfmt_options) ;
506567 assert_eq ! ( false , o. format_all) ;
568+ assert_eq ! ( Some ( String :: from( "short" ) ) , o. message_format) ;
507569 }
508570
509571 #[ test]
@@ -597,4 +659,87 @@ mod cargo_fmt_tests {
597659 . is_err( )
598660 ) ;
599661 }
662+
663+ mod convert_message_format_to_rustfmt_args_tests {
664+ use super :: * ;
665+
666+ #[ test]
667+ fn invalid_message_format ( ) {
668+ assert_eq ! (
669+ convert_message_format_to_rustfmt_args( "awesome" , & mut vec![ ] ) ,
670+ Err ( String :: from(
671+ "invalid --message-format value: awesome. Allowed values are: short|json|human"
672+ ) ) ,
673+ ) ;
674+ }
675+
676+ #[ test]
677+ fn json_message_format_and_check_arg ( ) {
678+ let mut args = vec ! [ String :: from( "--check" ) ] ;
679+ assert_eq ! (
680+ convert_message_format_to_rustfmt_args( "json" , & mut args) ,
681+ Err ( String :: from(
682+ "cannot include --check arg when --message-format is set to json"
683+ ) ) ,
684+ ) ;
685+ }
686+
687+ #[ test]
688+ fn json_message_format_and_emit_arg ( ) {
689+ let mut args = vec ! [ String :: from( "--emit" ) , String :: from( "checkstyle" ) ] ;
690+ assert_eq ! (
691+ convert_message_format_to_rustfmt_args( "json" , & mut args) ,
692+ Err ( String :: from(
693+ "cannot include --emit arg when --message-format is set to json"
694+ ) ) ,
695+ ) ;
696+ }
697+
698+ #[ test]
699+ fn json_message_format ( ) {
700+ let mut args = vec ! [ String :: from( "--edition" ) , String :: from( "2018" ) ] ;
701+ assert ! ( convert_message_format_to_rustfmt_args( "json" , & mut args) . is_ok( ) ) ;
702+ assert_eq ! (
703+ args,
704+ vec![
705+ String :: from( "--edition" ) ,
706+ String :: from( "2018" ) ,
707+ String :: from( "--emit" ) ,
708+ String :: from( "json" )
709+ ]
710+ ) ;
711+ }
712+
713+ #[ test]
714+ fn human_message_format ( ) {
715+ let exp_args = vec ! [ String :: from( "--emit" ) , String :: from( "json" ) ] ;
716+ let mut act_args = exp_args. clone ( ) ;
717+ assert ! ( convert_message_format_to_rustfmt_args( "human" , & mut act_args) . is_ok( ) ) ;
718+ assert_eq ! ( act_args, exp_args) ;
719+ }
720+
721+ #[ test]
722+ fn short_message_format ( ) {
723+ let mut args = vec ! [ String :: from( "--check" ) ] ;
724+ assert ! ( convert_message_format_to_rustfmt_args( "short" , & mut args) . is_ok( ) ) ;
725+ assert_eq ! ( args, vec![ String :: from( "--check" ) , String :: from( "-l" ) ] ) ;
726+ }
727+
728+ #[ test]
729+ fn short_message_format_included_short_list_files_flag ( ) {
730+ let mut args = vec ! [ String :: from( "--check" ) , String :: from( "-l" ) ] ;
731+ assert ! ( convert_message_format_to_rustfmt_args( "short" , & mut args) . is_ok( ) ) ;
732+ assert_eq ! ( args, vec![ String :: from( "--check" ) , String :: from( "-l" ) ] ) ;
733+ }
734+
735+ #[ test]
736+ fn short_message_format_included_long_list_files_flag ( ) {
737+ let mut args = vec ! [ String :: from( "--check" ) , String :: from( "--files-with-diff" ) ] ;
738+ assert ! ( convert_message_format_to_rustfmt_args( "short" , & mut args) . is_ok( ) ) ;
739+ assert_eq ! (
740+ args,
741+ vec![ String :: from( "--check" ) , String :: from( "--files-with-diff" ) ]
742+ ) ;
743+ }
744+ }
600745}
0 commit comments