]> git.lizzy.rs Git - rust.git/blobdiff - src/config/mod.rs
refactor: apply rustc mod parsing changes
[rust.git] / src / config / mod.rs
index 82a7f5fc39a24b2dc52c073e04aa1e1a9b3c47eb..dfce7977bfea1e06d4b9df2b72e931b6336e47fb 100644 (file)
@@ -6,6 +6,7 @@
 use std::{env, fs};
 
 use regex::Regex;
+use thiserror::Error;
 
 use crate::config::config_type::ConfigType;
 #[allow(unreachable_pub)]
@@ -40,7 +41,7 @@
 
     // Comments. macros, and strings
     wrap_comments: bool, false, false, "Break comments to fit on the line";
-    format_doc_comments: bool, false, false, "Format doc comments.";
+    format_code_in_doc_comments: bool, false, false, "Format the code snippet in doc comments.";
     comment_width: usize, 80, false,
         "Maximum length of comments. No effect unless wrap_comments = true";
     normalize_comments: bool, false, false, "Convert /* */ comments to // comments where possible";
     // Imports
     imports_indent: IndentStyle, IndentStyle::Block, false, "Indent of imports";
     imports_layout: ListTactic, ListTactic::Mixed, false, "Item layout inside a import block";
-    merge_imports: bool, false, false, "Merge imports";
+    imports_granularity: ImportGranularity, ImportGranularity::Preserve, false,
+        "Merge or split imports to the provided granularity";
+    group_imports: GroupImportsTactic, GroupImportsTactic::Preserve, false,
+        "Controls the strategy for how imports are grouped together";
+    merge_imports: bool, false, false, "(deprecated: use imports_granularity instead)";
 
     // Ordering
     reorder_imports: bool, true, true, "Reorder import and extern crate statements alphabetically";
         "Align enum variants discrims, if their diffs fit within threshold";
     match_arm_blocks: bool, true, false, "Wrap the body of arms in blocks when it does not fit on \
         the same line with the pattern of arms";
+    match_arm_leading_pipes: MatchArmLeadingPipe, MatchArmLeadingPipe::Never, true,
+        "Determines whether leading pipes are emitted on match arms";
     force_multiline_blocks: bool, false, false,
         "Force multiline closure bodies and match arms to be wrapped in a block";
-    fn_args_density: Density, Density::Tall, false, "Argument density in functions";
+    fn_args_layout: Density, Density::Tall, true,
+        "Control the layout of arguments in a function";
     brace_style: BraceStyle, BraceStyle::SameLineWhere, false, "Brace style for items";
     control_brace_style: ControlBraceStyle, ControlBraceStyle::AlwaysSameLine, false,
         "Brace style for control flow constructs";
     emit_mode: EmitMode, EmitMode::Files, false,
         "What emit Mode to use when none is supplied";
     make_backup: bool, false, false, "Backup changed files";
+    print_misformatted_file_names: bool, false, true,
+        "Prints the names of mismatched files that were formatted. Prints the names of \
+         files that would be formated when used with `--check` mode. ";
 }
 
