add new flag to list names of misformatted files (#3747)

This commit is contained in:
Caleb Cartwright 2019-08-18 21:04:40 -05:00 committed by Seiichi Uchida
parent 73847d3986
commit 62432fe31b
6 changed files with 121 additions and 9 deletions

View File

@ -2445,3 +2445,7 @@ Internal option
## `make_backup`
Internal option, use `--backup`
## `print_misformatted_file_names`
Internal option, use `-l` or `--files-with-diff`

View File

@ -126,6 +126,12 @@ fn make_opts() -> Options {
`current` writes to stdout current config as if formatting the file at PATH.",
"[default|minimal|current] PATH",
);
opts.optflag(
"l",
"files-with-diff",
"Prints the names of mismatched files that were formatted. Prints the names of \
files that would be formated when used with `--check` mode. ",
);
if is_nightly {
opts.optflag(
@ -480,6 +486,7 @@ struct GetOptsOptions {
file_lines: FileLines, // Default is all lines in all files.
unstable_features: bool,
error_on_unformatted: Option<bool>,
print_misformatted_file_names: bool,
}
impl GetOptsOptions {
@ -547,6 +554,10 @@ impl GetOptsOptions {
options.backup = true;
}
if matches.opt_present("files-with-diff") {
options.print_misformatted_file_names = true;
}
if !rust_nightly {
if !STABLE_EMIT_MODES.contains(&options.emit_mode) {
return Err(format_err!(
@ -610,6 +621,9 @@ impl CliOptions for GetOptsOptions {
if let Some(color) = self.color {
config.set().color(color);
}
if self.print_misformatted_file_names {
config.set().print_misformatted_file_names(true);
}
}
fn config_path(&self) -> Option<&Path> {

View File

@ -152,6 +152,9 @@ create_config! {
emit_mode: EmitMode, EmitMode::Files, false,
"What emit Mode to use when none is supplied";
make_backup: bool, false, false, "Backup changed files";
print_misformatted_file_names: bool, false, true,
"Prints the names of mismatched files that were formatted. Prints the names of \
files that would be formated when used with `--check` mode. ";
}
impl PartialConfig {
@ -161,6 +164,7 @@ impl PartialConfig {
cloned.file_lines = None;
cloned.verbose = None;
cloned.width_heuristics = None;
cloned.print_misformatted_file_names = None;
::toml::to_string(&cloned).map_err(|e| format!("Could not output config: {}", e))
}

View File

@ -15,7 +15,7 @@ impl DiffEmitter {
impl Emitter for DiffEmitter {
fn emit_formatted_file(
&mut self,
_output: &mut dyn Write,
output: &mut dyn Write,
FormattedFile {
filename,
original_text,
@ -25,11 +25,86 @@ impl Emitter for DiffEmitter {
const CONTEXT_SIZE: usize = 3;
let mismatch = make_diff(&original_text, formatted_text, CONTEXT_SIZE);
let has_diff = !mismatch.is_empty();
print_diff(
mismatch,
|line_num| format!("Diff in {} at line {}:", filename, line_num),
&self.config,
);
if has_diff {
if self.config.print_misformatted_file_names() {
writeln!(output, "{}", ensure_real_path(filename).display())?;
} else {
print_diff(
mismatch,
|line_num| format!("Diff in {} at line {}:", filename, line_num),
&self.config,
);
}
}
return Ok(EmitterResult { has_diff });
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::config::Config;
use crate::FileName;
use std::path::PathBuf;
#[test]
fn does_not_print_when_no_files_reformatted() {
let mut writer = Vec::new();
let config = Config::default();
let mut emitter = DiffEmitter::new(config);
let result = emitter
.emit_formatted_file(
&mut writer,
FormattedFile {
filename: &FileName::Real(PathBuf::from("src/lib.rs")),
original_text: "fn empty() {}\n",
formatted_text: "fn empty() {}\n",
},
)
.unwrap();
assert_eq!(result.has_diff, false);
assert_eq!(writer.len(), 0);
}
#[test]
fn prints_file_names_when_config_is_enabled() {
let bin_file = "src/bin.rs";
let bin_original = "fn main() {\nprintln!(\"Hello, world!\");\n}";
let bin_formatted = "fn main() {\n println!(\"Hello, world!\");\n}";
let lib_file = "src/lib.rs";
let lib_original = "fn greet() {\nprintln!(\"Greetings!\");\n}";
let lib_formatted = "fn greet() {\n println!(\"Greetings!\");\n}";
let mut writer = Vec::new();
let mut config = Config::default();
config.set().print_misformatted_file_names(true);
let mut emitter = DiffEmitter::new(config);
let _ = emitter
.emit_formatted_file(
&mut writer,
FormattedFile {
filename: &FileName::Real(PathBuf::from(bin_file)),
original_text: bin_original,
formatted_text: bin_formatted,
},
)
.unwrap();
let _ = emitter
.emit_formatted_file(
&mut writer,
FormattedFile {
filename: &FileName::Real(PathBuf::from(lib_file)),
original_text: lib_original,
formatted_text: lib_formatted,
},
)
.unwrap();
assert_eq!(
String::from_utf8(writer).unwrap(),
format!("{}\n{}\n", bin_file, lib_file),
)
}
}

View File

@ -2,12 +2,22 @@ use super::*;
use std::fs;
#[derive(Debug, Default)]
pub(crate) struct FilesEmitter;
pub(crate) struct FilesEmitter {
print_misformatted_file_names: bool,
}
impl FilesEmitter {
pub(crate) fn new(print_misformatted_file_names: bool) -> Self {
Self {
print_misformatted_file_names,
}
}
}
impl Emitter for FilesEmitter {
fn emit_formatted_file(
&mut self,
_output: &mut dyn Write,
output: &mut dyn Write,
FormattedFile {
filename,
original_text,
@ -18,6 +28,9 @@ impl Emitter for FilesEmitter {
let filename = ensure_real_path(filename);
if original_text != formatted_text {
fs::write(filename, formatted_text)?;
if self.print_misformatted_file_names {
writeln!(output, "{}", filename.display())?;
}
}
Ok(EmitterResult::default())
}

View File

@ -480,7 +480,9 @@ pub(crate) fn create_emitter<'a>(config: &Config) -> Box<dyn Emitter + 'a> {
EmitMode::Files if config.make_backup() => {
Box::new(emitter::FilesWithBackupEmitter::default())
}
EmitMode::Files => Box::new(emitter::FilesEmitter::default()),
EmitMode::Files => Box::new(emitter::FilesEmitter::new(
config.print_misformatted_file_names(),
)),
EmitMode::Stdout | EmitMode::Coverage => {
Box::new(emitter::StdoutEmitter::new(config.verbose()))
}