Merge pull request #3129 from otavio/issue-3104

cargo-fmt: detect Rust edition in use
This commit is contained in:
Nick Cameron 2018-10-25 13:39:40 +13:00 committed by GitHub
commit 6739dbe77d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 83 additions and 67 deletions

6
Cargo.lock generated
View file

@ -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"

View file

@ -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<Color>,
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<Edition, failure::Error> {
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<EmitMode, failure::Error> {
match emit_str {
"files" => Ok(EmitMode::Files),

View file

@ -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<ExitStatus, io::Error>, opts: &getopts::Options) -> i32 {
fn handle_command_status(status: Result<i32, io::Error>, 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<ExitStatus, io::Error> {
run_rustfmt(&[], &[String::from("--version")], verbosity)
fn get_version(verbosity: Verbosity) -> Result<i32, io::Error> {
run_rustfmt(&HashSet::new(), &[String::from("--version")], verbosity)
}
fn format_crate(
verbosity: Verbosity,
strategy: &CargoFmtStrategy,
) -> Result<ExitStatus, io::Error> {
fn format_crate(verbosity: Verbosity, strategy: &CargoFmtStrategy) -> Result<i32, io::Error> {
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<String> {
@ -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<Ta
}
fn run_rustfmt(
files: &[PathBuf],
targets: &HashSet<Target>,
fmt_args: &[String],
verbosity: Verbosity,
) -> Result<ExitStatus, io::Error> {
let stdout = if verbosity == Verbosity::Quiet {
std::process::Stdio::null()
} else {
std::process::Stdio::inherit()
};
) -> Result<i32, io::Error> {
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<cargo_metadata::Metadata, io::Error> {

View file

@ -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 {

View file

@ -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]