Skip to content

Commit

Permalink
Merge pull request #1723 from paul-dingemans/1033-disable-rules
Browse files Browse the repository at this point in the history
Split (ktlint_)disabled_rules property into rule (set) specific properties
  • Loading branch information
paul-dingemans committed Dec 10, 2022
2 parents 4610fdd + f133795 commit dc69d6c
Show file tree
Hide file tree
Showing 58 changed files with 1,409 additions and 675 deletions.
32 changes: 16 additions & 16 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,26 @@ This project adheres to [Semantic Versioning](https://semver.org/).

The `indent` rule has been rewritten from scratch. Solving problems in the old algorithm was very difficult. With the new algorithm this becomes a lot easier. Although the new implementation of the rule has been compared against several open source projects containing over 400,000 lines of code, it is still likely that new issues will be discovered. Please report your indentation issues so that these can be fixed as well.

### `.editorconfig` property `disabled_rules`
### `.editorconfig` property to disable rules

Usage of `.editorconfig` property `disabled_rules` results in a `DeprecatedEditorConfigPropertyException`. This property should be renamed to `ktlint_disabled_rules`.
In the previous release (0.47.x), the `.editorconfig` property `disabled_rules` was deprecated and replaced with `ktlint_disabled_rules`. This latter property has now been deprecated as well in favour of a more flexible and better maintainable solution. Rule and rule sets can now be enabled/disabled with a separate property per rule (set). Please read [deprecation of (ktlint_)disable_rules property](https://pinterest.github.io/ktlint/faq/#why-is-editorconfig-property-disabled_rules-deprecated-and-how-do-i-resolve-this) for more information.

The KtLint CLI has not been changed. Although you can still use parameter `--experimental` to enable KtLint's Experimental rule set, you might want to set `.editorconfig` property `ktlint_experimental = enabled` instead.

### API Changes & RuleSet providers

If you are not an API consumer or Rule Set provider then you can skip this section.

#### Class relocations

Classes below have been relocated:

* Class `com.pinterest.ktlint.core.api.UsesEditorConfigProperties.EditorConfigProperty` has been replaced with `com.pinterest.ktlint.core.api.editorconfig.EditorConfigProperty`.
* Class `com.pinterest.ktlint.core.KtLintParseException` has been replaced with `com.pinterest.ktlint.core.api.KtLintParseException`.
* Class `com.pinterest.ktlint.core.RuleExecutionException` has been replaced with `com.pinterest.ktlint.core.api.KtLintRuleException`.
* Class `com.pinterest.ktlint.reporter.format.internal.Color` has been moved to `com.pinterest.ktlint.reporter.format.Color`.
* Class `com.pinterest.ktlint.reporter.plain.internal.Color` has been moved to `com.pinterest.ktlint.reporter.plain.Color`.

#### Invoking `lint` and `format`

This is the last release that supports the `ExperimentalParams` to invoke the `lint` and `format` functions of KtLint. The `ExperimentalParams` contains a mix of configuration settings which are not dependent on the file/code which is to be processed. Other parameters in that class describe the code/file to be processed but can be configured inconsistently (for example a file with name "foo.kt" could be marked as a Kotlin Script file).
Expand Down Expand Up @@ -66,20 +80,6 @@ if (node.isRoot()) {
}
```

#### ParseException

Class `com.pinterest.ktlint.core.KtLintParseException` has been replaced with `com.pinterest.ktlint.core.api.KtLintParseException`.

#### RuleExecutionException

Class `com.pinterest.ktlint.core.RuleExecutionException` has been replaced with `com.pinterest.ktlint.core.api.KtLintRuleException`.

#### Color

Class `com.pinterest.ktlint.reporter.format.internal.Color` has been moved to `com.pinterest.ktlint.reporter.format.Color`.

Class `com.pinterest.ktlint.reporter.plain.internal.Color` has been moved to `com.pinterest.ktlint.reporter.plain.Color`.

### Added
* Wrap blocks in case the max line length is exceeded or in case the block contains a new line `wrapping` ([#1643](https://github.com/pinterest/ktlint/issue/1643))
* patterns can be read in from `stdin` with the `--patterns-from-stdin` command line options/flags ([#1606](https://github.com/pinterest/ktlint/pull/1606))
Expand Down
46 changes: 45 additions & 1 deletion docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,50 @@ Like with other `@Suppress` annotations, it can be placed on targets supported b


## How do I globally disable a rule?
With [`.editorConfig` property `ktlint_disabled_rules`](../rules/configuration-ktlint#disabled-rules) a rule can be disabled globally.
With [`.editorConfig` property `disabled_rules`](../rules/configuration-ktlint#disabled-rules) a rule can be disabled globally.

You may also pass a list of disabled rules via the `--disabled_rules` command line flag. It has the same syntax as the EditorConfig property.


## Why is `.editorconfig` property `disabled_rules` deprecated and how do I resolve this?
The `.editorconfig` properties `disabled_rules` and `ktlint_disbaled_rules` are deprecated as of KtLint version `0.48` and are marked for removal in version `0.49`. Those properties contain a comma separated list of rules which are disabled. Using a comma separated list of values has some disadvantages.

A big disadvantage is that it is not possible to override the property partially in an `.editorconfig` file in a subpackage. Another disadvantage is that it is not possible to express explicitly that a rule is enabled. Lastly, (qualified) rule ids can be 20 characters or longer, which makes a list with multiple entries hard to read.

*Root `.editorconfig`*
```editorconfig
root = true
[*.kt]
disabled_rules=rule-1,rule-2,rule-3
```
This `.editorconfig` defines that all rules except `rule-1`, `rule-2` and `rule-3` should be run in all packages. Suppose that we want to enable `rule-1` but disable `rule-4` in certain subpackage, then we would need to define an `.editorconfig` file like below:

*Secondary `.editorconfig`*
```editorconfig
[*.kt]
disabled_rules=rule-2,rule-4,rule-3
```
Disabling another rule in the root `.editorconfig` file, does not have effect on this subpackage as long as that rule has not been added to the `.editorconfig` file in the subpackage.

Starting with KtLint `0.48` entire rule sets and individual rules can be disabled / enabled with a separate property per rule (set).

All rules in a rule set can be enabled or disabled with a rule set property. The name of the rule set property consists of the `ktlint_` prefix followed by the rule set id. Examples:
```editorconfig
ktlint_standard = disabled # Disable all rules from the `standard` rule set provided by KtLint
ktlint_experimental = enabled # Enable all rules from the `experimental` rule set provided by KtLint
ktlint_your-custom-rule-set_custom-rule = enabled # Enable all rules in the `custom-rule-set` rule set (not provided by KtLint)
```

!!! note
All rules from the `standard` rule set are *enabled* by default and can optionally be disabled in the `.editorconfig`. All rules from the `experimental` and *custom* rule sets are *disabled* by default and can optionally be enabled in the `.editorconfig`.

An individual property can be enabled or disabled with a rule property. The name of the rule property consists of the `ktlint_` prefix followed by the rule set id followed by a `_` and the rule id. Examples:
```editorconfig
ktlint_standard_final-newline = disabled # Disables the `final-newline` rule in the `standard` rule set provided by KtLint
ktlint_experimental_type-argument-list-spacing = enabled # Enables the `type-argument-list-spacing` rule in the `experimental` rule set provided by KtLint
ktlint_custom-rule-set_custom-rule = disabled # Disables the `custom-rule` rule in the `custom-rule-set` rule set (not provided by KtLint)
```

!!! note
The *rule* properties are applied after applying the *rule set* properties and take precedence. So if a rule set is disabled but a specific rule of that rule set is enabled, then the rule will be executed.
3 changes: 3 additions & 0 deletions docs/install/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ To validate with the [standard ruleset](../../rules/standard/) and the [experime
ktlint --experimental
```

!!! note
Instead of using this command line flag, you can also set `.editorconfig` property `ktlint_experimental = enabled`.

To validate with a [custom ruleset](../../extensions/custom-rule-set/) run command below:

```shell title="Validation with standard and a custom ruleset"
Expand Down
39 changes: 33 additions & 6 deletions docs/rules/configuration-ktlint.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,40 @@ ktlint_code_style = official

## Disabled rules

By default, no rules are disabled. The property `ktlint_disabled_rules` holds a comma separated list (without spaces). Rules which are not defined in the `standard` ruleset have to be prefixed. Rules defined in the `standard` ruleset may optionally be prefixed.
!!! warning
Properties `disabled_rules` and `ktlint_disabled_rules` are deprecated in KtLint `0.48` and are marked for removal in KtLint `0.49`.

By default, no rules are disabled. The properties `disabled_rules` and `ktlint_disabled_rules` hold a comma separated list (without spaces). Rules which are not defined in the `standard` ruleset have to be prefixed. Rules defined in the `standard` ruleset may optionally be prefixed.

Example:
```ini
```editorconfig
[*.{kt,kts}]
ktlint_disabled_rules = some-standard-rule,experimental:some-experimental-rule,my-custom-ruleset:my-custom-rule
disabled_rules = some-standard-rule,experimental:some-experimental-rule,my-custom-ruleset:my-custom-rule
```

Starting with KtLint `0.48` entire rule sets and individual rules can be disabled / enabled with a separate property per rule (set).

All rules in a rule set can be enabled or disabled with a rule set property. The name of the rule set property consists of the `ktlint_` prefix followed by the rule set id. Examples:
```editorconfig
ktlint_standard = disabled # Disable all rules from the `standard` rule set provided by KtLint
ktlint_experimental = enabled # Enable all rules from the `experimental` rule set provided by KtLint
ktlint_your-custom-rule-set_custom-rule = enabled # Enable all rules in the `custom-rule-set` rule set (not provided by KtLint)
```

!!! note
All rules from the `standard` rule set are *enabled* by default and can optionally be disabled in the `.editorconfig`. All rules from the `experimental` and *custom* rule sets are *disabled* by default and can optionally be enabled in the `.editorconfig`.

An individual property can be enabled or disabled with a rule property. The name of the rule property consists of the `ktlint_` prefix followed by the rule set id followed by a `_` and the rule id. Examples:
```editorconfig
ktlint_standard_final-newline = disabled # Disables the `final-newline` rule in the `standard` rule set provided by KtLint
ktlint_experimental_type-argument-list-spacing = enabled # Enables the `type-argument-list-spacing` rule in the `experimental` rule set provided by KtLint
ktlint_custom-rule-set_custom-rule = disabled # Disables the `custom-rule` rule in the `custom-rule-set` rule set (not provided by KtLint)
```

!!! note
The *rule* properties are applied after applying the *rule set* properties and take precedence. So if a rule set is disabled but a specific rule of that rule set is enabled, then the rule will be executed.


## Final newline

By default, a final newline is required at the end of the file.
Expand Down Expand Up @@ -205,9 +231,10 @@ This setting only takes effect when rule `trailing-comma-on-declaration-site` is
You can [override](https://editorconfig.org/#file-format-details) properties for specific directories inside your project:
```ini
[*.{kt,kts}]
ktlint_disabled_rules=import-ordering
ktlint_standard_import-ordering = disabled

Note that in this case 'import-ordering' rule will be active and 'indent' will be disabled
[api/*.{kt,kts}]
ktlint_disabled_rules=indent
ktlint_standard_indent = disabled
```

Note that the `import-ordering` rule is disabled for *all* packages including the `api` sub package. Next to this the `indent` rule is disabled for the `api` package and its sub packages.
14 changes: 7 additions & 7 deletions ktlint-core/src/main/kotlin/com/pinterest/ktlint/core/KtLint.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ package com.pinterest.ktlint.core
import com.pinterest.ktlint.core.KtLint.ExperimentalParams
import com.pinterest.ktlint.core.KtLint.format
import com.pinterest.ktlint.core.KtLint.lint
import com.pinterest.ktlint.core.api.DefaultEditorConfigProperties
import com.pinterest.ktlint.core.api.DefaultEditorConfigProperties.CODE_STYLE_PROPERTY
import com.pinterest.ktlint.core.api.EditorConfigDefaults
import com.pinterest.ktlint.core.api.EditorConfigDefaults.Companion.EMPTY_EDITOR_CONFIG_DEFAULTS
import com.pinterest.ktlint.core.api.EditorConfigOverride
import com.pinterest.ktlint.core.api.EditorConfigOverride.Companion.EMPTY_EDITOR_CONFIG_OVERRIDE
import com.pinterest.ktlint.core.api.KtLintRuleException
import com.pinterest.ktlint.core.api.UsesEditorConfigProperties
import com.pinterest.ktlint.core.api.editorconfig.CodeStyleValue
import com.pinterest.ktlint.core.api.editorconfig.DEFAULT_EDITOR_CONFIG_PROPERTIES
import com.pinterest.ktlint.core.internal.EditorConfigFinder
import com.pinterest.ktlint.core.internal.EditorConfigGenerator
import com.pinterest.ktlint.core.internal.EditorConfigLoader
Expand Down Expand Up @@ -120,8 +120,8 @@ public object KtLint {
.filterIsInstance<UsesEditorConfigProperties>()
.map { it.editorConfigProperties }
.flatten()
.plus(DefaultEditorConfigProperties.editorConfigProperties)
.map { it.type.name }
.plus(DEFAULT_EDITOR_CONFIG_PROPERTIES)
.map { it.name }
.distinct()
.toSet()

Expand Down Expand Up @@ -580,10 +580,10 @@ public class KtLintRuleEngine(
public fun generateKotlinEditorConfigSection(filePath: Path): String {
val codeStyle =
editorConfigOverride
.properties[CODE_STYLE_PROPERTY]
.properties[com.pinterest.ktlint.core.api.editorconfig.CODE_STYLE_PROPERTY]
?.parsed
?.safeAs<DefaultEditorConfigProperties.CodeStyleValue>()
?: CODE_STYLE_PROPERTY.defaultValue
?.safeAs<CodeStyleValue>()
?: com.pinterest.ktlint.core.api.editorconfig.CODE_STYLE_PROPERTY.defaultValue
val rules =
ruleProviders
.map { RuleRunner(it) }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.pinterest.ktlint.core.api

import com.pinterest.ktlint.core.api.UsesEditorConfigProperties.EditorConfigProperty
import org.ec4j.core.model.PropertyType
import com.pinterest.ktlint.core.api.editorconfig.EditorConfigProperty
import org.ec4j.core.model.PropertyType.PropertyValue

/**
* The [EditorConfigOverride] allows to add or replace properties which are loaded from the ".editorconfig" file. It
Expand All @@ -15,16 +15,23 @@ import org.ec4j.core.model.PropertyType
* having to access an ".editorconfig" file from physical storage. This also improves readability of the tests.
*/
public class EditorConfigOverride {
private val _properties = mutableMapOf<EditorConfigProperty<*>, PropertyType.PropertyValue<*>>()
private val _properties = mutableMapOf<EditorConfigProperty<*>, PropertyValue<*>>()

/**
* Gets a safe copy of the [EditorConfigProperty] set.
*/
public val properties: Map<EditorConfigProperty<*>, PropertyType.PropertyValue<*>>
public val properties: Map<EditorConfigProperty<*>, PropertyValue<*>>
get() = _properties.toMap()

private fun add(property: EditorConfigProperty<*>, value: Any?) =
_properties.put(property, property.type.parse(value?.toString()))
_properties.put(
property,
if (value is PropertyValue<*>) {
value
} else {
property.type.parse(value?.toString())
},
)

public companion object {
/**
Expand Down

0 comments on commit dc69d6c

Please sign in to comment.