Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 6739dbe

Browse files
authored
Merge pull request rust-lang#3129 from otavio/issue-3104
cargo-fmt: detect Rust edition in use
2 parents fbeabe9 + de0b661 commit 6739dbe

File tree

5 files changed

+83
-67
lines changed

5 files changed

+83
-67
lines changed

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/bin/main.rs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ use failure::err_msg;
2525
use getopts::{Matches, Options};
2626

2727
use rustfmt::{
28-
load_config, CliOptions, Color, Config, EmitMode, ErrorKind, FileLines, FileName, Input,
29-
Session, Verbosity,
28+
load_config, CliOptions, Color, Config, Edition, EmitMode, ErrorKind, FileLines, FileName,
29+
Input, Session, Verbosity,
3030
};
3131

3232
fn main() {
@@ -102,6 +102,7 @@ fn make_opts() -> Options {
102102
found reverts to the input file path",
103103
"[Path for the configuration file]",
104104
);
105+
opts.optopt("", "edition", "Rust edition to use", "[2015|2018]");
105106
opts.optopt(
106107
"",
107108
"color",
@@ -437,6 +438,7 @@ struct GetOptsOptions {
437438
emit_mode: EmitMode,
438439
backup: bool,
439440
check: bool,
441+
edition: Edition,
440442
color: Option<Color>,
441443
file_lines: FileLines, // Default is all lines in all files.
442444
unstable_features: bool,
@@ -496,11 +498,12 @@ impl GetOptsOptions {
496498
if options.check {
497499
return Err(format_err!("Invalid to use `--emit` and `--check`"));
498500
}
499-
if let Ok(emit_mode) = emit_mode_from_emit_str(emit_str) {
500-
options.emit_mode = emit_mode;
501-
} else {
502-
return Err(format_err!("Invalid value for `--emit`"));
503-
}
501+
502+
options.emit_mode = emit_mode_from_emit_str(emit_str)?;
503+
}
504+
505+
if let Some(ref edition_str) = matches.opt_str("edition") {
506+
options.edition = edition_from_edition_str(edition_str)?;
504507
}
505508

506509
if matches.opt_present("backup") {
@@ -556,6 +559,7 @@ impl CliOptions for GetOptsOptions {
556559
if let Some(error_on_unformatted) = self.error_on_unformatted {
557560
config.set().error_on_unformatted(error_on_unformatted);
558561
}
562+
config.set().edition(self.edition);
559563
if self.check {
560564
config.set().emit_mode(EmitMode::Diff);
561565
} else {
@@ -574,6 +578,14 @@ impl CliOptions for GetOptsOptions {
574578
}
575579
}
576580

581+
fn edition_from_edition_str(edition_str: &str) -> Result<Edition, failure::Error> {
582+
match edition_str {
583+
"2015" => Ok(Edition::Edition2015),
584+
"2018" => Ok(Edition::Edition2018),
585+
_ => Err(format_err!("Invalid value for `--edition`")),
586+
}
587+
}
588+
577589
fn emit_mode_from_emit_str(emit_str: &str) -> Result<EmitMode, failure::Error> {
578590
match emit_str {
579591
"files" => Ok(EmitMode::Files),

src/cargo-fmt/main.rs

Lines changed: 53 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ extern crate cargo_metadata;
1717
extern crate getopts;
1818
extern crate serde_json as json;
1919

20-
use std::collections::HashSet;
20+
use std::collections::{HashMap, HashSet};
2121
use std::env;
2222
use std::fs;
2323
use std::hash::{Hash, Hasher};
2424
use std::io::{self, Write};
2525
use std::iter::FromIterator;
2626
use std::path::{Path, PathBuf};
27-
use std::process::{Command, ExitStatus};
27+
use std::process::Command;
2828
use std::str;
2929

3030
use getopts::{Matches, Options};
@@ -122,30 +122,21 @@ pub enum Verbosity {
122122
Quiet,
123123
}
124124

125-
fn handle_command_status(status: Result<ExitStatus, io::Error>, opts: &getopts::Options) -> i32 {
125+
fn handle_command_status(status: Result<i32, io::Error>, opts: &getopts::Options) -> i32 {
126126
match status {
127127
Err(e) => {
128128
print_usage_to_stderr(opts, &e.to_string());
129129
FAILURE
130130
}
131-
Ok(status) => {
132-
if status.success() {
133-
SUCCESS
134-
} else {
135-
status.code().unwrap_or(FAILURE)
136-
}
137-
}
131+
Ok(status) => status,
138132
}
139133
}
140134

141-
fn get_version(verbosity: Verbosity) -> Result<ExitStatus, io::Error> {
142-
run_rustfmt(&[], &[String::from("--version")], verbosity)
135+
fn get_version(verbosity: Verbosity) -> Result<i32, io::Error> {
136+
run_rustfmt(&HashSet::new(), &[String::from("--version")], verbosity)
143137
}
144138

145-
fn format_crate(
146-
verbosity: Verbosity,
147-
strategy: &CargoFmtStrategy,
148-
) -> Result<ExitStatus, io::Error> {
139+
fn format_crate(verbosity: Verbosity, strategy: &CargoFmtStrategy) -> Result<i32, io::Error> {
149140
let rustfmt_args = get_fmt_args();
150141
let targets = if rustfmt_args
151142
.iter()
@@ -157,17 +148,7 @@ fn format_crate(
157148
};
158149

159150
// Currently only bin and lib files get formatted
160-
let files: Vec<_> = targets
161-
.into_iter()
162-
.inspect(|t| {
163-
if verbosity == Verbosity::Verbose {
164-
println!("[{}] {:?}", t.kind, t.path)
165-
}
166-
})
167-
.map(|t| t.path)
168-
.collect();
169-
170-
run_rustfmt(&files, &rustfmt_args, verbosity)
151+
run_rustfmt(&targets, &rustfmt_args, verbosity)
171152
}
172153

173154
fn get_fmt_args() -> Vec<String> {
@@ -182,6 +163,8 @@ pub struct Target {
182163
path: PathBuf,
183164
/// A kind of target (e.g. lib, bin, example, ...).
184165
kind: String,
166+
/// Rust edition for this target.
167+
edition: String,
185168
}
186169

187170
impl Target {
@@ -192,6 +175,7 @@ impl Target {
192175
Target {
193176
path: canonicalized,
194177
kind: target.kind[0].clone(),
178+
edition: target.edition.clone(),
195179
}
196180
}
197181
}
@@ -334,41 +318,55 @@ fn add_targets(target_paths: &[cargo_metadata::Target], targets: &mut HashSet<Ta
334318
}
335319

336320
fn run_rustfmt(
337-
files: &[PathBuf],
321+
targets: &HashSet<Target>,
338322
fmt_args: &[String],
339323
verbosity: Verbosity,
340-
) -> Result<ExitStatus, io::Error> {
341-
let stdout = if verbosity == Verbosity::Quiet {
342-
std::process::Stdio::null()
343-
} else {
344-
std::process::Stdio::inherit()
345-
};
324+
) -> Result<i32, io::Error> {
325+
let by_edition: HashMap<_, _> = targets
326+
.iter()
327+
.inspect(|t| {
328+
if verbosity == Verbosity::Verbose {
329+
println!("[{} ({})] {:?}", t.kind, t.edition, t.path)
330+
}
331+
})
332+
.map(|t| (&t.edition, vec![&t.path]))
333+
.collect();
346334

347-
if verbosity == Verbosity::Verbose {
348-
print!("rustfmt");
349-
for a in fmt_args {
350-
print!(" {}", a);
335+
for (edition, files) in by_edition {
336+
let stdout = if verbosity == Verbosity::Quiet {
337+
std::process::Stdio::null()
338+
} else {
339+
std::process::Stdio::inherit()
340+
};
341+
342+
if verbosity == Verbosity::Verbose {
343+
print!("rustfmt");
344+
fmt_args.iter().for_each(|f| print!(" {}", f));
345+
files.iter().for_each(|f| print!(" {}", f.display()));
346+
println!();
351347
}
352-
for f in files {
353-
print!(" {}", f.display());
348+
349+
let mut command = Command::new("rustfmt")
350+
.stdout(stdout)
351+
.args(files)
352+
.args(&["--edition", edition])
353+
.args(fmt_args)
354+
.spawn()
355+
.map_err(|e| match e.kind() {
356+
io::ErrorKind::NotFound => io::Error::new(
357+
io::ErrorKind::Other,
358+
"Could not run rustfmt, please make sure it is in your PATH.",
359+
),
360+
_ => e,
361+
})?;
362+
363+
let status = command.wait()?;
364+
if !status.success() {
365+
return Ok(status.code().unwrap_or(FAILURE));
354366
}
355-
println!();
356367
}
357368

358-
let mut command = Command::new("rustfmt")
359-
.stdout(stdout)
360-
.args(files)
361-
.args(fmt_args)
362-
.spawn()
363-
.map_err(|e| match e.kind() {
364-
io::ErrorKind::NotFound => io::Error::new(
365-
io::ErrorKind::Other,
366-
"Could not run rustfmt, please make sure it is in your PATH.",
367-
),
368-
_ => e,
369-
})?;
370-
371-
command.wait()
369+
Ok(SUCCESS)
372370
}
373371

374372
fn get_cargo_metadata(manifest_path: Option<&Path>) -> Result<cargo_metadata::Metadata, io::Error> {

src/config/options.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,12 @@ configuration_option_enum!{ Edition:
452452
Edition2018: 2018,
453453
}
454454

455+
impl Default for Edition {
456+
fn default() -> Edition {
457+
Edition::Edition2015
458+
}
459+
}
460+
455461
impl Edition {
456462
pub(crate) fn to_libsyntax_pos_edition(self) -> syntax_pos::edition::Edition {
457463
match self {

src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ use issues::Issue;
4848
use shape::Indent;
4949

5050
pub use config::{
51-
load_config, CliOptions, Color, Config, EmitMode, FileLines, FileName, NewlineStyle, Range,
52-
Verbosity,
51+
load_config, CliOptions, Color, Config, Edition, EmitMode, FileLines, FileName, NewlineStyle,
52+
Range, Verbosity,
5353
};
5454

5555
#[macro_use]

0 commit comments

Comments
 (0)