From 5f49587a2cdcb74727c63516e589b3a047d547a1 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Fri, 23 Feb 2018 21:54:59 +0900 Subject: [PATCH 1/2] Update configuration tests This commit adds following functionalities to `configuration_snippet_tests`: 1. Error if there is an unknown configuration option in Configuration.md. 2. Error if there are multiple guides for the same configuration option in Configuration.md. 3. Error if an user-facing configuration option does not have its guide in Configuration.md. We will be able to catch outdated Configuration.md. Should prevent issues like #2459. --- rustfmt-config/src/config_type.rs | 39 ++++++++++++++++++++++--------- rustfmt-core/tests/lib.rs | 24 +++++++++++++++++-- 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/rustfmt-config/src/config_type.rs b/rustfmt-config/src/config_type.rs index 2bc9ceace87..bace9dba8ff 100644 --- a/rustfmt-config/src/config_type.rs +++ b/rustfmt-config/src/config_type.rs @@ -74,6 +74,8 @@ macro_rules! is_nightly_channel { macro_rules! create_config { ($($i:ident: $ty:ty, $def:expr, $stb:expr, $( $dstring:expr ),+ );+ $(;)*) => ( + use std::collections::HashSet; + #[derive(Clone)] pub struct Config { // For each config item, we store a bool indicating whether it has @@ -190,6 +192,24 @@ macro_rules! create_config { self } + /// Returns a hash set initialized with every user-facing config option name. + pub fn hash_set() -> HashSet { + let mut hash_set = HashSet::new(); + $( + hash_set.insert(stringify!($i).to_owned()); + )+ + hash_set + } + + pub fn is_valid_name(name: &str) -> bool { + match name { + $( + stringify!($i) => true, + )+ + _ => false, + } + } + pub fn from_toml(toml: &str) -> Result { let parsed: toml::Value = toml.parse().map_err(|e| format!("Could not parse TOML: {}", e))?; @@ -199,15 +219,9 @@ macro_rules! create_config { .as_table() .ok_or(String::from("Parsed config was not table"))?; for key in table.keys() { - match &**key { - $( - stringify!($i) => (), - )+ - _ => { - let msg = - &format!("Warning: Unknown configuration option `{}`\n", key); - err.push_str(msg) - } + if !Config::is_valid_name(key) { + let msg = &format!("Warning: Unknown configuration option `{}`\n", key); + err.push_str(msg) } } } @@ -324,10 +338,13 @@ macro_rules! create_config { } } + pub fn is_hidden_option(name: &str) -> bool { + const HIDE_OPTIONS: [&str; 3] = ["verbose", "file_lines", "width_heuristics"]; + HIDE_OPTIONS.contains(&name) + } pub fn print_docs() { use std::cmp; - const HIDE_OPTIONS: [&str; 3] = ["verbose", "file_lines", "width_heuristics"]; let max = 0; $( let max = cmp::max(max, stringify!($i).len()+1); )+ let mut space_str = String::with_capacity(max); @@ -338,7 +355,7 @@ macro_rules! create_config { $( let name_raw = stringify!($i); - if !HIDE_OPTIONS.contains(&name_raw) { + if !Config::is_hidden_option(name_raw) { let mut name_out = String::with_capacity(max); for _ in name_raw.len()..max-1 { name_out.push(' ') diff --git a/rustfmt-core/tests/lib.rs b/rustfmt-core/tests/lib.rs index f219cf3212b..00988dc6fc5 100644 --- a/rustfmt-core/tests/lib.rs +++ b/rustfmt-core/tests/lib.rs @@ -17,7 +17,7 @@ extern crate rustfmt_config as config; extern crate rustfmt_core as rustfmt; extern crate term; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::fs; use std::io::{self, BufRead, BufReader, Read}; use std::iter::{Enumerate, Peekable}; @@ -795,6 +795,7 @@ impl ConfigCodeBlock { fn extract>( file: &mut Enumerate, prev: Option<&ConfigCodeBlock>, + hash_set: &mut HashSet, ) -> Option { let mut code_block = ConfigCodeBlock::new(); code_block.config_name = prev.and_then(|cb| cb.config_name.clone()); @@ -806,6 +807,16 @@ impl ConfigCodeBlock { break; } Some(ConfigurationSection::ConfigName(name)) => { + assert!( + Config::is_valid_name(&name), + "an unknown configuration option was found: {}", + name + ); + assert!( + hash_set.remove(&name), + "multiple configuration guides found for option {}", + name + ); code_block.set_config_name(Some(name)); } Some(ConfigurationSection::ConfigValue(value)) => { @@ -831,11 +842,20 @@ fn configuration_snippet_tests() { .map(|l| l.unwrap()) .enumerate(); let mut code_blocks: Vec = Vec::new(); + let mut hash_set = Config::hash_set(); - while let Some(cb) = ConfigCodeBlock::extract(&mut file_iter, code_blocks.last()) { + while let Some(cb) = + ConfigCodeBlock::extract(&mut file_iter, code_blocks.last(), &mut hash_set) + { code_blocks.push(cb); } + for name in hash_set { + if !Config::is_hidden_option(&name) { + panic!("{} does not have a configuration guide", name); + } + } + code_blocks } From 34f6408ea2f0cf0b66eea083169217399b77ff96 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Fri, 23 Feb 2018 21:55:16 +0900 Subject: [PATCH 2/2] Update Configurations.md --- Configurations.md | 119 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 113 insertions(+), 6 deletions(-) diff --git a/Configurations.md b/Configurations.md index 18e57e1983a..324546f5a0d 100644 --- a/Configurations.md +++ b/Configurations.md @@ -579,7 +579,7 @@ Don't reformat anything ## `error_on_line_overflow` -Error if unable to get all lines within `max_width` +Error if unable to get all lines within `max_width`, except for comments and string literals. - **Default value**: `true` - **Possible values**: `true`, `false` @@ -587,16 +587,15 @@ Error if unable to get all lines within `max_width` See also [`max_width`](#max_width). -## `error_on_line_overflow_comments` +## `error_on_unformatted` -Error if unable to get all comment lines within `comment_width`. +Error if unable to get comments or string literals within `max_width`, or they are left with +trailing whitespaces. -- **Default value**: `true` +- **Default value**: `false` - **Possible values**: `true`, `false` - **Stable**: No -See also [`comment_width`](#comment_width). - ## `fn_args_density` Argument density in functions @@ -1379,6 +1378,41 @@ extern crate sit; This value has no influence beyond the effect of the [`reorder_extern_crates`](#reorder_extern_crates) option. Set [`reorder_extern_crates`](#reorder_extern_crates) to `false` if you do not want `extern crate` groups to be collapsed and ordered. +## `reorder_modules` + +Reorder `mod` declarations alphabetically in group. + +- **Default value**: `true` +- **Possible values**: `true`, `false` +- **Stable**: No + +#### `true` + +```rust +mod a; +mod b; + +mod dolor; +mod ipsum; +mod lorem; +mod sit; +``` + +#### `false` + +```rust +mod b; +mod a; + +mod lorem; +mod ipsum; +mod dolor; +mod sit; +``` + +**Note** `mod` with `#[macro_export]` will not be reordered since that could change the semantic +of the original source code. + ## `report_todo` Report `TODO` items in comments. @@ -2008,3 +2042,76 @@ fn bar() { println!("c"); } ``` + +## `remove_blank_lines_at_start_or_end_of_block` + +Remove blank lines at the start or the end of a block. + +- **Default value**: `true` +- **Possible values**: `true`, `false` +- **Stable**: No + +#### `true` + +```rust +fn foo() { + let msg = { + let mut str = String::new(); + str.push_str("hello, "); + str.push_str("world!"); + str + }; + println!("{}", msg); +} +``` + +#### `false` + +```rust +fn foo() { + + let msg = { + + let mut str = String::new(); + str.push_str("hello, "); + str.push_str("world!"); + str + + }; + println!("{}", msg); + +} +``` + +## `required_version` + +Require a specific version of rustfmt. If you want to make sure that the +specific version of rustfmt is used in your CI, use this option. + +- **Default value**: `CARGO_PKG_VERSION` +- **Possible values**: any published version (e.g. `"0.3.8"`) +- **Stable**: No + +## `hide_parse_errors` + +Do not show parse errors if the parser failed to parse files. + +- **Default value**: `false` +- **Possible values**: `true`, `false` +- **Stable**: No + +## `color` + +Whether to use colored output or not. + +- **Default value**: `"Auto"` +- **Possible values**: "Auto", "Always", "Never" +- **Stable**: No + +## `unstable_features` + +Enable unstable featuers on stable channel. + +- **Default value**: `false` +- **Possible values**: `true`, `false` +- **Stable**: Yes