X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fconfig%2Fmod.rs;h=dfce7977bfea1e06d4b9df2b72e931b6336e47fb;hb=612e8d5b9be72713a081370c85cc5bed30b6fae6;hp=4a4647a56635889677df75894fcfc259438ffec0;hpb=a2d9b6d1b11ba318d309a9c5512b3b7974091ccb;p=rust.git diff --git a/src/config/mod.rs b/src/config/mod.rs index 4a4647a5663..dfce7977bfe 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -6,20 +6,24 @@ use std::{env, fs}; use regex::Regex; +use thiserror::Error; use crate::config::config_type::ConfigType; +#[allow(unreachable_pub)] pub use crate::config::file_lines::{FileLines, FileName, Range}; +#[allow(unreachable_pub)] pub use crate::config::lists::*; +#[allow(unreachable_pub)] pub use crate::config::options::*; #[macro_use] -pub mod config_type; +pub(crate) mod config_type; #[macro_use] -pub mod options; +pub(crate) mod options; -pub mod file_lines; -pub mod license; -pub mod lists; +pub(crate) mod file_lines; +pub(crate) mod license; +pub(crate) mod lists; // This macro defines configuration options used in rustfmt. Each option // is defined as follows: @@ -37,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"; @@ -60,7 +64,11 @@ // 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"; @@ -87,9 +95,12 @@ "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"; @@ -148,17 +159,26 @@ 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 { + pub fn to_toml(&self) -> Result { // 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) } } @@ -244,7 +264,7 @@ fn resolve_project_file(dir: &Path) -> Result, Error> { } } - return Ok(None); + Ok(None) } match resolve_project_file(dir)? { @@ -260,7 +280,7 @@ pub(crate) fn from_toml(toml: &str, dir: &Path) -> Result { let mut err = String::new(); let table = parsed .as_table() - .ok_or(String::from("Parsed config was not table"))?; + .ok_or_else(|| String::from("Parsed config was not table"))?; for key in table.keys() { if !Config::is_valid_name(key) { let msg = &format!("Warning: Unknown configuration option `{}`\n", key); @@ -358,7 +378,7 @@ fn config_path(options: &dyn CliOptions) -> Result, Error> { config_path_not_found(path.to_str().unwrap()) } } - path => Ok(path.map(|p| p.to_owned())), + path => Ok(path.map(ToOwned::to_owned)), } } @@ -390,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"; @@ -426,7 +450,6 @@ fn test_config_used_to_toml() { #[test] fn test_was_set() { - use std::path::Path; let config = Config::from_toml("hard_tabs = true", Path::new("")).unwrap(); assert_eq!(config.was_set().hard_tabs(), true); @@ -460,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() { @@ -492,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); + } + } }