+#[derive(Error, Debug)]
+#[error("Could not output config: {0}")]
+pub struct ToTomlError(toml::ser::Error);
+
 impl PartialConfig {
-    pub fn to_toml(&self) -> Result<String, String> {
+    pub fn to_toml(&self) -> Result<String, ToTomlError> {
         // Non-user-facing options can't be specified in TOML
         let mut cloned = self.clone();
         cloned.file_lines = None;
         cloned.verbose = None;
         cloned.width_heuristics = None;
+        cloned.print_misformatted_file_names = None;
+        cloned.merge_imports = None;
 
-        ::toml::to_string(&cloned).map_err(|e| format!("Could not output config: {}", e))
+        ::toml::to_string(&cloned).map_err(ToTomlError)
     }
 }
 
@@ -393,6 +410,10 @@ mod mock {
                     via the --file-lines option";
             width_heuristics: WidthHeuristics, WidthHeuristics::scaled(100), false,
                 "'small' heuristic values";
+            // merge_imports deprecation
+            imports_granularity: ImportGranularity, ImportGranularity::Preserve, false,
+                "Merge imports";
+            merge_imports: bool, false, false, "(deprecated: use imports_granularity instead)";
 
             // Options that are used by the tests
             stable_option: bool, false, true, "A stable option";
@@ -462,6 +483,113 @@ fn test_print_docs_include_unstable() {
         assert_eq!(s.contains("(unstable)"), true);
     }
 
+    #[test]
+    fn test_empty_string_license_template_path() {
+        let toml = r#"license_template_path = """#;
+        let config = Config::from_toml(toml, Path::new("")).unwrap();
+        assert!(config.license_template.is_none());
+    }
+
+    #[test]
+    fn test_valid_license_template_path() {
+        if !crate::is_nightly_channel!() {
+            return;
+        }
+        let toml = r#"license_template_path = "tests/license-template/lt.txt""#;
+        let config = Config::from_toml(toml, Path::new("")).unwrap();
+        assert!(config.license_template.is_some());
+    }
+
+    #[test]
+    fn test_override_existing_license_with_no_license() {
+        if !crate::is_nightly_channel!() {
+            return;
+        }
+        let toml = r#"license_template_path = "tests/license-template/lt.txt""#;
+        let mut config = Config::from_toml(toml, Path::new("")).unwrap();
+        assert!(config.license_template.is_some());
+        config.override_value("license_template_path", "");
+        assert!(config.license_template.is_none());
+    }
+
+    #[test]
+    fn test_dump_default_config() {
+        let default_config = format!(
+            r#"max_width = 100
+hard_tabs = false
+tab_spaces = 4
+newline_style = "Auto"
+use_small_heuristics = "Default"
+indent_style = "Block"
+wrap_comments = false
+format_code_in_doc_comments = false
+comment_width = 80
+normalize_comments = false
+normalize_doc_attributes = false
+license_template_path = ""
+format_strings = false
+format_macro_matchers = false
+format_macro_bodies = true
+empty_item_single_line = true
+struct_lit_single_line = true
+fn_single_line = false
+where_single_line = false
+imports_indent = "Block"
+imports_layout = "Mixed"
+imports_granularity = "Preserve"
+group_imports = "Preserve"
+reorder_imports = true
+reorder_modules = true
+reorder_impl_items = false
+type_punctuation_density = "Wide"
+space_before_colon = false
+space_after_colon = true
+spaces_around_ranges = false
+binop_separator = "Front"
+remove_nested_parens = true
+combine_control_expr = true
+overflow_delimited_expr = false
+struct_field_align_threshold = 0
+enum_discrim_align_threshold = 0
+match_arm_blocks = true
+match_arm_leading_pipes = "Never"
+force_multiline_blocks = false
+fn_args_layout = "Tall"
+brace_style = "SameLineWhere"
+control_brace_style = "AlwaysSameLine"
+trailing_semicolon = true
+trailing_comma = "Vertical"
+match_block_trailing_comma = false
+blank_lines_upper_bound = 1
+blank_lines_lower_bound = 0
+edition = "2015"
+version = "One"
+inline_attribute_width = 0
+merge_derives = true
+use_try_shorthand = false
+use_field_init_shorthand = false
+force_explicit_abi = true
+condense_wildcard_suffixes = false
+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
+report_todo = "Never"
+report_fixme = "Never"
+ignore = []
+emit_mode = "Files"
+make_backup = false
+"#,
+            env!("CARGO_PKG_VERSION")
+        );
+        let toml = Config::default().all_options().to_toml().unwrap();
+        assert_eq!(&toml, &default_config);
+    }
+
     // FIXME(#2183): these tests cannot be run in parallel because they use env vars.
     // #[test]
     // fn test_as_not_nightly_channel() {
@@ -494,4 +622,65 @@ fn test_print_docs_include_unstable() {
     //     assert_eq!(config.unstable_features(), true);
     //     ::std::env::set_var("CFG_RELEASE_CHANNEL", v);
     // }
+
+    #[cfg(test)]
+    mod deprecated_option_merge_imports {
+        use super::*;
+
+        #[test]
+        fn test_old_option_set() {
+            if !crate::is_nightly_channel!() {
+                return;
+            }
+            let toml = r#"
+                unstable_features = true
+                merge_imports = true
+            "#;
+            let config = Config::from_toml(toml, Path::new("")).unwrap();
+            assert_eq!(config.imports_granularity(), ImportGranularity::Crate);
+        }
+
+        #[test]
+        fn test_both_set() {
+            if !crate::is_nightly_channel!() {
+                return;
+            }
+            let toml = r#"
+                unstable_features = true
+                merge_imports = true
+                imports_granularity = "Preserve"
+            "#;
+            let config = Config::from_toml(toml, Path::new("")).unwrap();
+            assert_eq!(config.imports_granularity(), ImportGranularity::Preserve);
+        }
+
+        #[test]
+        fn test_new_overridden() {
+            if !crate::is_nightly_channel!() {
+                return;
+            }
+            let toml = r#"
+                unstable_features = true
+                merge_imports = true
+            "#;
+            let mut config = Config::from_toml(toml, Path::new("")).unwrap();
+            config.override_value("imports_granularity", "Preserve");
+            assert_eq!(config.imports_granularity(), ImportGranularity::Preserve);
+        }
+
+        #[test]
+        fn test_old_overridden() {
+            if !crate::is_nightly_channel!() {
+                return;
+            }
+            let toml = r#"
+                unstable_features = true
+                imports_granularity = "Module"
+            "#;
+            let mut config = Config::from_toml(toml, Path::new("")).unwrap();
+            config.override_value("merge_imports", "true");
+            // no effect: the new option always takes precedence
+            assert_eq!(config.imports_granularity(), ImportGranularity::Module);
+        }
+    }
 }