diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ef0db0c41..9ff8d9b69c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ This project adheres to [Semantic Versioning](https://semver.org/). ### Fixed +* Allow to disable ktlint in `.editorconfig` for a glob ([#2100](https://github.com/pinterest/ktlint/issues/2100)) * Fix wrapping of nested function literals `wrapping` ([#2106](https://github.com/pinterest/ktlint/issues/2106)) * Do not indent class body for classes having a long super type list in code style `ktlint_official` as it is inconsistent compared to other class bodies `indent` [#2115](https://github.com/pinterest/ktlint/issues/2115) diff --git a/documentation/release-latest/docs/faq.md b/documentation/release-latest/docs/faq.md index 31a6601b82..cecf5ca97b 100644 --- a/documentation/release-latest/docs/faq.md +++ b/documentation/release-latest/docs/faq.md @@ -154,3 +154,16 @@ ij_formatter_on_tag = some-custom-on-tag # Defaults to '@formatter:on' ``` When enabled, the ktlint rule checking is disabled for all code surrounded by the formatter tags. + +# How do I disable ktlint for generated code? + +Running ktlint on generated code is not useful. Fixing lint and format errors on generated code is a waste of time as errors will be re-introduced once that code is generated again. Given that generated code is located in a separate directory, you can disable ktlint for such directory by adding a glob for that directory: +```editorconfig +[some/path/to/generated/code/**/*] +ktlint = disabled +``` + +!!! warning + The `ec4j` library used by ktlint does not seem to work with globs starting with `**` followed by a chain of multiple directories (for example `**/path/to/generated/**/*`). But both `some/path/to/generated/**/*` and `**/generated/**/*` work fine. + + diff --git a/documentation/snapshot/docs/faq.md b/documentation/snapshot/docs/faq.md index 31a6601b82..cecf5ca97b 100644 --- a/documentation/snapshot/docs/faq.md +++ b/documentation/snapshot/docs/faq.md @@ -154,3 +154,16 @@ ij_formatter_on_tag = some-custom-on-tag # Defaults to '@formatter:on' ``` When enabled, the ktlint rule checking is disabled for all code surrounded by the formatter tags. + +# How do I disable ktlint for generated code? + +Running ktlint on generated code is not useful. Fixing lint and format errors on generated code is a waste of time as errors will be re-introduced once that code is generated again. Given that generated code is located in a separate directory, you can disable ktlint for such directory by adding a glob for that directory: +```editorconfig +[some/path/to/generated/code/**/*] +ktlint = disabled +``` + +!!! warning + The `ec4j` library used by ktlint does not seem to work with globs starting with `**` followed by a chain of multiple directories (for example `**/path/to/generated/**/*`). But both `some/path/to/generated/**/*` and `**/generated/**/*` work fine. + + diff --git a/ktlint-rule-engine-core/src/main/kotlin/com/pinterest/ktlint/rule/engine/core/api/editorconfig/RuleExecutionEditorConfigProperty.kt b/ktlint-rule-engine-core/src/main/kotlin/com/pinterest/ktlint/rule/engine/core/api/editorconfig/RuleExecutionEditorConfigProperty.kt index 543b9f85fa..b5b7104537 100644 --- a/ktlint-rule-engine-core/src/main/kotlin/com/pinterest/ktlint/rule/engine/core/api/editorconfig/RuleExecutionEditorConfigProperty.kt +++ b/ktlint-rule-engine-core/src/main/kotlin/com/pinterest/ktlint/rule/engine/core/api/editorconfig/RuleExecutionEditorConfigProperty.kt @@ -19,6 +19,18 @@ public val RULE_EXECUTION_PROPERTY_TYPE: PropertyType.LowerCasingPropertyType = + EditorConfigProperty( + // Explicitly name the rule as multiple properties exists for this property type + name = "ktlint", + type = RULE_EXECUTION_PROPERTY_TYPE, + defaultValue = RuleExecution.enabled, + ) + /** * When enabled, a rule that implements interface "Rule.Experimental" is executed unless that rule itself is explicitly disabled. */ diff --git a/ktlint-rule-engine/src/main/kotlin/com/pinterest/ktlint/rule/engine/internal/rulefilter/RuleExecutionRuleFilter.kt b/ktlint-rule-engine/src/main/kotlin/com/pinterest/ktlint/rule/engine/internal/rulefilter/RuleExecutionRuleFilter.kt index a46cf7fde0..acf91fa856 100644 --- a/ktlint-rule-engine/src/main/kotlin/com/pinterest/ktlint/rule/engine/internal/rulefilter/RuleExecutionRuleFilter.kt +++ b/ktlint-rule-engine/src/main/kotlin/com/pinterest/ktlint/rule/engine/internal/rulefilter/RuleExecutionRuleFilter.kt @@ -4,6 +4,7 @@ import com.pinterest.ktlint.logger.api.initKtLintKLogger import com.pinterest.ktlint.rule.engine.api.KtLintRuleEngine import com.pinterest.ktlint.rule.engine.core.api.Rule import com.pinterest.ktlint.rule.engine.core.api.RuleProvider +import com.pinterest.ktlint.rule.engine.core.api.editorconfig.ALL_RULES_EXECUTION_PROPERTY import com.pinterest.ktlint.rule.engine.core.api.editorconfig.CODE_STYLE_PROPERTY import com.pinterest.ktlint.rule.engine.core.api.editorconfig.CodeStyleValue import com.pinterest.ktlint.rule.engine.core.api.editorconfig.EXPERIMENTAL_RULES_EXECUTION_PROPERTY @@ -24,16 +25,22 @@ private val LOGGER = KotlinLogging.logger {}.initKtLintKLogger() internal class RuleExecutionRuleFilter( private val editorConfig: EditorConfig, ) : RuleFilter { - override fun filter(ruleProviders: Set): Set { - val ruleExecutionFilter = - RuleExecutionFilter( - editorConfig.ruleExecutionProperties(ruleProviders), - editorConfig[CODE_STYLE_PROPERTY], - ) - return ruleProviders - .filter { ruleExecutionFilter.isEnabled(it) } - .toSet() - } + override fun filter(ruleProviders: Set): Set = + if (disableKtlintEntirely()) { + emptySet() + } else { + val ruleExecutionFilter = + RuleExecutionFilter( + editorConfig.ruleExecutionProperties(ruleProviders), + editorConfig[CODE_STYLE_PROPERTY], + ) + ruleProviders + .filter { ruleExecutionFilter.isEnabled(it) } + .toSet() + } + + private fun disableKtlintEntirely() = + editorConfig.getEditorConfigValueOrNull(RULE_EXECUTION_PROPERTY_TYPE, ALL_RULES_EXECUTION_PROPERTY.name) == RuleExecution.disabled private fun EditorConfig.ruleExecutionProperties(ruleProviders: Set): Map { val ruleExecutionPropertyNames = diff --git a/ktlint-rule-engine/src/test/kotlin/com/pinterest/ktlint/rule/engine/internal/rulefilter/RuleExecutionRuleFilterTest.kt b/ktlint-rule-engine/src/test/kotlin/com/pinterest/ktlint/rule/engine/internal/rulefilter/RuleExecutionRuleFilterTest.kt index fb4dd8c226..f9f00d93c3 100644 --- a/ktlint-rule-engine/src/test/kotlin/com/pinterest/ktlint/rule/engine/internal/rulefilter/RuleExecutionRuleFilterTest.kt +++ b/ktlint-rule-engine/src/test/kotlin/com/pinterest/ktlint/rule/engine/internal/rulefilter/RuleExecutionRuleFilterTest.kt @@ -4,6 +4,7 @@ import com.pinterest.ktlint.rule.engine.core.api.Rule import com.pinterest.ktlint.rule.engine.core.api.RuleId import com.pinterest.ktlint.rule.engine.core.api.RuleProvider import com.pinterest.ktlint.rule.engine.core.api.RuleSetId +import com.pinterest.ktlint.rule.engine.core.api.editorconfig.ALL_RULES_EXECUTION_PROPERTY import com.pinterest.ktlint.rule.engine.core.api.editorconfig.CODE_STYLE_PROPERTY import com.pinterest.ktlint.rule.engine.core.api.editorconfig.EditorConfig import com.pinterest.ktlint.rule.engine.core.api.editorconfig.RULE_EXECUTION_PROPERTY_TYPE @@ -176,6 +177,21 @@ class RuleExecutionRuleFilterTest { assertThat(actual).containsExactly(KTLINT_SUPPRESSION_RULE_ID) } + @Test + fun `Given that ktlint is disabled entirely then the internal rule for migrating the ktlint-disable directives is disabled`() { + val actual = + runWithRuleExecutionRuleFilter( + RuleProvider { NormalRule(STANDARD_RULE_A) }, + RuleProvider { KtlintSuppressionRule(listOf(STANDARD_RULE_A)) }, + editorConfig = + EditorConfig( + ktLintDisableAllRuleExecutionEditorConfigProperty(), + ), + ).toRuleIds() + + assertThat(actual).isEmpty() + } + /** * Create a [RuleExecutionRuleFilter] for a given set of [RuleProvider]s and an [EditorConfig]. */ @@ -191,6 +207,14 @@ class RuleExecutionRuleFilterTest { private fun Set.toRuleIds() = map { it.ruleId } + private fun ktLintDisableAllRuleExecutionEditorConfigProperty() = + Property + .builder() + .type(RULE_EXECUTION_PROPERTY_TYPE) + .name(ALL_RULES_EXECUTION_PROPERTY.name) + .value(RuleExecution.disabled.name) + .build() + private fun ktLintRuleExecutionEditorConfigProperty( ktlintRuleExecutionPropertyName: String, ruleExecution: RuleExecution,