From dff3954629c8c4550a0eeaf3f39436803e37ed61 Mon Sep 17 00:00:00 2001 From: Rob Pickerill Date: Tue, 19 Sep 2023 20:21:04 +0100 Subject: [PATCH] add config to allow generated lines scan to be configurable --- Configurations.md | 21 ++++++++++++++++----- src/config/mod.rs | 4 ++++ src/formatting.rs | 2 +- src/formatting/generated.rs | 27 +++++++++++++++++++++++++-- 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/Configurations.md b/Configurations.md index ac5747800b2..8999937d4db 100644 --- a/Configurations.md +++ b/Configurations.md @@ -1050,15 +1050,26 @@ Max width for code snippets included in doc comments. Only used if [`format_code ## `format_generated_files` -Format generated files. A file is considered generated -if any of the first five lines contain a `@generated` comment marker. -By default, generated files are reformatted, i. e. `@generated` marker is ignored. -This option is currently ignored for stdin (`@generated` in stdin is ignored.) +Format generated files. A file is considered generated if any of +the first `generated_files_scan_lines_limit` lines contain a +`@generated` comment marker. By default, generated files are +reformatted, i. e. `@generated` marker is ignored. This option +is currently ignored for stdin (`@generated` in stdin is ignored.) - **Default value**: `true` - **Possible values**: `true`, `false` - **Stable**: No (tracking issue: [#5080](https://github.com/rust-lang/rustfmt/issues/5080)) +## `generated_files_scan_lines_limit` + +Number of lines to scan for `@generated` marker in generated files. If the marker is not found +within the specified number of lines, the file is considered not generated. + +- **Default value**: `5` +- **Possible values**: any positive integer +- **Stable**: No (tracking issue: [#5658](https://github.com/rust-lang/rustfmt/issues/5658)) + + ## `format_macro_matchers` Format the metavariable matching patterns in macros. @@ -2342,7 +2353,7 @@ specific version of rustfmt is used in your CI, use this option. The width threshold for an array element to be considered "short". -The layout of an array is dependent on the length of each of its elements. +The layout of an array is dependent on the length of each of its elements. If the length of every element in an array is below this threshold (all elements are "short") then the array can be formatted in the mixed/compressed style, but if any one element has a length that exceeds this threshold then the array elements will have to be formatted vertically. - **Default value**: `10` diff --git a/src/config/mod.rs b/src/config/mod.rs index 7538b26522d..1b0c8cf87e5 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -151,6 +151,9 @@ create_config! { "Write an item and its attribute on the same line \ if their combined width is below a threshold"; format_generated_files: bool, true, false, "Format generated files"; + generated_files_scan_lines_limit: usize, 5, false, + "How many lines at the beginning of each file to scan for \ + `// rustfmt-generated` markers indicating generated files"; // Options that can change the source code beyond whitespace/blocks (somewhat linty things) merge_derives: bool, true, true, "Merge multiple `#[derive(...)]` into a single one"; @@ -671,6 +674,7 @@ edition = "2015" version = "One" inline_attribute_width = 0 format_generated_files = true +generated_files_scan_lines_limit = 5 merge_derives = true use_try_shorthand = false use_field_init_shorthand = false diff --git a/src/formatting.rs b/src/formatting.rs index cd57a025b67..f66d5f612d1 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -82,7 +82,7 @@ fn should_skip_module( let source_file = context.parse_session.span_to_file_contents(module.span); let src = source_file.src.as_ref().expect("SourceFile without src"); - if is_generated_file(src) { + if is_generated_file(src, config.generated_files_scan_lines_limit()) { return true; } } diff --git a/src/formatting/generated.rs b/src/formatting/generated.rs index 58f43f17ee1..420faed5427 100644 --- a/src/formatting/generated.rs +++ b/src/formatting/generated.rs @@ -1,7 +1,30 @@ /// Returns `true` if the given span is a part of generated files. -pub(super) fn is_generated_file(original_snippet: &str) -> bool { +pub(super) fn is_generated_file(original_snippet: &str, scan_number_of_lines: usize) -> bool { original_snippet .lines() - .take(5) // looking for marker only in the beginning of the file + .take(scan_number_of_lines) .any(|line| line.contains("@generated")) } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn detect_generated_file_simple() { + let snippet = "@generated"; + assert!(is_generated_file(snippet, 1)); + } + + #[test] + fn detect_generated_file_5_lines() { + let snippet = "\n \n \n \n @generated"; + assert!(is_generated_file(snippet, 5)); + } + + #[test] + fn no_detect_generated_file_5_lines() { + let snippet = "\n \n \n \n \n @generated"; + assert!(!is_generated_file(snippet, 5)); + } +}