Skip to content

Commit

Permalink
Merge pull request #1724 from paul-dingemans/1456-small-bugs
Browse files Browse the repository at this point in the history
Small bugs and cleanups
  • Loading branch information
paul-dingemans committed Dec 14, 2022
2 parents dc69d6c + 0214a28 commit 6d5355a
Show file tree
Hide file tree
Showing 54 changed files with 681 additions and 321 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Expand Up @@ -96,6 +96,11 @@ if (node.isRoot()) {
* Add missing `ktlint_disabled_rules` to exposed `editorConfigProperties` ([#1671](https://github.com/pinterest/ktlint/issue/1671))
* Do not add a second trailing comma, if the original trailing comma is followed by a KDOC `trailing-comma-on-declaration-site` and `trailing-comma-on-call-site` ([#1676](https://github.com/pinterest/ktlint/issue/1676))
* A function signature preceded by an annotation array should be handled similar as function preceded by a singular annotation `function-signature` ([#1690](https://github.com/pinterest/ktlint/issue/1690))
* Fix offset of annotation violations
* Fix line offset when blank line found between class and primary constructor
* Remove needless blank line between class followed by EOL, and primary constructor
* Fix offset of unexpected linebreak before assignment
* Remove whitespace before redundant semicolon if the semicolon is followed by whitespace

### Changed
* Update Kotlin development version to `1.8.0-RC` and Kotlin version to `1.7.21`.
Expand Down
63 changes: 48 additions & 15 deletions RELEASE_TESTING.MD
Expand Up @@ -54,7 +54,10 @@ Before releasing a new version of KtLint, the release candidate is tested on a s
```shell
./exec-in-each-project.sh "git pull"
```
3. Remove file `baseline.xml`
3. Remove baseline file
```shell
rm baseline.xml
```

## Testing a new release

Expand All @@ -68,6 +71,8 @@ Pre-requisites:

Formatting projects in which ktlint is not used may result in a huge amount of fixes. The main focus of this test is to see what the effects are when upgrading ktlint in a project already formatted with latest released ktlint version.

TODO: After release 0.48, update procedure below as the parameter "--experimental" does not need to be specified anymore when it is stored correctly in the `.editorconfig` file(s).

1. Format the sample projects with the *latest released* ktlint version:
```shell
ktlint -F --experimental --relative # Do not call this command via the "./exec-in-each-project.sh" script.
Expand All @@ -77,25 +82,53 @@ Formatting projects in which ktlint is not used may result in a huge amount of f
```shell
./exec-in-each-project.sh "git add --all && git commit -m \"Format with ktlint (xx.yy.zz) -F --experimental\""
```
3. Create a baseline file with the *latest released* ktlint version:
Repeat step 1 and 2 until no files are changed anymore.
3. Create a new baseline file with the *latest released* ktlint version to ignore all lint violations that could not be autocorrected using the latest ktlint version:
```shell
rm baseline.xml
ktlint --experimental --baseline=baseline.xml --relative # Do not call this command via the "./exec-in-each-project.sh" script as we want one combined baseline.xml file for all projects.
```
4. Rerun previous command. As all violations were stored in file `baseline.xml` it is to be expected that no violations will be reported anymore. However, if violations are reported, this should be investigated and fixed before proceeding as otherwise you might falsely interpret them as caused by changed in the new release. You might want to add some `.editorconfig` configuration to suppress violations which can not be autocorrected. Commit your changes:
4. Check that besides the `baseline.xml` no files are changed (in step 1 and 2 all violations which could be autocorrected have already been committed). Remaining violations which could not be autocorrected are saved in the `baseline.xml` which is stored outside the project directories.
```shell
./exec-in-each-project.sh "git add --all && git commit -m \"Fix for some reason\""
./exec-in-each-project.sh "git status"
```
The `baseline.xml` file should only contain errors which can not be autocorrected.
5. Define `.editorconfig` in the integration test directory with content below. Also follow up the instructions mentioned:
```editorconfig
root = true
[*.{kt,kts}]
# The open source projects that are used for release testing of ktlint contain a few '.editorconfig' files which need to
# be changed:
# 1) Disable the "root = true" property so that each project ultimately falls back on this file. In this way offending
# rules can be easily enabled/disabled for all test projects
# 2) Add specific rules to project below
# graphql
# ktlint_standard_import-ordering = disabled
# ktlint_standard_package-name = disabled
ktlint_standard = enabled
ktlint_standard_filename = disabled
ktlint_standard_no-wildcard-imports = disabled
ktlint_experimental = enabled
ktlint_experimental_function-naming = disabled
ktlint_experimental_property-naming = disabled
```
Repeat until no new violations are reported.
5. Lint with *latest development* version:
6. Commit changes:
```shell
ktlint-dev --experimental --baseline=baseline.xml --relative # Do not call this command via the "./exec-in-each-project.sh" script as we want to use the one combined baseline.xml file for all projects.
./exec-in-each-project.sh "git add --all && git commit -m \"Update .editorconfig to fallback to integration test settings\""
```
7. Lint with *latest development* version:
```shell
ktlint-dev --baseline=baseline.xml --relative # Do not call this command via the "./exec-in-each-project.sh" script as we want to use the one combined baseline.xml file for all projects.
# or when lots are violations are reported
ktlint-dev --baseline=baseline.xml --relative --reporter=plain-summary # Do not call this command via the "./exec-in-each-project.sh" script as we want to use the one combined baseline.xml file for all projects.
```
Inspect the output roughly (detailed inspection is done when formatting):
* Is the amount of logging messages comparable to before? If not, are the changes intended?
* Are violations related to rules that have actually been added or changed?
6. Format with *latest development* version:
8. Format with *latest development* version:
```shell
ktlint-dev -F --experimental --baseline=baseline.xml --relative # Do not call this command via the "./exec-in-each-project.sh" script as we want to use the one combined baseline.xml file for all projects.
ktlint-dev -F --baseline=baseline.xml --relative # Do not call this command via the "./exec-in-each-project.sh" script as we want to use the one combined baseline.xml file for all projects.
```
Inspect the output carefully:
* If you see an error like below, then this version obviously may *not* be released. It is best to fix this error before continuing with testing and validating!
Expand All @@ -105,15 +138,15 @@ Formatting projects in which ktlint is not used may result in a huge amount of f
* Ideally, no violations are shown. This means that all violations have been autocorrected.
* Violations which could not be autocorrected should be validated for correctness but do not block the release as most likely this is intended behavior.
* If a violation is shown which is not marked as being "can not be autocorrected" this means that during autocorrect of another violation a new violations has been introduced. This should be fixed before releasing especially when the next format introduces the original violation again which of course would result in an endless loop.
7. Inspect all fixed violations, Of course inspection similar violations tens of times does not make sense. At least check different types of violations a couple of times. Commit changes which do not need to be inspected again:
9. Inspect all fixed violations, Of course inspection similar violations tens of times does not make sense. At least check different types of violations a couple of times. Commit changes which do not need to be inspected again:
```shell
./exec-in-each-project.sh "git add --all && git commit -m \"Fixed with latest development version\""
```
8. Rerun lint with *latest development* version:
```shell
ktlint-dev --experimental --baseline=baseline.xml --relative # Do not call this command via the "./exec-in-each-project.sh" script as we want to use the one combined baseline.xml file for all projects.
```
No violations should be expected.
10. Rerun lint with *latest development* version:
```shell
ktlint-dev --experimental --baseline=baseline.xml --relative # Do not call this command via the "./exec-in-each-project.sh" script as we want to use the one combined baseline.xml file for all projects.
```
No violations, except error that can not be autocorrected, should be expected.

## Checking documentation
[The documentation for KtLint](https://pinterest.github.io/ktlint/) should be checked for dead links.
Expand Down
2 changes: 1 addition & 1 deletion docs/install/cli.md
Expand Up @@ -60,7 +60,7 @@ When no arguments are specified, the style of all Kotlin files (ending with '.kt
ktlint
```

To validate with the [standard ruleset](../../rules/standard/) and the [experimental rulesset](../../rules/experimental/) run command below:
To validate with the [standard ruleset](../../rules/standard/) and the [experimental ruleset](../../rules/experimental/) run command below:

```shell title="Validation with standard and experimental ruleset"
ktlint --experimental
Expand Down
Expand Up @@ -11,6 +11,7 @@ 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.CODE_STYLE_PROPERTY
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
Expand Down Expand Up @@ -580,10 +581,10 @@ public class KtLintRuleEngine(
public fun generateKotlinEditorConfigSection(filePath: Path): String {
val codeStyle =
editorConfigOverride
.properties[com.pinterest.ktlint.core.api.editorconfig.CODE_STYLE_PROPERTY]
.properties[CODE_STYLE_PROPERTY]
?.parsed
?.safeAs<CodeStyleValue>()
?: com.pinterest.ktlint.core.api.editorconfig.CODE_STYLE_PROPERTY.defaultValue
?: CODE_STYLE_PROPERTY.defaultValue
val rules =
ruleProviders
.map { RuleRunner(it) }
Expand Down
Expand Up @@ -180,6 +180,7 @@ public object DefaultEditorConfigProperties : UsesEditorConfigProperties {
// ReplaceWith is not specified as the property should not be migrated to KTLINT_DISABLED_RULES_PROPERTY but to
// the RuleExecution property.
)
@Suppress("ktlint:experimental:property-naming")
public val disabledRulesProperty: EditorConfigProperty<String> =
DISABLED_RULES_PROPERTY

Expand Down
Expand Up @@ -17,7 +17,7 @@ public val CODE_STYLE_PROPERTY: EditorConfigProperty<CodeStyleValue> =
type = PropertyType.LowerCasingPropertyType(
"ktlint_code_style",
"The code style ('official' or 'android') to be applied. Defaults to 'official' when not set.",
EnumValueParser(CodeStyleValue::class.java),
SafeEnumValueParser(CodeStyleValue::class.java),
CodeStyleValue.values().map { it.name }.toSet(),
),
defaultValue = CodeStyleValue.official,
Expand Down
Expand Up @@ -14,7 +14,7 @@ internal val RULE_EXECUTION_PROPERTY_TYPE =
PropertyType.LowerCasingPropertyType(
"ktlint_rule_execution",
"When enabled, the rule is being executed.",
PropertyType.PropertyValueParser.EnumValueParser(RuleExecution::class.java),
SafeEnumValueParser(RuleExecution::class.java),
CodeStyleValue.values().map { it.name }.toSet(),
)

Expand Down
@@ -0,0 +1,49 @@
package com.pinterest.ktlint.core.api.editorconfig

import java.util.Locale
import org.ec4j.core.model.PropertyType
import org.ec4j.core.model.PropertyType.PropertyValueParser

/**
* A [PropertyValueParser] implementation that allows only members of a given [Enum] type. This class is almost
* identical to the original [EnumValueParser] provided by ec4j. Difference is that values are trimmed before trying to
* match the enum values.
*
* As the ec4j project has not provided any new release since version 1.0 (2019-08-01) a custom implementation has been
* added.
*
* @param <T> the type of the value <T>
*
*/
internal class SafeEnumValueParser<T : Enum<*>?>(enumType: Class<out T?>) : PropertyValueParser<T> {
private val enumType: Class<out Enum<*>?>

init {
this.enumType = enumType
}

override fun parse(name: String?, value: String?): PropertyType.PropertyValue<T> =
if (value == null) {
PropertyType.PropertyValue.invalid(value, "Cannot make enum " + enumType.name + " out of null")
} else {
try {
PropertyType.PropertyValue.valid(
value,
java.lang.Enum.valueOf(
enumType,
value
// In case an EOL comment (separated with a space) is appended after the value then the comment
// itself is removed but not the space. This results in the enum value not being parsed
// correctly.
.trim()
.lowercase(Locale.getDefault()),
) as T,
)
} catch (e: IllegalArgumentException) {
PropertyType.PropertyValue.invalid(
value,
"Unexpected parsed \"" + value + "\" for enum " + enumType.name,
)
}
}
}
Expand Up @@ -4,6 +4,7 @@ import com.pinterest.ktlint.core.Rule
import com.pinterest.ktlint.core.api.DefaultEditorConfigProperties.writeEditorConfigProperty
import com.pinterest.ktlint.core.api.EditorConfigOverride
import com.pinterest.ktlint.core.api.UsesEditorConfigProperties
import com.pinterest.ktlint.core.api.editorconfig.CODE_STYLE_PROPERTY
import com.pinterest.ktlint.core.api.editorconfig.CodeStyleValue
import com.pinterest.ktlint.core.api.editorconfig.DEFAULT_EDITOR_CONFIG_PROPERTIES
import com.pinterest.ktlint.core.initKtLintKLogger
Expand Down Expand Up @@ -41,7 +42,7 @@ internal class EditorConfigGenerator(
.load(
filePath = filePath,
rules = rules,
editorConfigOverride = EditorConfigOverride.from(com.pinterest.ktlint.core.api.editorconfig.CODE_STYLE_PROPERTY to codeStyle.name),
editorConfigOverride = EditorConfigOverride.from(CODE_STYLE_PROPERTY to codeStyle.name),
)

val potentialEditorConfigSettings =
Expand Down
Expand Up @@ -8,6 +8,7 @@ import com.pinterest.ktlint.core.api.EditorConfigOverride.Companion.EMPTY_EDITOR
import com.pinterest.ktlint.core.api.EditorConfigProperties
import com.pinterest.ktlint.core.api.UsesEditorConfigProperties
import com.pinterest.ktlint.core.api.editorconfig.EditorConfigProperty
import com.pinterest.ktlint.core.api.editorconfig.INDENT_SIZE_PROPERTY
import com.pinterest.ktlint.core.initKtLintKLogger
import com.pinterest.ktlint.core.internal.ThreadSafeEditorConfigCache.Companion.THREAD_SAFE_EDITOR_CONFIG_CACHE
import java.nio.charset.StandardCharsets
Expand Down Expand Up @@ -58,8 +59,8 @@ public class EditorConfigLoader(
.queryProperties(normalizedFilePath.resource())
.properties
.also { loaded ->
if (loaded[TAB_WIDTH_PROPERTY_NAME]?.sourceValue == loaded[com.pinterest.ktlint.core.api.editorconfig.INDENT_SIZE_PROPERTY.name]?.sourceValue &&
editorConfigOverride.properties[com.pinterest.ktlint.core.api.editorconfig.INDENT_SIZE_PROPERTY] != null
if (loaded[TAB_WIDTH_PROPERTY_NAME]?.sourceValue == loaded[INDENT_SIZE_PROPERTY.name]?.sourceValue &&
editorConfigOverride.properties[INDENT_SIZE_PROPERTY] != null
) {
// The tab_width property can not be overridden via the editorConfigOverride. So if it has been
// set to the same value as the indent_size property then keep its value in sync with that
Expand All @@ -68,7 +69,7 @@ public class EditorConfigLoader(
.builder()
.name(TAB_WIDTH_PROPERTY_NAME)
.type(PropertyType.tab_width)
.value(editorConfigOverride.properties[com.pinterest.ktlint.core.api.editorconfig.INDENT_SIZE_PROPERTY]?.source)
.value(editorConfigOverride.properties[INDENT_SIZE_PROPERTY]?.source)
.build()
}
editorConfigOverride
Expand Down
Expand Up @@ -3,7 +3,9 @@ package com.pinterest.ktlint.core.internal
import com.pinterest.ktlint.core.Rule
import com.pinterest.ktlint.core.api.EditorConfigProperties
import com.pinterest.ktlint.core.api.UsesEditorConfigProperties
import com.pinterest.ktlint.core.api.editorconfig.DISABLED_RULES_PROPERTY
import com.pinterest.ktlint.core.api.editorconfig.EditorConfigProperty
import com.pinterest.ktlint.core.api.editorconfig.KTLINT_DISABLED_RULES_PROPERTY
import com.pinterest.ktlint.core.api.editorconfig.RULE_EXECUTION_PROPERTY_TYPE
import com.pinterest.ktlint.core.api.editorconfig.RuleExecution
import com.pinterest.ktlint.core.api.editorconfig.createRuleExecutionEditorConfigProperty
Expand All @@ -29,8 +31,8 @@ internal class VisitorProvider(
recreateRuleSorter: Boolean = false,
) : UsesEditorConfigProperties {
override val editorConfigProperties: List<EditorConfigProperty<*>> = listOf(
com.pinterest.ktlint.core.api.editorconfig.KTLINT_DISABLED_RULES_PROPERTY,
com.pinterest.ktlint.core.api.editorconfig.DISABLED_RULES_PROPERTY,
KTLINT_DISABLED_RULES_PROPERTY,
DISABLED_RULES_PROPERTY,
).plus(
ruleRunners.map {
createRuleExecutionEditorConfigProperty(toQualifiedRuleId(it.ruleSetId, it.ruleId))
Expand Down Expand Up @@ -99,15 +101,15 @@ internal class VisitorProvider(
editorConfigProperties.containsKey(ktLintRuleSetExecutionPropertyName(qualifiedRuleId)) ->
editorConfigProperties.isRuleEnabled(qualifiedRuleId)

editorConfigProperties.containsKey(com.pinterest.ktlint.core.api.editorconfig.KTLINT_DISABLED_RULES_PROPERTY.name) ->
editorConfigProperties.containsKey(KTLINT_DISABLED_RULES_PROPERTY.name) ->
editorConfigProperties.isEnabled(
com.pinterest.ktlint.core.api.editorconfig.KTLINT_DISABLED_RULES_PROPERTY,
KTLINT_DISABLED_RULES_PROPERTY,
qualifiedRuleId,
)

editorConfigProperties.containsKey(com.pinterest.ktlint.core.api.editorconfig.DISABLED_RULES_PROPERTY.name) ->
editorConfigProperties.containsKey(DISABLED_RULES_PROPERTY.name) ->
editorConfigProperties.isEnabled(
com.pinterest.ktlint.core.api.editorconfig.DISABLED_RULES_PROPERTY,
DISABLED_RULES_PROPERTY,
qualifiedRuleId,
)

Expand Down

0 comments on commit 6d5355a

Please sign in to comment.