diff --git a/Cargo.lock b/Cargo.lock index 113a79c568ed..a56ecda12140 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -78,7 +78,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cargo_metadata" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -607,7 +607,7 @@ dependencies = [ "assert_cli 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "bytecount 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "cargo_metadata 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo_metadata 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "derive-new 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -864,7 +864,7 @@ dependencies = [ "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum bytecount 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f861d9ce359f56dbcb6e0c2a1cb84e52ad732cadb57b806adeb3c7668caccbd8" "checksum byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90492c5858dd7d2e78691cfb89f90d273a2800fc11d98f60786e5d87e2f83781" -"checksum cargo_metadata 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d6809b327f87369e6f3651efd2c5a96c49847a3ed2559477ecba79014751ee1" +"checksum cargo_metadata 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1aaa1a9856ae2d188340526d0986feb6899c9ad11c5dfd73453c784fed6e373d" "checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16" "checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" diff --git a/src/bin/main.rs b/src/bin/main.rs index 91260a199c41..204efa19541c 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -25,8 +25,8 @@ use failure::err_msg; use getopts::{Matches, Options}; use rustfmt::{ - load_config, CliOptions, Color, Config, EmitMode, ErrorKind, FileLines, FileName, Input, - Session, Verbosity, + load_config, CliOptions, Color, Config, Edition, EmitMode, ErrorKind, FileLines, FileName, + Input, Session, Verbosity, }; fn main() { @@ -102,6 +102,7 @@ fn make_opts() -> Options { found reverts to the input file path", "[Path for the configuration file]", ); + opts.optopt("", "edition", "Rust edition to use", "[2015|2018]"); opts.optopt( "", "color", @@ -437,6 +438,7 @@ struct GetOptsOptions { emit_mode: EmitMode, backup: bool, check: bool, + edition: Edition, color: Option, file_lines: FileLines, // Default is all lines in all files. unstable_features: bool, @@ -496,11 +498,12 @@ impl GetOptsOptions { if options.check { return Err(format_err!("Invalid to use `--emit` and `--check`")); } - if let Ok(emit_mode) = emit_mode_from_emit_str(emit_str) { - options.emit_mode = emit_mode; - } else { - return Err(format_err!("Invalid value for `--emit`")); - } + + options.emit_mode = emit_mode_from_emit_str(emit_str)?; + } + + if let Some(ref edition_str) = matches.opt_str("edition") { + options.edition = edition_from_edition_str(edition_str)?; } if matches.opt_present("backup") { @@ -556,6 +559,7 @@ impl CliOptions for GetOptsOptions { if let Some(error_on_unformatted) = self.error_on_unformatted { config.set().error_on_unformatted(error_on_unformatted); } + config.set().edition(self.edition); if self.check { config.set().emit_mode(EmitMode::Diff); } else { @@ -574,6 +578,14 @@ impl CliOptions for GetOptsOptions { } } +fn edition_from_edition_str(edition_str: &str) -> Result { + match edition_str { + "2015" => Ok(Edition::Edition2015), + "2018" => Ok(Edition::Edition2018), + _ => Err(format_err!("Invalid value for `--edition`")), + } +} + fn emit_mode_from_emit_str(emit_str: &str) -> Result { match emit_str { "files" => Ok(EmitMode::Files), diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index eee102b6bf8b..45d002518286 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -17,14 +17,14 @@ extern crate cargo_metadata; extern crate getopts; extern crate serde_json as json; -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; use std::env; use std::fs; use std::hash::{Hash, Hasher}; use std::io::{self, Write}; use std::iter::FromIterator; use std::path::{Path, PathBuf}; -use std::process::{Command, ExitStatus}; +use std::process::Command; use std::str; use getopts::{Matches, Options}; @@ -122,30 +122,21 @@ pub enum Verbosity { Quiet, } -fn handle_command_status(status: Result, opts: &getopts::Options) -> i32 { +fn handle_command_status(status: Result, opts: &getopts::Options) -> i32 { match status { Err(e) => { print_usage_to_stderr(opts, &e.to_string()); FAILURE } - Ok(status) => { - if status.success() { - SUCCESS - } else { - status.code().unwrap_or(FAILURE) - } - } + Ok(status) => status, } } -fn get_version(verbosity: Verbosity) -> Result { - run_rustfmt(&[], &[String::from("--version")], verbosity) +fn get_version(verbosity: Verbosity) -> Result { + run_rustfmt(&HashSet::new(), &[String::from("--version")], verbosity) } -fn format_crate( - verbosity: Verbosity, - strategy: &CargoFmtStrategy, -) -> Result { +fn format_crate(verbosity: Verbosity, strategy: &CargoFmtStrategy) -> Result { let rustfmt_args = get_fmt_args(); let targets = if rustfmt_args .iter() @@ -157,17 +148,7 @@ fn format_crate( }; // Currently only bin and lib files get formatted - let files: Vec<_> = targets - .into_iter() - .inspect(|t| { - if verbosity == Verbosity::Verbose { - println!("[{}] {:?}", t.kind, t.path) - } - }) - .map(|t| t.path) - .collect(); - - run_rustfmt(&files, &rustfmt_args, verbosity) + run_rustfmt(&targets, &rustfmt_args, verbosity) } fn get_fmt_args() -> Vec { @@ -182,6 +163,8 @@ pub struct Target { path: PathBuf, /// A kind of target (e.g. lib, bin, example, ...). kind: String, + /// Rust edition for this target. + edition: String, } impl Target { @@ -192,6 +175,7 @@ impl Target { Target { path: canonicalized, kind: target.kind[0].clone(), + edition: target.edition.clone(), } } } @@ -334,41 +318,55 @@ fn add_targets(target_paths: &[cargo_metadata::Target], targets: &mut HashSet, fmt_args: &[String], verbosity: Verbosity, -) -> Result { - let stdout = if verbosity == Verbosity::Quiet { - std::process::Stdio::null() - } else { - std::process::Stdio::inherit() - }; +) -> Result { + let by_edition: HashMap<_, _> = targets + .iter() + .inspect(|t| { + if verbosity == Verbosity::Verbose { + println!("[{} ({})] {:?}", t.kind, t.edition, t.path) + } + }) + .map(|t| (&t.edition, vec![&t.path])) + .collect(); - if verbosity == Verbosity::Verbose { - print!("rustfmt"); - for a in fmt_args { - print!(" {}", a); + for (edition, files) in by_edition { + let stdout = if verbosity == Verbosity::Quiet { + std::process::Stdio::null() + } else { + std::process::Stdio::inherit() + }; + + if verbosity == Verbosity::Verbose { + print!("rustfmt"); + fmt_args.iter().for_each(|f| print!(" {}", f)); + files.iter().for_each(|f| print!(" {}", f.display())); + println!(); } - for f in files { - print!(" {}", f.display()); + + let mut command = Command::new("rustfmt") + .stdout(stdout) + .args(files) + .args(&["--edition", edition]) + .args(fmt_args) + .spawn() + .map_err(|e| match e.kind() { + io::ErrorKind::NotFound => io::Error::new( + io::ErrorKind::Other, + "Could not run rustfmt, please make sure it is in your PATH.", + ), + _ => e, + })?; + + let status = command.wait()?; + if !status.success() { + return Ok(status.code().unwrap_or(FAILURE)); } - println!(); } - let mut command = Command::new("rustfmt") - .stdout(stdout) - .args(files) - .args(fmt_args) - .spawn() - .map_err(|e| match e.kind() { - io::ErrorKind::NotFound => io::Error::new( - io::ErrorKind::Other, - "Could not run rustfmt, please make sure it is in your PATH.", - ), - _ => e, - })?; - - command.wait() + Ok(SUCCESS) } fn get_cargo_metadata(manifest_path: Option<&Path>) -> Result { diff --git a/src/config/options.rs b/src/config/options.rs index 27a4db70feac..38ed1e526eb2 100644 --- a/src/config/options.rs +++ b/src/config/options.rs @@ -452,6 +452,12 @@ configuration_option_enum!{ Edition: Edition2018: 2018, } +impl Default for Edition { + fn default() -> Edition { + Edition::Edition2015 + } +} + impl Edition { pub(crate) fn to_libsyntax_pos_edition(self) -> syntax_pos::edition::Edition { match self { diff --git a/src/lib.rs b/src/lib.rs index 2dcbf823d556..751f9acfd66f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,8 +48,8 @@ use issues::Issue; use shape::Indent; pub use config::{ - load_config, CliOptions, Color, Config, EmitMode, FileLines, FileName, NewlineStyle, Range, - Verbosity, + load_config, CliOptions, Color, Config, Edition, EmitMode, FileLines, FileName, NewlineStyle, + Range, Verbosity, }; #[macro_use]