Skip to content

Refactor for 2.0 #4168

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
May 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 1 addition & 22 deletions Configurations.md
Original file line number Diff line number Diff line change
Expand Up @@ -311,14 +311,6 @@ By default this option is set as a percentage of [`max_width`](#max_width) provi

See also [`max_width`](#max_width) and [`width_heuristics`](#width_heuristics)

## `color`

Whether to use colored output or not.

- **Default value**: `"Auto"`
- **Possible values**: "Auto", "Always", "Never"
- **Stable**: No (tracking issue: [#3385](https://github.com/rust-lang/rustfmt/issues/3385))

## `combine_control_expr`

Combine control expressions with function calls.
Expand Down Expand Up @@ -2629,17 +2621,4 @@ Break comments to fit on the line
// magna aliqua. Ut enim ad minim veniam, quis nostrud
// exercitation ullamco laboris nisi ut aliquip ex ea
// commodo consequat.
```

# Internal Options

## `emit_mode`

Internal option

## `print_misformatted_file_names`

Internal option, use `-l` or `--files-with-diff`

## `recursive`
Internal option, use `-r` or `--recursive`
```
202 changes: 74 additions & 128 deletions rustfmt-core/rustfmt-bin/src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ use structopt::StructOpt;
use thiserror::Error;

use rustfmt_lib::{
load_config, CliOptions, Config, Edition, EmitMode, FileLines, FileName,
FormatReportFormatterBuilder, Input, Session, Verbosity,
emitter::{emit_format_report, EmitMode, EmitterConfig, Verbosity},
format_inputs, load_config, CliOptions, Config, Edition, FileLines, FileName,
FormatReportFormatterBuilder, Input, OperationSetting,
};

fn main() {
env_logger::init();

let opt: Opt = Opt::from_args();

let exit_code = match execute(opt) {
Expand Down Expand Up @@ -127,6 +129,32 @@ struct Opt {
files: Vec<PathBuf>,
}

impl Opt {
fn verbosity(&self) -> Verbosity {
if self.verbose {
Verbosity::Verbose
} else if self.quiet {
Verbosity::Quiet
} else {
Verbosity::Normal
}
}

fn emitter_config(&self, default_emit_mode: EmitMode) -> EmitterConfig {
let emit_mode = if self.check {
EmitMode::Diff
} else {
self.emit.map_or(default_emit_mode, Emit::to_emit_mode)
};
EmitterConfig {
emit_mode,
verbosity: self.verbosity(),
print_filename: self.files_with_diff,
..EmitterConfig::default()
}
}
}

#[derive(Debug, Clone)]
struct InlineConfig(HashMap<String, String>, bool /* is help */);

Expand Down Expand Up @@ -307,29 +335,13 @@ impl From<IoError> for OperationError {

impl CliOptions for Opt {
fn apply_to(&self, config: &mut Config) {
if self.verbose {
config.set().verbose(Verbosity::Verbose);
} else if self.quiet {
config.set().verbose(Verbosity::Quiet);
}
config.set().file_lines(self.file_lines.clone());
if self.recursive {
config.set().recursive(true);
}
if self.error_on_unformatted {
config.set().error_on_unformatted(true);
}
if let Some(ref edition) = self.edition {
config.set().edition((*edition).clone());
}
if self.check {
config.set().emit_mode(EmitMode::Diff);
} else if let Some(emit) = self.emit {
config.set().emit_mode(emit.to_emit_mode());
}
if self.files_with_diff {
config.set().print_misformatted_file_names(true);
}
if let Some(ref inline_configs) = self.inline_config {
for inline_config in inline_configs {
for (k, v) in &inline_config.0 {
Expand Down Expand Up @@ -392,17 +404,8 @@ fn format_string(input: String, opt: Opt) -> Result<i32> {
// try to read config from local directory
let (mut config, _) = load_config(Some(Path::new(".")), Some(&opt))?;

if opt.check {
config.set().emit_mode(EmitMode::Diff);
} else {
config
.set()
.emit_mode(opt.emit.map_or(EmitMode::Stdout, Emit::to_emit_mode));
}
config.set().verbose(Verbosity::Quiet);

// parse file_lines
config.set().file_lines(opt.file_lines);
config.set().file_lines(opt.file_lines.clone());
for f in config.file_lines().files() {
match *f {
FileName::Stdin => {}
Expand All @@ -411,15 +414,13 @@ fn format_string(input: String, opt: Opt) -> Result<i32> {
}

let out = &mut stdout();
let mut session = Session::new(config, Some(out));
format_and_emit_report(&mut session, Input::Text(input));

let exit_code = if session.has_operational_errors() || session.has_parsing_errors() {
1
} else {
0
let setting = OperationSetting {
recursive: opt.recursive,
verbosity: Verbosity::Quiet,
};
Ok(exit_code)
let report = rustfmt_lib::format(Input::Text(input), &config, setting)?;
let has_diff = emit_format_report(report, out, opt.emitter_config(EmitMode::Stdout))?;
Ok(if opt.check && has_diff { 1 } else { 0 })
}

enum FileConfig {
Expand Down Expand Up @@ -482,80 +483,50 @@ fn format(opt: Opt) -> Result<i32> {
return Err(format_err!("Error: `{}` is a directory", dir.display()));
}

let (config, config_path) = load_config(None, Some(&opt))?;
let (default_config, config_path) = load_config(None, Some(&opt))?;

if config.verbose() == Verbosity::Verbose {
if opt.verbose {
if let Some(path) = config_path.as_ref() {
println!("Using rustfmt config file {}", path.display());
}
}

let out = &mut stdout();
let mut session = Session::new(config, Some(out));

for pair in FileConfigPairIter::new(&opt, config_path.is_some()) {
let file = pair.file;

if let FileConfig::Local(local_config, config_path) = pair.config {
if let Some(path) = config_path {
if local_config.verbose() == Verbosity::Verbose {
println!(
"Using rustfmt config file {} for {}",
path.display(),
file.display()
);
}
}

session.override_config(local_config, |sess| {
format_and_emit_report(sess, Input::File(file.to_path_buf()))
});
} else {
format_and_emit_report(&mut session, Input::File(file.to_path_buf()));
}
}

let exit_code = if session.has_operational_errors()
|| session.has_parsing_errors()
|| ((session.has_diff() || session.has_check_errors()) && opt.check)
{
1
} else {
0
let setting = OperationSetting {
recursive: opt.recursive,
verbosity: opt.verbosity(),
};
Ok(exit_code)
}

fn format_and_emit_report<T: Write>(session: &mut Session<'_, T>, input: Input) {
match session.format(input) {
Ok(report) => {
if report.has_warnings() {
eprintln!(
"{}",
FormatReportFormatterBuilder::new(&report)
.enable_colors(should_print_with_colors(session))
.build()
);
}
}
Err(msg) => {
eprintln!("Error writing files: {}", msg);
session.add_operational_error();
}
}
}

fn should_print_with_colors<T: Write>(session: &mut Session<'_, T>) -> bool {
match term::stderr() {
Some(ref t)
if session.config.color().use_colored_tty()
&& t.supports_color()
&& t.supports_attr(term::Attr::Bold) =>
{
true
}
_ => false,
}
let inputs = FileConfigPairIter::new(&opt, config_path.is_some()).collect::<Vec<_>>();
let format_report = format_inputs(
inputs.iter().map(|p| {
(
Input::File(p.file.to_path_buf()),
if let FileConfig::Local(ref config, _) = p.config {
config
} else {
&default_config
},
)
}),
setting,
)?;

if format_report.has_errors() {
eprintln!(
"{}",
FormatReportFormatterBuilder::new(&format_report)
.enable_colors(true)
.build()
);
}

let has_diff = emit_format_report(
format_report,
&mut stdout(),
opt.emitter_config(EmitMode::Files),
)?;

Ok(if opt.check && has_diff { 1 } else { 0 })
}

#[cfg(test)]
Expand All @@ -567,31 +538,6 @@ mod test {
let _ = env_logger::builder().is_test(true).try_init();
}

#[test]
fn format_lines_errors_are_reported() {
init_log();
let long_identifier = String::from_utf8(vec![b'a'; 239]).unwrap();
let input = Input::Text(format!("fn {}() {{}}", long_identifier));
let mut config = Config::default();
config.set().error_on_line_overflow(true);
let mut session = Session::<io::Stdout>::new(config, None);
session.format(input).unwrap();
assert!(session.has_formatting_errors());
}

#[test]
fn format_lines_errors_are_reported_with_tabs() {
init_log();
let long_identifier = String::from_utf8(vec![b'a'; 97]).unwrap();
let input = Input::Text(format!("fn a() {{\n\t{}\n}}", long_identifier));
let mut config = Config::default();
config.set().error_on_line_overflow(true);
config.set().hard_tabs(true);
let mut session = Session::<io::Stdout>::new(config, None);
session.format(input).unwrap();
assert!(session.has_formatting_errors());
}

struct TempFile {
path: PathBuf,
}
Expand Down Expand Up @@ -704,7 +650,7 @@ mod test {
let output = child
.wait_with_output()
.expect("Failed to wait on rustfmt child");
assert!(output.status.success());
assert!(!output.status.success());
assert_eq!(std::str::from_utf8(&output.stdout).unwrap(), "stdin\n");
}

Expand Down
26 changes: 18 additions & 8 deletions rustfmt-core/rustfmt-bin/src/git-rustfmt/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ use std::process::Command;

use structopt::StructOpt;

use rustfmt_lib::{load_config, CliOptions, FormatReportFormatterBuilder, Input, Session};
use rustfmt_lib::{
emitter::{emit_format_report, EmitterConfig},
format, load_config, CliOptions, FormatReportFormatterBuilder, Input, OperationSetting,
};

fn prune_files(files: Vec<&str>) -> Vec<&str> {
let prefixes: Vec<_> = files
Expand Down Expand Up @@ -56,20 +59,27 @@ fn get_files(input: &str) -> Vec<&str> {
fn fmt_files(files: &[&str]) -> i32 {
let (config, _) =
load_config::<NullOptions>(Some(Path::new(".")), None).expect("couldn't load config");
let setting = OperationSetting::default();

let mut exit_code = 0;
let mut out = stdout();
let mut session = Session::new(config, Some(&mut out));
for file in files {
let report = session.format(Input::File(PathBuf::from(file))).unwrap();
if report.has_warnings() {
let report = match format(Input::File(PathBuf::from(file)), &config, setting) {
Ok(report) => report,
Err(e) => {
eprintln!("{}", e);
return 1;
}
};
if report.has_errors() {
eprintln!("{}", FormatReportFormatterBuilder::new(&report).build());
}
if !session.has_no_errors() {
exit_code = 1;
if let Err(e) = emit_format_report(report, &mut out, EmitterConfig::default()) {
eprintln!("{}", e);
return 1;
}
}
exit_code

0
}

struct NullOptions;
Expand Down
10 changes: 5 additions & 5 deletions rustfmt-core/rustfmt-bin/tests/rustfmt/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ fn inline_config() {
"--print-config",
"current",
".",
"--config=color=Never,edition=2018"
"--config=max_width=50,edition=2018"
],
contains("color = \"Never\"") && contains("edition = \"2018\"")
contains("max_width = 50") && contains("edition = \"2018\"")
);

// multiple overriding invocations
Expand All @@ -89,11 +89,11 @@ fn inline_config() {
"current",
".",
"--config",
"color=never,edition=2018",
"max_width=80,edition=2018",
"--config",
"color=always,format_strings=true"
"max_width=60,format_strings=true"
],
contains("color = \"Always\"")
contains("max_width = 60")
&& contains("edition = \"2018\"")
&& contains("format_strings = true")
);
Expand Down
Loading