Skip to content

Commit c26c0e5

Browse files
calebcartwrighttopecongiro
authored andcommitted
feat: add support for --message-format option (rust-lang#3752)
1 parent ac940c7 commit c26c0e5

File tree

1 file changed

+152
-7
lines changed

1 file changed

+152
-7
lines changed

src/cargo-fmt/main.rs

+152-7
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)