about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNick Cameron <nrc@ncameron.org>2018-02-25 12:46:07 +1300
committerGitHub <noreply@github.com>2018-02-25 12:46:07 +1300
commit4d3b73e075193f2e575d93bfa2bcddab422af55d (patch)
tree6b0cde34d7718c3ae323b251bdd76ce3c4eb5d4d
parenteea5dcac4661877dc5e1921eb201102c903f21e6 (diff)
parent34f6408ea2f0cf0b66eea083169217399b77ff96 (diff)
Merge pull request #2483 from topecongiro/error-on-unknown-config-name-in-configurations
Error on outdated Configurations.md
-rw-r--r--Configurations.md119
-rw-r--r--rustfmt-config/src/config_type.rs39
-rw-r--r--rustfmt-core/tests/lib.rs24
3 files changed, 163 insertions, 19 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
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<String> {
+                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<Config, String> {
                 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<I: Iterator<Item = String>>(
         file: &mut Enumerate<I>,
         prev: Option<&ConfigCodeBlock>,
+        hash_set: &mut HashSet<String>,
     ) -> Option<ConfigCodeBlock> {
         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<ConfigCodeBlock> = 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
     }