From ad950b06f20e70a5663bdce580408a98b51e5854 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Wed, 8 Jan 2020 22:45:58 +0900 Subject: [PATCH 01/15] Bump version --- Cargo.toml | 2 +- rustfmt-core/rustfmt-bin/Cargo.toml | 2 +- rustfmt-core/rustfmt-config/Cargo.toml | 2 +- rustfmt-core/rustfmt-emitter/Cargo.toml | 4 ++-- rustfmt-core/rustfmt-lib/Cargo.toml | 6 +++--- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7bfe19809a8..59c3945cfec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,7 +51,7 @@ structopt = "0.3" term = "0.6" thiserror = "1.0" -rustfmt_lib = { path = "rustfmt-core/rustfmt-lib", version = "1.0" } +rustfmt_lib = { path = "rustfmt-core/rustfmt-lib", version = "2.0.0-rc.1" } [dev-dependencies] lazy_static = "1.0" diff --git a/rustfmt-core/rustfmt-bin/Cargo.toml b/rustfmt-core/rustfmt-bin/Cargo.toml index b57df94890a..401467957ac 100644 --- a/rustfmt-core/rustfmt-bin/Cargo.toml +++ b/rustfmt-core/rustfmt-bin/Cargo.toml @@ -41,7 +41,7 @@ structopt = "0.3" term = "0.6" thiserror = "1.0" -rustfmt_lib = { path = "../rustfmt-lib", version = "1.0" } +rustfmt_lib = { path = "../rustfmt-lib", version = "2.0.0-rc.1" } [dev-dependencies] lazy_static = "1.0" diff --git a/rustfmt-core/rustfmt-config/Cargo.toml b/rustfmt-core/rustfmt-config/Cargo.toml index afb773ef5c7..4b47a672605 100644 --- a/rustfmt-core/rustfmt-config/Cargo.toml +++ b/rustfmt-core/rustfmt-config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rustfmt_configuration" -version = "1.0.0" +version = "2.0.0-rc.1" authors = ["topecongiro "] edition = "2018" description = "Rustfmt configuration library" diff --git a/rustfmt-core/rustfmt-emitter/Cargo.toml b/rustfmt-core/rustfmt-emitter/Cargo.toml index 4fd60e2c1aa..8ce93fb133a 100644 --- a/rustfmt-core/rustfmt-emitter/Cargo.toml +++ b/rustfmt-core/rustfmt-emitter/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rustfmt_emitter" -version = "1.0.0" +version = "2.0.0-rc.1" authors = ["topecongiro "] edition = "2018" description = "Rustfmt emitter library" @@ -9,7 +9,7 @@ repository = "https://github.com/rust-lang/rustfmt" [dependencies] diff = "0.1" -rustfmt_configuration = { path = "../rustfmt-config", version = "1.0" } +rustfmt_configuration = { path = "../rustfmt-config", version = "2.0.0-rc.1" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" term = "0.6" diff --git a/rustfmt-core/rustfmt-lib/Cargo.toml b/rustfmt-core/rustfmt-lib/Cargo.toml index 8089bda96fc..93413df833e 100644 --- a/rustfmt-core/rustfmt-lib/Cargo.toml +++ b/rustfmt-core/rustfmt-lib/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rustfmt_lib" -version = "1.0.0" +version = "2.0.0-rc.1" authors = ["topecongiro "] edition = "2018" description = "Rustfmt as a library" @@ -18,8 +18,8 @@ itertools = "0.8" lazy_static = "1.0.0" log = "0.4" regex = "1.0" -rustfmt_configuration = { path = "../rustfmt-config", version = "1.0" } -rustfmt_emitter = { path = "../rustfmt-emitter", version = "1.0" } +rustfmt_configuration = { path = "../rustfmt-config", version = "2.0.0-rc.1" } +rustfmt_emitter = { path = "../rustfmt-emitter", version = "2.0.0-rc.1" } term = "0.6" thiserror = "1.0" unicode_categories = "0.1.1" From af0ae9b858898dfa37313991c33ececb1bebf53e Mon Sep 17 00:00:00 2001 From: topecongiro Date: Wed, 8 Jan 2020 22:50:19 +0900 Subject: [PATCH 02/15] Remove skip_children --- Configurations.md | 8 ----- rustfmt-core/rustfmt-config/Cargo.toml | 1 - .../rustfmt-config/src/config_type.rs | 12 ------- rustfmt-core/rustfmt-config/src/lib.rs | 35 +------------------ rustfmt-core/rustfmt-lib/src/test/mod.rs | 3 -- .../tests/config/skip_children.toml | 1 - .../source/configs/skip_children/foo/mod.rs | 3 -- .../source/configs/skip_children/true.rs | 4 --- .../tests/source/mod_skip_child.rs | 2 -- .../tests/source/nested_skipped/mod.rs | 3 -- .../target/configs/skip_children/foo/mod.rs | 3 -- .../target/configs/skip_children/true.rs | 4 --- .../target/issue-2673-nonmodrs-mods/foo.rs | 4 --- .../issue-2673-nonmodrs-mods/foo/bar.rs | 1 - .../target/issue-2673-nonmodrs-mods/lib.rs | 6 ---- .../tests/target/mod_skip_child.rs | 2 -- .../tests/target/nested_skipped/mod.rs | 3 -- 17 files changed, 1 insertion(+), 94 deletions(-) delete mode 100644 rustfmt-core/rustfmt-lib/tests/config/skip_children.toml delete mode 100644 rustfmt-core/rustfmt-lib/tests/source/configs/skip_children/foo/mod.rs delete mode 100644 rustfmt-core/rustfmt-lib/tests/source/configs/skip_children/true.rs delete mode 100644 rustfmt-core/rustfmt-lib/tests/source/mod_skip_child.rs delete mode 100644 rustfmt-core/rustfmt-lib/tests/source/nested_skipped/mod.rs delete mode 100644 rustfmt-core/rustfmt-lib/tests/target/configs/skip_children/foo/mod.rs delete mode 100644 rustfmt-core/rustfmt-lib/tests/target/configs/skip_children/true.rs delete mode 100644 rustfmt-core/rustfmt-lib/tests/target/issue-2673-nonmodrs-mods/foo.rs delete mode 100644 rustfmt-core/rustfmt-lib/tests/target/issue-2673-nonmodrs-mods/foo/bar.rs delete mode 100644 rustfmt-core/rustfmt-lib/tests/target/issue-2673-nonmodrs-mods/lib.rs delete mode 100644 rustfmt-core/rustfmt-lib/tests/target/mod_skip_child.rs delete mode 100644 rustfmt-core/rustfmt-lib/tests/target/nested_skipped/mod.rs diff --git a/Configurations.md b/Configurations.md index f0ab14d1eb1..6de10eaabf0 100644 --- a/Configurations.md +++ b/Configurations.md @@ -1881,14 +1881,6 @@ specific version of rustfmt is used in your CI, use this option. - **Possible values**: any published version (e.g. `"0.3.8"`) - **Stable**: No (tracking issue: #3386) -## `skip_children` (DEPRECATED #3587) - -Don't reformat out of line modules - -- **Default value**: `false` -- **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3389) - ## `space_after_colon` Leave a space after the colon. diff --git a/rustfmt-core/rustfmt-config/Cargo.toml b/rustfmt-core/rustfmt-config/Cargo.toml index 4b47a672605..c65222dfd51 100644 --- a/rustfmt-core/rustfmt-config/Cargo.toml +++ b/rustfmt-core/rustfmt-config/Cargo.toml @@ -8,7 +8,6 @@ license = "Apache-2.0/MIT" repository = "https://github.com/rust-lang/rustfmt" [dependencies] -ansi_term = "0.12" dirs = "2.0" itertools = "0.8" regex = "1.3" diff --git a/rustfmt-core/rustfmt-config/src/config_type.rs b/rustfmt-core/rustfmt-config/src/config_type.rs index a864742a8ed..147238566ba 100644 --- a/rustfmt-core/rustfmt-config/src/config_type.rs +++ b/rustfmt-core/rustfmt-config/src/config_type.rs @@ -57,9 +57,6 @@ macro_rules! create_config { use serde::{Deserialize, Serialize}; - // for error messages - use ansi_term::Colour::Red; - #[derive(Clone)] #[allow(unreachable_pub)] pub struct Config { @@ -139,17 +136,8 @@ macro_rules! create_config { } fn fill_from_parsed_config(mut self, parsed: PartialConfig, dir: &Path) -> Self { - let deprecate_skip_children = || { - let msg = "Option skip_children is deprecated since it is now the default to \ - not format submodules of given files (#3587)"; - eprintln!("{}: {}", Red.bold().paint("Deprecation"), msg); - }; - $( if let Some(val) = parsed.$i { - if stringify!($i) == "skip_children" { - deprecate_skip_children() - } if self.$i.3 { self.$i.1 = true; self.$i.2 = val; diff --git a/rustfmt-core/rustfmt-config/src/lib.rs b/rustfmt-core/rustfmt-config/src/lib.rs index 8dbdacb9054..9134fc23463 100644 --- a/rustfmt-core/rustfmt-config/src/lib.rs +++ b/rustfmt-core/rustfmt-config/src/lib.rs @@ -285,13 +285,6 @@ impl Config { eprint!("{}", err); } let config = Config::default().fill_from_parsed_config(parsed_config, dir); - if config.skip_children() && config.recursive() { - return Err(String::from( - "Error: Conflicting config options `skip_children` and `recursive` are \ - both enabled. `skip_children` has been deprecated and should be \ - removed from your config.", - )); - } Ok(config) } Err(e) => { @@ -431,16 +424,12 @@ mod test { let config = Config::default(); let merge_derives = config.merge_derives(); - let skip_children = config.skip_children(); let used_options = config.used_options(); let toml = used_options.to_toml().unwrap(); assert_eq!( toml, - format!( - "merge_derives = {}\nskip_children = {}\n", - merge_derives, skip_children, - ) + "merge_derives = false\n" ); } @@ -496,27 +485,6 @@ mod test { assert!(config.license_template.is_some()); } - #[test] - fn test_conflicting_recursive_skip_children() { - if !option_env!("CFG_RELEASE_CHANNEL").map_or(true, |c| c == "nightly" || c == "dev") { - return; - } - - let toml = "skip_children = true\nrecursive = true"; - // Update to `contains_err()` once it lands - // https://github.com/rust-lang/rust/issues/62358 - // https://doc.rust-lang.org/std/result/enum.Result.html#method.contains_err - match Config::from_toml(toml, Path::new("")) { - Ok(_) => panic!("Expected configuration error"), - Err(msg) => assert_eq!( - msg, - "Error: Conflicting config options `skip_children` and `recursive` \ - are both enabled. `skip_children` has been deprecated and should be \ - removed from your config.", - ), - } - } - #[test] fn test_dump_default_config() { let default_config = format!( @@ -577,7 +545,6 @@ color = "Auto" required_version = "{}" unstable_features = false disable_all_formatting = false -skip_children = false hide_parse_errors = false error_on_line_overflow = false error_on_unformatted = false diff --git a/rustfmt-core/rustfmt-lib/src/test/mod.rs b/rustfmt-core/rustfmt-lib/src/test/mod.rs index 8ccf3be75d5..73aa730de7e 100644 --- a/rustfmt-core/rustfmt-lib/src/test/mod.rs +++ b/rustfmt-core/rustfmt-lib/src/test/mod.rs @@ -23,9 +23,6 @@ const DIFF_CONTEXT_SIZE: usize = 3; // A list of files on which we want to skip testing. const SKIP_FILE_WHITE_LIST: &[&str] = &[ - // We want to make sure that the `skip_children` is correctly working, - // so we do not want to test this file directly. - "configs/skip_children/foo/mod.rs", "issue-3434/no_entry.rs", "issue-3665/sub_mod.rs", // Testing for issue-3779 diff --git a/rustfmt-core/rustfmt-lib/tests/config/skip_children.toml b/rustfmt-core/rustfmt-lib/tests/config/skip_children.toml deleted file mode 100644 index f52930d50b6..00000000000 --- a/rustfmt-core/rustfmt-lib/tests/config/skip_children.toml +++ /dev/null @@ -1 +0,0 @@ -skip_children = true diff --git a/rustfmt-core/rustfmt-lib/tests/source/configs/skip_children/foo/mod.rs b/rustfmt-core/rustfmt-lib/tests/source/configs/skip_children/foo/mod.rs deleted file mode 100644 index d7ff6cdb829..00000000000 --- a/rustfmt-core/rustfmt-lib/tests/source/configs/skip_children/foo/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn skip_formatting_this() { - println ! ( "Skip this" ) ; -} diff --git a/rustfmt-core/rustfmt-lib/tests/source/configs/skip_children/true.rs b/rustfmt-core/rustfmt-lib/tests/source/configs/skip_children/true.rs deleted file mode 100644 index e51889dd4c9..00000000000 --- a/rustfmt-core/rustfmt-lib/tests/source/configs/skip_children/true.rs +++ /dev/null @@ -1,4 +0,0 @@ -// rustfmt-skip_children: true - -mod foo ; -mod void; diff --git a/rustfmt-core/rustfmt-lib/tests/source/mod_skip_child.rs b/rustfmt-core/rustfmt-lib/tests/source/mod_skip_child.rs deleted file mode 100644 index d48c4a37e81..00000000000 --- a/rustfmt-core/rustfmt-lib/tests/source/mod_skip_child.rs +++ /dev/null @@ -1,2 +0,0 @@ -// rustfmt-skip_children: true -mod nested_skipped; diff --git a/rustfmt-core/rustfmt-lib/tests/source/nested_skipped/mod.rs b/rustfmt-core/rustfmt-lib/tests/source/nested_skipped/mod.rs deleted file mode 100644 index 44b25ca8797..00000000000 --- a/rustfmt-core/rustfmt-lib/tests/source/nested_skipped/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn ugly() { -92; -} diff --git a/rustfmt-core/rustfmt-lib/tests/target/configs/skip_children/foo/mod.rs b/rustfmt-core/rustfmt-lib/tests/target/configs/skip_children/foo/mod.rs deleted file mode 100644 index d7ff6cdb829..00000000000 --- a/rustfmt-core/rustfmt-lib/tests/target/configs/skip_children/foo/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn skip_formatting_this() { - println ! ( "Skip this" ) ; -} diff --git a/rustfmt-core/rustfmt-lib/tests/target/configs/skip_children/true.rs b/rustfmt-core/rustfmt-lib/tests/target/configs/skip_children/true.rs deleted file mode 100644 index 33fd782b4fa..00000000000 --- a/rustfmt-core/rustfmt-lib/tests/target/configs/skip_children/true.rs +++ /dev/null @@ -1,4 +0,0 @@ -// rustfmt-skip_children: true - -mod foo; -mod void; diff --git a/rustfmt-core/rustfmt-lib/tests/target/issue-2673-nonmodrs-mods/foo.rs b/rustfmt-core/rustfmt-lib/tests/target/issue-2673-nonmodrs-mods/foo.rs deleted file mode 100644 index 5340816d61e..00000000000 --- a/rustfmt-core/rustfmt-lib/tests/target/issue-2673-nonmodrs-mods/foo.rs +++ /dev/null @@ -1,4 +0,0 @@ -// rustfmt-config: skip_children.toml -mod bar; - -mod baz {} diff --git a/rustfmt-core/rustfmt-lib/tests/target/issue-2673-nonmodrs-mods/foo/bar.rs b/rustfmt-core/rustfmt-lib/tests/target/issue-2673-nonmodrs-mods/foo/bar.rs deleted file mode 100644 index 9ceacd59d86..00000000000 --- a/rustfmt-core/rustfmt-lib/tests/target/issue-2673-nonmodrs-mods/foo/bar.rs +++ /dev/null @@ -1 +0,0 @@ -fn dummy() {} diff --git a/rustfmt-core/rustfmt-lib/tests/target/issue-2673-nonmodrs-mods/lib.rs b/rustfmt-core/rustfmt-lib/tests/target/issue-2673-nonmodrs-mods/lib.rs deleted file mode 100644 index 82425de565a..00000000000 --- a/rustfmt-core/rustfmt-lib/tests/target/issue-2673-nonmodrs-mods/lib.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![feature(non_modrs_mods)] - -// Test that submodules in non-mod.rs files work. This is just an idempotence -// test since we just want to verify that rustfmt doesn't fail. - -mod foo; diff --git a/rustfmt-core/rustfmt-lib/tests/target/mod_skip_child.rs b/rustfmt-core/rustfmt-lib/tests/target/mod_skip_child.rs deleted file mode 100644 index d48c4a37e81..00000000000 --- a/rustfmt-core/rustfmt-lib/tests/target/mod_skip_child.rs +++ /dev/null @@ -1,2 +0,0 @@ -// rustfmt-skip_children: true -mod nested_skipped; diff --git a/rustfmt-core/rustfmt-lib/tests/target/nested_skipped/mod.rs b/rustfmt-core/rustfmt-lib/tests/target/nested_skipped/mod.rs deleted file mode 100644 index 0ab6f081e44..00000000000 --- a/rustfmt-core/rustfmt-lib/tests/target/nested_skipped/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn ugly() { - 92; -} From 0310620eb85ab4340d22ee42b29e9267921bad8d Mon Sep 17 00:00:00 2001 From: topecongiro Date: Wed, 8 Jan 2020 22:50:42 +0900 Subject: [PATCH 03/15] Remove unused getopts error from format-diff --- rustfmt-core/rustfmt-bin/src/format-diff/main.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/rustfmt-core/rustfmt-bin/src/format-diff/main.rs b/rustfmt-core/rustfmt-bin/src/format-diff/main.rs index 5d16c0e015e..05bfae9f227 100644 --- a/rustfmt-core/rustfmt-bin/src/format-diff/main.rs +++ b/rustfmt-core/rustfmt-bin/src/format-diff/main.rs @@ -26,8 +26,6 @@ const DEFAULT_PATTERN: &str = r".*\.rs"; #[derive(Error, Debug)] enum FormatDiffError { - #[error("{0}")] - IncorrectOptions(#[from] getopts::Fail), #[error("{0}")] IncorrectFilter(#[from] regex::Error), #[error("{0}")] From 0bd06bd9285c707012ea603c9b684d7091366378 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Wed, 8 Jan 2020 22:53:19 +0900 Subject: [PATCH 04/15] Replace getopts with structopt in git-rustfmt --- .../rustfmt-bin/src/git-rustfmt/main.rs | 81 ++++--------------- 1 file changed, 15 insertions(+), 66 deletions(-) diff --git a/rustfmt-core/rustfmt-bin/src/git-rustfmt/main.rs b/rustfmt-core/rustfmt-bin/src/git-rustfmt/main.rs index 50ba77982cd..202e94714d4 100644 --- a/rustfmt-core/rustfmt-bin/src/git-rustfmt/main.rs +++ b/rustfmt-core/rustfmt-bin/src/git-rustfmt/main.rs @@ -1,13 +1,11 @@ #[macro_use] extern crate log; -use std::env; use std::io::stdout; use std::path::{Path, PathBuf}; use std::process::Command; -use std::str::FromStr; -use getopts::{Matches, Options}; +use structopt::StructOpt; use rustfmt_lib::{load_config, CliOptions, FormatReportFormatterBuilder, Input, Session}; @@ -37,10 +35,10 @@ fn prune_files(files: Vec<&str>) -> Vec<&str> { .collect() } -fn git_diff(commits: &str) -> String { +fn git_diff(commits: u64) -> String { let mut cmd = Command::new("git"); cmd.arg("diff"); - if commits != "0" { + if commits != 0 { cmd.arg(format!("HEAD~{}", commits)); } let output = cmd.output().expect("Couldn't execute `git diff`"); @@ -114,77 +112,28 @@ fn check_uncommitted() { } } -fn make_opts() -> Options { - let mut opts = Options::new(); - opts.optflag("h", "help", "show this message"); - opts.optflag("c", "check", "check only, don't format (unimplemented)"); - opts.optflag("u", "uncommitted", "format uncommitted files"); - opts -} - -struct Config { - commits: String, - uncommitted: bool, +#[derive(Debug, StructOpt)] +struct Opt { + /// Check only. + #[structopt(short, long)] check: bool, -} - -impl Config { - fn from_args(matches: &Matches, opts: &Options) -> Config { - // `--help` display help message and quit - if matches.opt_present("h") { - let message = format!( - "\nusage: {} [options]\n\n\ - commits: number of commits to format, default: 1", - env::args_os().next().unwrap().to_string_lossy() - ); - println!("{}", opts.usage(&message)); - std::process::exit(0); - } - - let mut config = Config { - commits: "1".to_owned(), - uncommitted: false, - check: false, - }; - - if matches.opt_present("c") { - config.check = true; - unimplemented!(); - } - - if matches.opt_present("u") { - config.uncommitted = true; - } - - if matches.free.len() > 1 { - panic!("unknown arguments, use `-h` for usage"); - } - if matches.free.len() == 1 { - let commits = matches.free[0].trim(); - if u32::from_str(commits).is_err() { - panic!("Couldn't parse number of commits"); - } - config.commits = commits.to_owned(); - } - - config - } + /// Format uncommitted files. + #[structopt(short, long)] + uncommitted: bool, + #[structopt(short, long)] + commits: u64, } fn main() { env_logger::init(); - let opts = make_opts(); - let matches = opts - .parse(env::args().skip(1)) - .expect("Couldn't parse command line"); - let config = Config::from_args(&matches, &opts); + let opt: Opt = Opt::from_args(); - if !config.uncommitted { + if !opt.uncommitted { check_uncommitted(); } - let stdout = git_diff(&config.commits); + let stdout = git_diff(opt.commits); let files = get_files(&stdout); debug!("files: {:?}", files); let files = prune_files(files); From 4201852c53301978b70fbe36a3395a9cda6a9451 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Wed, 8 Jan 2020 22:54:13 +0900 Subject: [PATCH 05/15] Add error detail to FileLinesError::CannotCanonicalize --- rustfmt-core/rustfmt-config/src/file_lines.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rustfmt-core/rustfmt-config/src/file_lines.rs b/rustfmt-core/rustfmt-config/src/file_lines.rs index ecea5b7ca59..88c4443db17 100644 --- a/rustfmt-core/rustfmt-config/src/file_lines.rs +++ b/rustfmt-core/rustfmt-config/src/file_lines.rs @@ -251,7 +251,7 @@ impl FileLines { Some(ref map) => map, }; - match canonicalize_path_string(file_name).and_then(|file| map.get(&file)) { + match canonicalize_path_string(file_name).ok().and_then(|file| map.get(&file)) { Some(ranges) => ranges.iter().any(f), None => false, } @@ -290,10 +290,10 @@ impl<'a> iter::Iterator for Files<'a> { } } -fn canonicalize_path_string(file: &FileName) -> Option { +fn canonicalize_path_string(file: &FileName) -> std::io::Result { match *file { - FileName::Real(ref path) => path.canonicalize().ok().map(FileName::Real), - _ => Some(file.clone()), + FileName::Real(ref path) => path.canonicalize().map(FileName::Real), + _ => Ok(file.clone()), } } @@ -301,8 +301,8 @@ fn canonicalize_path_string(file: &FileName) -> Option { pub enum FileLinesError { #[error("{0}")] Json(json::Error), - #[error("Can't canonicalize {0}")] - CannotCanonicalize(FileName), + #[error("Can't canonicalize {0}: {1}")] + CannotCanonicalize(FileName, std::io::Error), } // This impl is needed for `Config::override_value` to work for use in tests. @@ -335,7 +335,7 @@ impl JsonSpan { fn into_tuple(self) -> Result<(FileName, Range), FileLinesError> { let (lo, hi) = self.range; let canonical = canonicalize_path_string(&self.file) - .ok_or_else(|| FileLinesError::CannotCanonicalize(self.file))?; + .map_err(|e| FileLinesError::CannotCanonicalize(self.file, e))?; Ok((canonical, Range::new(lo, hi))) } } From 2bfbd61f64bf81e547cccbfc2a8225d7c442e601 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Wed, 8 Jan 2020 22:57:05 +0900 Subject: [PATCH 06/15] Take self reference intead of its ownership --- rustfmt-core/rustfmt-bin/src/git-rustfmt/main.rs | 2 +- rustfmt-core/rustfmt-config/src/lib.rs | 4 ++-- rustfmt-core/rustfmt-config/src/options.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rustfmt-core/rustfmt-bin/src/git-rustfmt/main.rs b/rustfmt-core/rustfmt-bin/src/git-rustfmt/main.rs index 202e94714d4..d84b1a48ed9 100644 --- a/rustfmt-core/rustfmt-bin/src/git-rustfmt/main.rs +++ b/rustfmt-core/rustfmt-bin/src/git-rustfmt/main.rs @@ -75,7 +75,7 @@ fn fmt_files(files: &[&str]) -> i32 { struct NullOptions; impl CliOptions for NullOptions { - fn apply_to(self, _: &mut rustfmt_lib::Config) { + fn apply_to(&self, _: &mut rustfmt_lib::Config) { unreachable!(); } fn config_path(&self) -> Option<&Path> { diff --git a/rustfmt-core/rustfmt-config/src/lib.rs b/rustfmt-core/rustfmt-config/src/lib.rs index 9134fc23463..d30e1ebc203 100644 --- a/rustfmt-core/rustfmt-config/src/lib.rs +++ b/rustfmt-core/rustfmt-config/src/lib.rs @@ -301,10 +301,10 @@ impl Config { /// file system (including searching the file system for overrides). pub fn load_config( file_path: Option<&Path>, - options: Option, + options: Option<&O>, ) -> Result<(Config, Option), Error> { let over_ride = match options { - Some(ref opts) => config_path(opts)?, + Some(opts) => config_path(opts)?, None => None, }; diff --git a/rustfmt-core/rustfmt-config/src/options.rs b/rustfmt-core/rustfmt-config/src/options.rs index ea187f10639..c970868f482 100644 --- a/rustfmt-core/rustfmt-config/src/options.rs +++ b/rustfmt-core/rustfmt-config/src/options.rs @@ -351,7 +351,7 @@ impl std::str::FromStr for IgnoreList { /// Maps client-supplied options to Rustfmt's internals, mostly overriding /// values in a config with values from the command line. pub trait CliOptions { - fn apply_to(self, config: &mut Config); + fn apply_to(&self, config: &mut Config); fn config_path(&self) -> Option<&Path>; } From 25dd8955d50529327c8fa0c41d0499fb1b95ce86 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Wed, 8 Jan 2020 22:58:29 +0900 Subject: [PATCH 07/15] Do not dump emit_mode --- rustfmt-core/rustfmt-config/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rustfmt-core/rustfmt-config/src/lib.rs b/rustfmt-core/rustfmt-config/src/lib.rs index d30e1ebc203..8b12eb19991 100644 --- a/rustfmt-core/rustfmt-config/src/lib.rs +++ b/rustfmt-core/rustfmt-config/src/lib.rs @@ -169,6 +169,7 @@ impl PartialConfig { cloned.width_heuristics = None; cloned.print_misformatted_file_names = None; cloned.recursive = None; + cloned.emit_mode = None; ::toml::to_string(&cloned).map_err(ToTomlError) } @@ -551,7 +552,6 @@ error_on_unformatted = false report_todo = "Never" report_fixme = "Never" ignore = [] -emit_mode = "Files" "#, env!("CARGO_PKG_VERSION") ); From ca605bad83d5c7a987a9a659036db603abcaac0e Mon Sep 17 00:00:00 2001 From: topecongiro Date: Wed, 8 Jan 2020 22:58:47 +0900 Subject: [PATCH 08/15] Change the behavior of Config::used_option Currently it returns a set of configuration options that was read. IMO, this is not all that useful. Instead, it should return a set of options that was explicitly set to some value that is different from its default value. --- rustfmt-core/rustfmt-config/src/config_type.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/rustfmt-core/rustfmt-config/src/config_type.rs b/rustfmt-core/rustfmt-config/src/config_type.rs index 147238566ba..4f8cf34759e 100644 --- a/rustfmt-core/rustfmt-config/src/config_type.rs +++ b/rustfmt-core/rustfmt-config/src/config_type.rs @@ -92,11 +92,14 @@ macro_rules! create_config { $( #[allow(unreachable_pub)] pub fn $i(&mut self, value: $Ty) { - (self.0).$i.2 = value; - match stringify!($i) { - "max_width" | "use_small_heuristics" => self.0.set_heuristics(), - "license_template_path" => self.0.set_license_template(), - &_ => (), + if value != (self.0).$i.2 { + (self.0).$i.1 = true; + (self.0).$i.2 = value; + match stringify!($i) { + "max_width" | "use_small_heuristics" => self.0.set_heuristics(), + "license_template_path" => self.0.set_license_template(), + &_ => (), + } } } )+ @@ -189,7 +192,7 @@ macro_rules! create_config { pub fn used_options(&self) -> PartialConfig { PartialConfig { $( - $i: if self.$i.0.get() { + $i: if self.$i.1 && self.$i.2 != $def { Some(self.$i.2.clone()) } else { None From ea95e9419dcff1b1eb9807136307f1da64aebae3 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Wed, 8 Jan 2020 23:00:44 +0900 Subject: [PATCH 09/15] Update test --- rustfmt-core/rustfmt-config/src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rustfmt-core/rustfmt-config/src/lib.rs b/rustfmt-core/rustfmt-config/src/lib.rs index 8b12eb19991..d2826677aa6 100644 --- a/rustfmt-core/rustfmt-config/src/lib.rs +++ b/rustfmt-core/rustfmt-config/src/lib.rs @@ -422,9 +422,10 @@ mod test { #[test] fn test_config_used_to_toml() { - let config = Config::default(); + let mut config = Config::default(); - let merge_derives = config.merge_derives(); + config.set().merge_derives(false); + config.set().max_width(100); let used_options = config.used_options(); let toml = used_options.to_toml().unwrap(); From c9cf7adbf1be9ad7839552df4c2dfb55a8d03107 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Wed, 8 Jan 2020 23:01:02 +0900 Subject: [PATCH 10/15] Replace getotps with sturctopt in rustfmt --- rustfmt-core/rustfmt-bin/build.rs | 10 +- rustfmt-core/rustfmt-bin/src/bin/main.rs | 937 ++++++++---------- .../rustfmt-bin/tests/cargo-fmt/main.rs | 2 +- .../rustfmt-bin/tests/rustfmt/main.rs | 27 +- 4 files changed, 400 insertions(+), 576 deletions(-) diff --git a/rustfmt-core/rustfmt-bin/build.rs b/rustfmt-core/rustfmt-bin/build.rs index e7b1e1b854c..4d8f2502b13 100644 --- a/rustfmt-core/rustfmt-bin/build.rs +++ b/rustfmt-core/rustfmt-bin/build.rs @@ -12,10 +12,13 @@ fn main() { } println!("cargo:rerun-if-env-changed=CFG_RELEASE_CHANNEL"); + if option_env!("CFG_RELEASE_CHANNEL").map_or(true, |c| c == "nightly" || c == "dev") { + println!("cargo:rustc-cfg=nightly"); + } let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); - File::create(out_dir.join("commit-info.txt")) + File::create(out_dir.join("version-info.txt")) .unwrap() .write_all(commit_info().as_bytes()) .unwrap(); @@ -25,7 +28,10 @@ fn main() { // (git not installed or if this is not a git repository) just return an empty string. fn commit_info() -> String { match (channel(), commit_hash(), commit_date()) { - (channel, Some(hash), Some(date)) => format!("{} ({} {})", channel, hash.trim_end(), date), + (channel, Some(hash), Some(date)) => { + format!("{}-{} ({} {})", option_env!("CARGO_PKG_VERSION") + .unwrap_or("unknown"), channel, hash.trim_end(), date) + }, _ => String::new(), } } diff --git a/rustfmt-core/rustfmt-bin/src/bin/main.rs b/rustfmt-core/rustfmt-bin/src/bin/main.rs index 2d4536384f7..4c24f42dcb2 100644 --- a/rustfmt-core/rustfmt-bin/src/bin/main.rs +++ b/rustfmt-core/rustfmt-bin/src/bin/main.rs @@ -1,24 +1,28 @@ +#[cfg(test)] +#[macro_use] +extern crate lazy_static; + use std::collections::HashMap; use std::env; -use std::io::{self, stdout, Error as IoError, Read, Write}; +use std::fmt; +use std::io::{self, stdout, Error as IoError, Read, Write, stdin}; use std::path::{Path, PathBuf}; use std::str::FromStr; -use ansi_term::Colour::Red; use anyhow::{format_err, Result}; -use getopts::{Matches, Options}; +use structopt::StructOpt; use thiserror::Error; use rustfmt_lib::{ - load_config, CliOptions, Color, Config, Edition, EmitMode, FileLines, FileName, + load_config, CliOptions, Config, Edition, EmitMode, FileLines, FileName, FormatReportFormatterBuilder, Input, Session, Verbosity, }; fn main() { env_logger::init(); - let opts = make_opts(); + let opt: Opt = Opt::from_args(); - let exit_code = match execute(&opts) { + let exit_code = match execute(opt) { Ok(code) => code, Err(e) => { eprintln!("{}", e.to_string()); @@ -35,25 +39,247 @@ fn main() { std::process::exit(exit_code); } -/// Rustfmt operations. -enum Operation { - /// Format files and their child modules. - Format { - files: Vec, - minimal_config_path: Option, - }, - /// Print the help message. - Help(HelpOp), - /// Print version information - Version, - /// Output default config to a file, or stdout if None - ConfigOutputDefault { path: Option }, - /// Output current config (as if formatting to a file) to stdout - ConfigOutputCurrent { path: Option }, - /// No file specified, read from stdin - Stdin { input: String }, +/// Format Rust code +#[derive(Debug, StructOpt, Clone)] +#[structopt(name = "rustfmt", version = include_str!(concat!(env!("OUT_DIR"), "/version-info.txt")))] +struct Opt { + /// Run in 'check' mode. + /// + /// Exits with 0 if input is formatted correctly. + /// Exits with 1 and prints a diff if formatting is required. + #[structopt(short, long)] + check: bool, + /// Specify the format of rustfmt's output. + #[structopt(long)] + emit: Option, + /// A path to the configuration file. + #[structopt(long = "config-path", parse(from_os_str))] + config_path: Option, + /// Rust compiler edition + /// + /// Specify which edition of the compiler to use when formatting code. + #[structopt(long, name = "2015|2018")] + edition: Option, + /// Print configuration options. + /// + /// `default` will print the default configuration options. `current` will print the + /// current configuration options. `minimal` will print the minimal subset of the + /// current configuration options. + #[structopt(long = "print-config", name = "default|current|minimal")] + print_config: Option, + /// Prints the names of files with diff. + #[structopt(short = "l", long = "files-with-diff")] + files_with_diff: bool, + /// Set options from command line. + /// + /// Set configuration options via command line by specifying a list of key-value pairs + /// separated by commas (e.g., rustfmt --config=max_width=100,merge_imports=true). + /// These settings precedes any other settings specified in configuration files. + #[structopt(long = "config")] + inline_config: Option>, + /// Recursively format submodules. + /// + /// Format all encountered modules recursively regardless of whether the modules + /// are defined inline or in another file. + #[structopt(short, long)] + recursive: bool, + /// Print no output. + #[structopt(short, long)] + quiet: bool, + /// Print verbose output. + #[structopt(short, long)] + verbose: bool, + + // Nightly-only options. + + /// Limit formatting to specified ranges. + /// + /// If you want to restrict reformatting to specific sets of lines, you can + /// use the `--file-lines` option. Its argument is a JSON array of objects + /// with `file` and `range` properties, where `file` is a file name, and + /// `range` is an array representing a range of lines like `[7,13]`. Ranges + /// are 1-based and inclusive of both end points. Specifying an empty array + /// will result in no files being formatted. For example, + /// + /// ``` + /// rustfmt --file-lines '[ + /// {{\"file\":\"src/lib.rs\",\"range\":[7,13]}}, + /// {{\"file\":\"src/lib.rs\",\"range\":[21,29]}}, + /// {{\"file\":\"src/foo.rs\",\"range\":[10,11]}}, + /// {{\"file\":\"src/foo.rs\",\"range\":[15,15]}}]' + /// ``` + /// + /// would format lines `7-13` and `21-29` of `src/lib.rs`, and lines `10-11`, + /// and `15` of `src/foo.rs`. No other files would be formatted, even if they + /// are included as out of line modules from `src/lib.rs`. + #[cfg_attr(nightly, structopt(long = "file-lines", default_value = "null"))] + #[cfg_attr(not(nightly), structopt(skip))] + file_lines: FileLines, + + /// Error if unable to get comments or string literals within max_width, + /// or they are left with trailing whitespaces (unstable). + #[cfg_attr(nightly, structopt(long = "error_on_unformatted"))] + #[cfg_attr(not(nightly), structopt(skip))] + error_on_unformatted: bool, + + // Positional arguments. + + #[structopt(parse(from_os_str))] + files: Vec, +} + +#[derive(Debug, Clone)] +struct InlineConfig(HashMap, bool /* is help */); + +impl InlineConfig { + fn is_help(&self) -> bool { + self.1 + } +} + +impl FromStr for InlineConfig { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + if s.trim() == "help" { + return Ok(InlineConfig(HashMap::default(), true)); + } + + s.split(',') + .map( + |key_val| match key_val.char_indices().find(|(_, ch)| *ch == '=') { + Some((middle, _)) => { + let (key, val) = (&key_val[..middle], &key_val[middle + 1..]); + if !Config::is_valid_key_val(key, val) { + Err(format_err!("invalid key=val pair: `{}`", key_val)) + } else { + Ok((key.to_string(), val.to_string())) + } + } + + None => Err(format_err!( + "--config expects comma-separated list of key=val pairs, found `{}`", + key_val + )), + }, + ).collect::, _>>() + .map(|map| InlineConfig(map, false)) + } +} + +#[derive(Debug, Copy, Clone, PartialEq)] +enum PrintConfig { + Default, + Minimal, + Current, +} + +impl FromStr for PrintConfig { + type Err = String; + + fn from_str(s: &str) -> Result { + match s { + "default" => Ok(PrintConfig::Default), + "minimal" => Ok(PrintConfig::Minimal), + "current" => Ok(PrintConfig::Current), + _ => Err(format!("expected one of [current,default,minimal], found `{}`", s)), + } + } +} + +#[derive(Debug, Copy, Clone, PartialEq)] +pub enum Emit { + Files, + Stdout, + Checkstyle, + Json, +} + +impl Emit { + fn to_emit_mode(self) -> EmitMode { + match self { + Emit::Files => EmitMode::Files, + Emit::Json => EmitMode::Json, + Emit::Checkstyle => EmitMode::Checkstyle, + Emit::Stdout => EmitMode::Stdout, + } + } +} + +impl fmt::Display for Emit { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Emit::Files => f.write_str("files"), + Emit::Stdout => f.write_str("stdout"), + Emit::Checkstyle => f.write_str("checkstyle"), + Emit::Json => f.write_str("json"), + } + } +} + +impl FromStr for Emit { + type Err = String; + + fn from_str(s: &str) -> Result { + match s { + "files" => Ok(Emit::Files), + "stdout" => Ok(Emit::Stdout), + "checkstyle" => Ok(Emit::Checkstyle), + "json" => Ok(Emit::Json), + _ => Err(format!("unknown --emit mode: {}", s)), + } + } +} + +/// Rustfmt command line option errors. +#[derive(Error, Debug)] +enum OptError { + /// Attempt to use --quiet and --verbose at once. + #[error("--quiet and --verbose cannot be used at once.")] + QuietAndVerbose, + /// Attempt to use --emit and --check at once. + #[error("--emit and --check cannot be used at once.")] + EmitAndCheck, + /// Attempt to use --emit with a mode which is not currently + /// supported with standard input. + #[error("Emit mode {0} not supported with standard output.")] + StdinBadEmit(Emit), } +impl Opt { + fn canonicalize(&mut self) { + for f in &mut self.files { + if let Ok(canonical_path) = f.canonicalize() { + *f = canonical_path; + } + } + } + + fn verify(&self) -> Result<(), OptError> { + if self.quiet && self.verbose { + return Err(OptError::QuietAndVerbose); + } + + if self.check && self.emit.is_some() { + return Err(OptError::EmitAndCheck); + } + + if self.files.is_empty() { + match self.emit { + // Emit modes which work with standard input + // None means default, which is Stdout. + None | Some(Emit::Stdout) | Some(Emit::Checkstyle) | Some(Emit::Json) => {} + Some(emit_mode) => { + return Err(OptError::StdinBadEmit(emit_mode)); + } + } + } + + Ok(()) + } +} + + /// Rustfmt operations errors. #[derive(Error, Debug)] pub enum OperationError { @@ -69,10 +295,6 @@ pub enum OperationError { /// An io error during reading or writing. #[error("io error: {0}")] IoError(IoError), - /// Attempt to use --emit with a mode which is not currently - /// supported with stdandard input. - #[error("Emit mode {0} not supported with standard output.")] - StdinBadEmit(EmitMode), } impl From for OperationError { @@ -81,190 +303,103 @@ impl From for OperationError { } } -/// Arguments to `--help` -enum HelpOp { - None, - Config, - FileLines, -} - -fn make_opts() -> Options { - let mut opts = Options::new(); - - opts.optflag( - "", - "check", - "Run in 'check' mode. Exits with 0 if input is formatted correctly. Exits \ - with 1 and prints a diff if formatting is required.", - ); - let is_nightly = is_nightly(); - let emit_opts = if is_nightly { - "[files|stdout|coverage|checkstyle|json]" - } else { - "[files|stdout]" - }; - opts.optopt("", "emit", "What data to emit and how", emit_opts); - opts.optopt( - "", - "config-path", - "Recursively searches the given path for the rustfmt.toml config file. If not \ - found reverts to the input file path", - "[Path for the configuration file]", - ); - opts.optopt("", "edition", "Rust edition to use", "[2015|2018]"); - opts.optopt( - "", - "color", - "Use colored output (if supported)", - "[always|never|auto]", - ); - opts.optopt( - "", - "print-config", - "Dumps a default or minimal config to PATH. A minimal config is the \ - subset of the current config file used for formatting the current program. \ - `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. ", - ); - opts.optmulti( - "", - "config", - "Set options from command line. These settings take priority over .rustfmt.toml", - "[key1=val1,key2=val2...]", - ); - - if is_nightly { - opts.optflag( - "", - "unstable-features", - "Enables unstable features. Only available on nightly channel.", - ); - opts.optopt( - "", - "file-lines", - "Format specified line ranges. Run with `--help=file-lines` for \ - more detail (unstable).", - "JSON", - ); - opts.optflag( - "", - "error-on-unformatted", - "Error if unable to get comments or string literals within max_width, \ - or they are left with trailing whitespaces (unstable).", - ); - opts.optflag( - "", - "skip-children", - "Don't reformat child modules (unstable).", - ); - } - opts.optflag( - "r", - "recursive", - "Format all encountered modules recursively regardless of whether the modules\ - are defined inline or in another file", - ); - opts.optflag("v", "verbose", "Print verbose output"); - opts.optflag("q", "quiet", "Print less output"); - opts.optflag("V", "version", "Show version information"); - opts.optflagopt( - "h", - "help", - "Show this message or help about a specific topic: `config` or `file-lines`", - "=TOPIC", - ); - - opts -} - -fn is_nightly() -> bool { - option_env!("CFG_RELEASE_CHANNEL").map_or(true, |c| c == "nightly" || c == "dev") -} - -// Returned i32 is an exit code -fn execute(opts: &Options) -> Result { - let matches = opts.parse(env::args().skip(1))?; - let options = GetOptsOptions::from_matches(&matches)?; - - match determine_operation(&matches)? { - Operation::Help(HelpOp::None) => { - print_usage_to_stdout(opts, ""); - Ok(0) +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); } - Operation::Help(HelpOp::Config) => { - Config::print_docs(&mut stdout(), options.unstable_features); - Ok(0) + config.set().file_lines(self.file_lines.clone()); + if self.recursive { + config.set().recursive(true); } - Operation::Help(HelpOp::FileLines) => { - print_help_file_lines(); - Ok(0) + if self.error_on_unformatted { + config.set().error_on_unformatted(true); } - Operation::Version => { - print_version(); - Ok(0) + if let Some(ref edition) = self.edition { + config.set().edition((*edition).clone()); } - Operation::ConfigOutputDefault { path } => { - let toml = Config::default().all_options().to_toml()?; - if let Some(path) = path { - let mut file = std::fs::File::create(path)?; - file.write_all(toml.as_bytes())?; - } else { - io::stdout().write_all(toml.as_bytes())?; + 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 { + config.override_value(k, v); + } } - Ok(0) } - Operation::ConfigOutputCurrent { path } => { - let path = match path { - Some(path) => path, - None => return Err(format_err!("PATH required for `--print-config current`")), - }; + } - let file = PathBuf::from(path); - let file = file.canonicalize().unwrap_or(file); + fn config_path(&self) -> Option<&Path> { + self.config_path.as_ref().map(PathBuf::as_path) + } +} + +// Returned i32 is an exit code +fn execute(mut opt: Opt) -> Result { + opt.verify()?; + + if opt.inline_config.as_ref().map_or(false, |inline_configs| inline_configs.iter().any(InlineConfig::is_help)) { + Config::print_docs(&mut stdout(), cfg!(nightly)); + return Ok(0); + } - let (config, _) = load_config(Some(file.parent().unwrap()), Some(options))?; - let toml = config.all_options().to_toml()?; - io::stdout().write_all(toml.as_bytes())?; + opt.canonicalize(); - Ok(0) - } - Operation::Stdin { input } => format_string(input, options), - Operation::Format { - files, - minimal_config_path, - } => format(files, minimal_config_path, &options), + match opt.print_config { + Some(PrintConfig::Default) => print_default_config(), + Some(PrintConfig::Minimal) => print_config(&opt, PrintConfig::Minimal), + Some(PrintConfig::Current) => print_config(&opt, PrintConfig::Current), + None => format(opt), } } -fn format_string(input: String, options: GetOptsOptions) -> Result { +fn print_default_config() -> Result { + let toml = Config::default().all_options().to_toml()?; + io::stdout().write_all(toml.as_bytes())?; + Ok(0) +} + +fn print_config(opt: &Opt, print_config: PrintConfig) -> Result { + let (config, config_path) = + load_config(env::current_dir().ok().as_ref().map(PathBuf::as_path), Some(opt))?; + let actual_config = FileConfigPairIter::new(&opt, config_path.is_some()) + .find_map(|pair| match pair.config { + FileConfig::Local(config, Some(_)) => Some(config), + _ => None, + }); + let used_config = actual_config.unwrap_or(config); + let toml = if print_config == PrintConfig::Minimal { + used_config.used_options().to_toml()? + } else { + used_config.all_options().to_toml()? + }; + io::stdout().write_all(toml.as_bytes())?; + Ok(0) +} + +fn format_string(input: String, opt: Opt) -> Result { // try to read config from local directory - let (mut config, _) = load_config(Some(Path::new(".")), Some(options.clone()))?; + let (mut config, _) = load_config(Some(Path::new(".")), Some(&opt))?; - if options.check { + if opt.check { config.set().emit_mode(EmitMode::Diff); } else { - match options.emit_mode { - // Emit modes which work with standard input - // None means default, which is Stdout. - None | Some(EmitMode::Stdout) | Some(EmitMode::Checkstyle) | Some(EmitMode::Json) => {} - Some(emit_mode) => { - return Err(OperationError::StdinBadEmit(emit_mode).into()); - } - } config .set() - .emit_mode(options.emit_mode.unwrap_or(EmitMode::Stdout)); + .emit_mode(opt.emit.map_or(EmitMode::Stdout, Emit::to_emit_mode)); } config.set().verbose(Verbosity::Quiet); // parse file_lines - config.set().file_lines(options.file_lines); + config.set().file_lines(opt.file_lines); for f in config.file_lines().files() { match *f { FileName::Stdin => {} @@ -284,13 +419,61 @@ fn format_string(input: String, options: GetOptsOptions) -> Result { Ok(exit_code) } +enum FileConfig { + Default, + Local(Config, Option), +} + +struct FileConfigPair<'a> { + file: &'a Path, + config: FileConfig, +} + +struct FileConfigPairIter<'a> { + has_config_from_commandline: bool, + files: std::slice::Iter<'a, PathBuf>, + opt: &'a Opt, +} + +impl<'a> FileConfigPairIter<'a> +{ + fn new(opt: &'a Opt, has_config_from_commandline: bool) -> Self { + FileConfigPairIter { + has_config_from_commandline, + files: opt.files.iter(), + opt, + } + } +} + +impl<'a> Iterator for FileConfigPairIter<'a> +{ + type Item = FileConfigPair<'a>; + + fn next(&mut self) -> Option { + let file = self.files.next()?; + let config = if self.has_config_from_commandline { + FileConfig::Default + } else { + let (local_config, config_path) = + load_config(Some(file.parent()?), Some(self.opt)).ok()?; + FileConfig::Local(local_config, config_path) + }; + + Some(FileConfigPair {file, config}) + } +} + fn format( - files: Vec, - minimal_config_path: Option, - options: &GetOptsOptions, + opt: Opt, ) -> Result { - options.verify_file_lines(&files); - let (config, config_path) = load_config(None, Some(options.clone()))?; + if opt.files.is_empty() { + let mut buf = String::new(); + stdin().read_to_string(&mut buf)?; + return format_string(buf, opt); + } + + let (config, config_path) = load_config(None, Some(&opt))?; if config.verbose() == Verbosity::Verbose { if let Some(path) = config_path.as_ref() { @@ -301,7 +484,9 @@ fn format( let out = &mut stdout(); let mut session = Session::new(config, Some(out)); - for file in files { + for pair in FileConfigPairIter::new(&opt, config_path.is_some()) { + let file = pair.file; + if !file.exists() { eprintln!("Error: file `{}` does not exist", file.display()); session.add_operational_error(); @@ -309,12 +494,9 @@ fn format( eprintln!("Error: `{}` is a directory", file.display()); session.add_operational_error(); } else { - // Check the file directory if the config-path could not be read or not provided - if config_path.is_none() { - let (local_config, config_path) = - load_config(Some(file.parent().unwrap()), Some(options.clone()))?; - if local_config.verbose() == Verbosity::Verbose { - if let Some(path) = config_path { + 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(), @@ -324,25 +506,17 @@ fn format( } session.override_config(local_config, |sess| { - format_and_emit_report(sess, Input::File(file)) + format_and_emit_report(sess, Input::File(file.to_path_buf())) }); } else { - format_and_emit_report(&mut session, Input::File(file)); + format_and_emit_report(&mut session, Input::File(file.to_path_buf())); } } } - // If we were given a path via dump-minimal-config, output any options - // that were used during formatting as TOML. - if let Some(path) = minimal_config_path { - let mut file = std::fs::File::create(path)?; - let toml = session.config.used_options().to_toml()?; - file.write_all(toml.as_bytes())?; - } - let exit_code = if session.has_operational_errors() || session.has_parsing_errors() - || ((session.has_diff() || session.has_check_errors()) && options.check) + || ((session.has_diff() || session.has_check_errors()) && opt.check) { 1 } else { @@ -383,345 +557,6 @@ fn should_print_with_colors(session: &mut Session<'_, T>) -> bool { } } -fn print_usage_to_stdout(opts: &Options, reason: &str) { - let sep = if reason.is_empty() { - String::new() - } else { - format!("{}\n\n", reason) - }; - let msg = format!( - "{}Format Rust code\n\nusage: {} [options] ...", - sep, - env::args_os().next().unwrap().to_string_lossy() - ); - println!("{}", opts.usage(&msg)); -} - -fn print_help_file_lines() { - println!( - "If you want to restrict reformatting to specific sets of lines, you can -use the `--file-lines` option. Its argument is a JSON array of objects -with `file` and `range` properties, where `file` is a file name, and -`range` is an array representing a range of lines like `[7,13]`. Ranges -are 1-based and inclusive of both end points. Specifying an empty array -will result in no files being formatted. For example, - -``` -rustfmt --file-lines '[ - {{\"file\":\"src/lib.rs\",\"range\":[7,13]}}, - {{\"file\":\"src/lib.rs\",\"range\":[21,29]}}, - {{\"file\":\"src/foo.rs\",\"range\":[10,11]}}, - {{\"file\":\"src/foo.rs\",\"range\":[15,15]}}]' -``` - -would format lines `7-13` and `21-29` of `src/lib.rs`, and lines `10-11`, -and `15` of `src/foo.rs`. No other files would be formatted, even if they -are included as out of line modules from `src/lib.rs`." - ); -} - -fn print_version() { - let version_info = format!( - "{}-{}", - option_env!("CARGO_PKG_VERSION").unwrap_or("unknown"), - include_str!(concat!(env!("OUT_DIR"), "/commit-info.txt")) - ); - - println!("rustfmt {}", version_info); -} - -fn determine_operation(matches: &Matches) -> Result { - if matches.opt_present("h") { - let topic = matches.opt_str("h"); - if topic == None { - return Ok(Operation::Help(HelpOp::None)); - } else if topic == Some("config".to_owned()) { - return Ok(Operation::Help(HelpOp::Config)); - } else if topic == Some("file-lines".to_owned()) { - return Ok(Operation::Help(HelpOp::FileLines)); - } else { - return Err(OperationError::UnknownHelpTopic(topic.unwrap())); - } - } - let mut free_matches = matches.free.iter(); - - let mut minimal_config_path = None; - if let Some(kind) = matches.opt_str("print-config") { - let path = free_matches.next().cloned(); - match kind.as_str() { - "default" => return Ok(Operation::ConfigOutputDefault { path }), - "current" => return Ok(Operation::ConfigOutputCurrent { path }), - "minimal" => { - minimal_config_path = path; - if minimal_config_path.is_none() { - eprintln!("WARNING: PATH required for `--print-config minimal`."); - } - } - _ => { - return Err(OperationError::UnknownPrintConfigTopic(kind)); - } - } - } - - if matches.opt_present("version") { - return Ok(Operation::Version); - } - - let files: Vec<_> = free_matches - .map(|s| { - let p = PathBuf::from(s); - // we will do comparison later, so here tries to canonicalize first - // to get the expected behavior. - p.canonicalize().unwrap_or(p) - }) - .collect(); - - // if no file argument is supplied, read from stdin - if files.is_empty() { - if minimal_config_path.is_some() { - return Err(OperationError::MinimalPathWithStdin); - } - let mut buffer = String::new(); - io::stdin().read_to_string(&mut buffer)?; - - return Ok(Operation::Stdin { input: buffer }); - } - - Ok(Operation::Format { - files, - minimal_config_path, - }) -} - -const STABLE_EMIT_MODES: [EmitMode; 3] = [EmitMode::Files, EmitMode::Stdout, EmitMode::Diff]; - -/// Parsed command line options. -#[derive(Clone, Debug, Default)] -struct GetOptsOptions { - skip_children: Option, - recursive: Option, - quiet: bool, - verbose: bool, - config_path: Option, - inline_config: HashMap, - emit_mode: Option, - check: bool, - edition: Option, - color: Option, - file_lines: FileLines, // Default is all lines in all files. - unstable_features: bool, - error_on_unformatted: Option, - print_misformatted_file_names: bool, -} - -fn deprecate_skip_children() { - let msg = "Option --skip-children is deprecated since it is now the default to not format \ - submodules of given files (#3587)"; - eprintln!("{}: {}", Red.bold().paint("Deprecation"), msg); -} - -impl GetOptsOptions { - pub fn from_matches(matches: &Matches) -> Result { - let mut options = GetOptsOptions::default(); - options.verbose = matches.opt_present("verbose"); - options.quiet = matches.opt_present("quiet"); - if options.verbose && options.quiet { - return Err(format_err!("Can't use both `--verbose` and `--quiet`")); - } - - let rust_nightly = is_nightly(); - - if rust_nightly { - options.unstable_features = matches.opt_present("unstable-features"); - - if options.unstable_features { - if matches.opt_present("skip-children") { - deprecate_skip_children(); - options.skip_children = Some(true); - } - if matches.opt_present("error-on-unformatted") { - options.error_on_unformatted = Some(true); - } - if let Some(ref file_lines) = matches.opt_str("file-lines") { - options.file_lines = file_lines.parse()?; - } - } else { - let mut unstable_options = vec![]; - if matches.opt_present("skip-children") { - deprecate_skip_children(); - unstable_options.push("`--skip-children`"); - } - if matches.opt_present("error-on-unformatted") { - unstable_options.push("`--error-on-unformatted`"); - } - if matches.opt_present("file-lines") { - unstable_options.push("`--file-lines`"); - } - if !unstable_options.is_empty() { - let s = if unstable_options.len() == 1 { "" } else { "s" }; - return Err(format_err!( - "Unstable option{} ({}) used without `--unstable-features`", - s, - unstable_options.join(", "), - )); - } - } - } - - if matches.opt_present("recursive") { - if let Some(true) = options.skip_children { - return Err(format_err!( - "Conflicting options `skip_children` and `recursive` were specified. \ - `skip_children` has been deprecated and should no longer be used. ", - )); - } - options.recursive = Some(true); - } - - options.config_path = matches.opt_str("config-path").map(PathBuf::from); - - options.inline_config = matches - .opt_strs("config") - .iter() - .flat_map(|config| config.split(',')) - .map( - |key_val| match key_val.char_indices().find(|(_, ch)| *ch == '=') { - Some((middle, _)) => { - let (key, val) = (&key_val[..middle], &key_val[middle + 1..]); - if !Config::is_valid_key_val(key, val) { - Err(format_err!("invalid key=val pair: `{}`", key_val)) - } else { - Ok((key.to_string(), val.to_string())) - } - } - - None => Err(format_err!( - "--config expects comma-separated list of key=val pairs, found `{}`", - key_val - )), - }, - ) - .collect::, _>>()?; - - options.check = matches.opt_present("check"); - if let Some(ref emit_str) = matches.opt_str("emit") { - if options.check { - return Err(format_err!("Invalid to use `--emit` and `--check`")); - } - - options.emit_mode = Some(emit_mode_from_emit_str(emit_str)?); - } - - if let Some(ref edition_str) = matches.opt_str("edition") { - options.edition = Some(edition_from_edition_str(edition_str)?); - } - - if matches.opt_present("files-with-diff") { - options.print_misformatted_file_names = true; - } - - if !rust_nightly { - if let Some(ref emit_mode) = options.emit_mode { - if !STABLE_EMIT_MODES.contains(emit_mode) { - return Err(format_err!( - "Invalid value for `--emit` - using an unstable \ - value without `--unstable-features`", - )); - } - } - } - - if let Some(ref color) = matches.opt_str("color") { - match Color::from_str(color) { - Ok(color) => options.color = Some(color), - _ => return Err(format_err!("Invalid color: {}", color)), - } - } - - Ok(options) - } - - fn verify_file_lines(&self, files: &[PathBuf]) { - for f in self.file_lines.files() { - match *f { - FileName::Real(ref f) if files.contains(f) => {} - FileName::Real(_) => { - eprintln!("Warning: Extra file listed in file_lines option '{}'", f) - } - FileName::Stdin => eprintln!("Warning: Not a file '{}'", f), - } - } - } -} - -impl CliOptions for GetOptsOptions { - fn apply_to(self, config: &mut Config) { - if self.verbose { - config.set().verbose(Verbosity::Verbose); - } else if self.quiet { - config.set().verbose(Verbosity::Quiet); - } else { - config.set().verbose(Verbosity::Normal); - } - config.set().file_lines(self.file_lines); - config.set().unstable_features(self.unstable_features); - if let Some(skip_children) = self.skip_children { - config.set().skip_children(skip_children); - } - if let Some(recursive) = self.recursive { - config.set().recursive(recursive); - } - if let Some(error_on_unformatted) = self.error_on_unformatted { - config.set().error_on_unformatted(error_on_unformatted); - } - if let Some(edition) = self.edition { - config.set().edition(edition); - } - if self.check { - config.set().emit_mode(EmitMode::Diff); - } else if let Some(emit_mode) = self.emit_mode { - config.set().emit_mode(emit_mode); - } - if let Some(color) = self.color { - config.set().color(color); - } - if self.print_misformatted_file_names { - config.set().print_misformatted_file_names(true); - } - - for (key, val) in self.inline_config { - config.override_value(&key, &val); - } - } - - fn config_path(&self) -> Option<&Path> { - self.config_path.as_ref().map(|p| &**p) - } -} - -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), - "stdout" => Ok(EmitMode::Stdout), - "coverage" => Ok(EmitMode::Coverage), - "checkstyle" => Ok(EmitMode::Checkstyle), - "json" => Ok(EmitMode::Json), - _ => Err(format_err!("Invalid value for `--emit`")), - } -} - -#[cfg(test)] -#[macro_use] -extern crate lazy_static; - #[cfg(test)] mod test { use super::*; diff --git a/rustfmt-core/rustfmt-bin/tests/cargo-fmt/main.rs b/rustfmt-core/rustfmt-bin/tests/cargo-fmt/main.rs index 5493b09e4aa..d5b2c9bde0f 100644 --- a/rustfmt-core/rustfmt-bin/tests/cargo-fmt/main.rs +++ b/rustfmt-core/rustfmt-bin/tests/cargo-fmt/main.rs @@ -69,5 +69,5 @@ fn print_config() { fn rustfmt_help() { assert_that!(&["--", "--help"], contains("Format Rust code")); assert_that!(&["--", "-h"], contains("Format Rust code")); - assert_that!(&["--", "--help=config"], contains("Configuration Options:")); + assert_that!(&["--", "--config", "help"], contains("Configuration Options:")); } diff --git a/rustfmt-core/rustfmt-bin/tests/rustfmt/main.rs b/rustfmt-core/rustfmt-bin/tests/rustfmt/main.rs index 8effb1c6fca..a64db645c4a 100644 --- a/rustfmt-core/rustfmt-bin/tests/rustfmt/main.rs +++ b/rustfmt-core/rustfmt-bin/tests/rustfmt/main.rs @@ -1,8 +1,6 @@ //! Integration tests for rustfmt. use std::env; -use std::fs::remove_file; -use std::path::Path; use std::process::Command; /// Run the rustfmt executable and return its output. @@ -52,28 +50,13 @@ macro_rules! assert_that { fn print_config() { assert_that!( &["--print-config", "unknown"], - starts_with("Unknown print-config option") + starts_with("error: Invalid value for '--print-config") ); assert_that!(&["--print-config", "default"], contains("max_width = 100")); - assert_that!(&["--print-config", "minimal"], contains("PATH required")); - assert_that!( - &["--print-config", "minimal", "minimal-config"], - contains("doesn't work with standard input.") - ); - - let (stdout, stderr) = rustfmt(&[ - "--print-config", - "minimal", - "minimal-config", - "src/shape.rs", - ]); - assert!( - Path::new("minimal-config").exists(), - "stdout:\n{}\nstderr:\n{}", - stdout, - stderr - ); - remove_file("minimal-config").unwrap(); + assert_that!(&["--print-config", "current"], contains("max_width = 100")); + assert_that!(&["--config", "max_width=120", "--print-config", "current"], contains("max_width = 120")); + assert_that!(&["--config", "max_width=120", "--print-config", "minimal"], contains("max_width = 120")); + assert_that!(&["--config", "max_width=100", "--print-config", "minimal"], eq("")); } #[ignore] From e255052c3b745fe557dc3922cf7ec18769cb9aff Mon Sep 17 00:00:00 2001 From: topecongiro Date: Wed, 8 Jan 2020 23:01:37 +0900 Subject: [PATCH 11/15] Upate Cargo.toml Remove unused dependencies and use optional dependencies. --- Cargo.toml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 59c3945cfec..a3c33c836cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,24 +33,23 @@ test = false [features] default = ["cargo-fmt", "rustfmt-format-diff"] -cargo-fmt = [] -rustfmt-format-diff = [] +cargo-fmt = ["cargo_metadata"] +rustfmt-format-diff = ["regex", "serde", "serde_json"] generic-simd = ["rustfmt_lib/generic-simd"] [dependencies] -ansi_term = "0.12" anyhow = "1.0" -cargo_metadata = "0.9" env_logger = "0.7" -getopts = "0.2" log = "0.4" -regex = "1.0" -serde = "1.0" -serde_json = "1.0" structopt = "0.3" term = "0.6" thiserror = "1.0" +cargo_metadata = { version = "0.9", optional = true } +regex = { version = "1.0", optional = true } +serde = { version = "1.0", optional = true } +serde_json = { version = "1.0", optional = true } + rustfmt_lib = { path = "rustfmt-core/rustfmt-lib", version = "2.0.0-rc.1" } [dev-dependencies] From 265697c232cfd6b65262995512d0e7028f2571aa Mon Sep 17 00:00:00 2001 From: topecongiro Date: Wed, 8 Jan 2020 23:02:01 +0900 Subject: [PATCH 12/15] Update Cargo.lock --- Cargo.lock | 31 +++++-------------------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 032d52f06a8..18348b2b661 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,7 +15,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7021ce4924a3f25f802b2cccd1af585e39ea1a363a1aa2e72afe54b67a3a7a7" dependencies = [ - "ansi_term 0.11.0", + "ansi_term", ] [[package]] @@ -27,15 +27,6 @@ dependencies = [ "winapi 0.3.8", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi 0.3.8", -] - [[package]] name = "anyhow" version = "1.0.26" @@ -172,7 +163,7 @@ version = "2.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" dependencies = [ - "ansi_term 0.11.0", + "ansi_term", "atty", "bitflags", "strsim", @@ -349,15 +340,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -[[package]] -name = "getopts" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" -dependencies = [ - "unicode-width", -] - [[package]] name = "getrandom" version = "0.1.13" @@ -901,11 +883,9 @@ dependencies = [ name = "rustfmt-nightly" version = "2.0.0-rc.1" dependencies = [ - "ansi_term 0.12.1", "anyhow", "cargo_metadata", "env_logger", - "getopts", "lazy_static", "log", "regex", @@ -920,9 +900,8 @@ dependencies = [ [[package]] name = "rustfmt_configuration" -version = "1.0.0" +version = "2.0.0-rc.1" dependencies = [ - "ansi_term 0.12.1", "dirs", "itertools", "regex", @@ -936,7 +915,7 @@ dependencies = [ [[package]] name = "rustfmt_emitter" -version = "1.0.0" +version = "2.0.0-rc.1" dependencies = [ "diff", "rustfmt_configuration", @@ -965,7 +944,7 @@ dependencies = [ [[package]] name = "rustfmt_lib" -version = "1.0.0" +version = "2.0.0-rc.1" dependencies = [ "annotate-snippets", "anyhow", From d961464e867088133de884454e151b524fced757 Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Sat, 11 Jan 2020 17:59:58 +0900 Subject: [PATCH 13/15] Update rustfmt-core/rustfmt-bin/src/bin/main.rs Co-Authored-By: Caleb Cartwright --- rustfmt-core/rustfmt-bin/src/bin/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rustfmt-core/rustfmt-bin/src/bin/main.rs b/rustfmt-core/rustfmt-bin/src/bin/main.rs index 4c24f42dcb2..64f18938988 100644 --- a/rustfmt-core/rustfmt-bin/src/bin/main.rs +++ b/rustfmt-core/rustfmt-bin/src/bin/main.rs @@ -64,7 +64,7 @@ struct Opt { /// /// `default` will print the default configuration options. `current` will print the /// current configuration options. `minimal` will print the minimal subset of the - /// current configuration options. + /// current configuration options that have non-default values. #[structopt(long = "print-config", name = "default|current|minimal")] print_config: Option, /// Prints the names of files with diff. From f73785c1dd5ea15c3d33f27f67f26d363310a807 Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Sat, 11 Jan 2020 18:02:38 +0900 Subject: [PATCH 14/15] Update rustfmt-core/rustfmt-bin/src/bin/main.rs Co-Authored-By: Caleb Cartwright --- rustfmt-core/rustfmt-bin/src/bin/main.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rustfmt-core/rustfmt-bin/src/bin/main.rs b/rustfmt-core/rustfmt-bin/src/bin/main.rs index 64f18938988..fb6bf8aebac 100644 --- a/rustfmt-core/rustfmt-bin/src/bin/main.rs +++ b/rustfmt-core/rustfmt-bin/src/bin/main.rs @@ -50,7 +50,8 @@ struct Opt { #[structopt(short, long)] check: bool, /// Specify the format of rustfmt's output. - #[structopt(long)] + #[cfg_attr(nightly, structopt(long, name= "files|stdout|checkstyle|json"))] + #[cfg_attr(not(nightly), structopt(long, name= "files|stdout"))] emit: Option, /// A path to the configuration file. #[structopt(long = "config-path", parse(from_os_str))] From 6e5e6df4047e4a9a3a284602fbaf4f9b5e07be86 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Sat, 11 Jan 2020 18:02:33 +0900 Subject: [PATCH 15/15] Remove skip_children --- rustfmt-core/rustfmt-config/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/rustfmt-core/rustfmt-config/src/lib.rs b/rustfmt-core/rustfmt-config/src/lib.rs index d2826677aa6..3bd37d75c97 100644 --- a/rustfmt-core/rustfmt-config/src/lib.rs +++ b/rustfmt-core/rustfmt-config/src/lib.rs @@ -127,7 +127,6 @@ create_config! { unstable_features: bool, false, false, "Enables unstable features. Only available on nightly channel"; disable_all_formatting: bool, false, false, "Don't reformat anything"; - skip_children: bool, false, false, "Don't reformat out of line modules"; hide_parse_errors: bool, false, false, "Hide errors from the parser"; error_on_line_overflow: bool, false, false, "Error if unable to get all lines within max_width"; error_on_unformatted: bool, false, false,