Skip to content

Commit

Permalink
Add build task experimental rules (#1307)
Browse files Browse the repository at this point in the history
* Add separate verification build step to include experimental rules

Ktlint should apply the dogfooding principal and only provide experimental
rules that at least on the ktlint code base itself gives satisfiable
results.

Initially all experimental rules that cause violations have been disabled,
so that a separate commit can be created to enable each specific rule.

* Enable rule experimental:spacing-between-declarations-with-comments

For BaselineTests it was necessary to rename the files which are used for testing
to have a non standard kotlin file extension. This prevents the files from being
changed when running the ktlint formatting on the ktlint code base itself. Note
that the baseline protection mechanism did work in this case and as of that has
been removed from the command.

* Enable rule experimental:no-empty-first-line-in-method-block

* Enable rule experimental:annotation

* Resolve some violations of rule experimental:argument-list-wrapping

It is not yet possible to enable the rule as some violations are actually false
positives. This will be solved by #1284

* Enable rule experimental:spacing-between-declarations-with-annotations

* Enable rule experimental:trailing-comma

For now, it has been chosen to disallow trailing comma's instead of forcing them to
be added. Reasons for this are two folded. The number of changes is considerably
smaller. More importantly is that the benefit, with respect to avoiding future merge
conflicts, seems not that big when scanning the code change which would result from
forcing the trailing comma to be added.

* Update changelog

* Remove autocorrect mode from build step ktlint_experimental

* Run the experimental rules by default

There is no need for a separate build task to run the experimental rules. The
experimental rules can be executed by default in the "ktlint" task. Also, the
baseline has been fixed so there is no longer a need to use extension "_kt"
for the baseline test files.

Closes #1222

* Update ktlint/src/test/resources/TestBaselineFile.kt

* Update ktlint/src/test/resources/TestBaselineFile.kt

* Update ktlint/src/test/resources/TestBaselineExtraErrorFile.kt

* Update ktlint/src/test/resources/TestBaselineExtraErrorFile.kt

* Revert BaselineTests

* Revert ktlint-test-baseline

* Fix tests

* Exclude all test resources from the ktlint module from the linting task

Those source files all contain linting errors which have to be reported
by unit tests. Therefore they should not be reported during a normal
build because those should not be fixed as that would result in the
tests to fail.

* Revert renaming of file test-baseline.xml

* Fix lint errors due to merge of master in branch

Co-authored-by: Paul Dingemans <pdingemans@bol.com>
Co-authored-by: Roman Zavarnitsyn <rom4ek93@gmail.com>
  • Loading branch information
3 people authored Jan 21, 2022
1 parent e5206c3 commit 77c60e5
Show file tree
Hide file tree
Showing 26 changed files with 101 additions and 106 deletions.
8 changes: 8 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ indent_size = 4

[*.{kt,kts}]
ij_kotlin_imports_layout=*
# Ideally, no experimental rule should be disabled. Ktlint should follow the dogfooding principle. This means that an
# experimental rule should only be added to the master branch no sooner than that this rule has been applied on the
# ktlint code base itself.
# For now, the experimental:argument-list-wrapping still needs to be disabled as it fails the build due to false
# positives. See https://github.com/pinterest/ktlint/pull/1284
disabled_rules=experimental:argument-list-wrapping
ij_kotlin_allow_trailing_comma=false
ij_kotlin_allow_trailing_comma_on_call_site=false

[{Makefile,*.go}]
indent_style = tab
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- Update Kotlin version to `1.6.0` release
- Add separate tasks to run tests on JDK 11 - "testOnJdk11"
- Update Dokka to `1.6.0` release
- Apply ktlint experimental rules on the ktlint code base itself.
- Update shadow plugin to `7.1.1` release

### Removed
Expand Down
8 changes: 6 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,14 @@ dependencies {
}

task ktlint(type: JavaExec, group: LifecycleBasePlugin.VERIFICATION_GROUP) {
description = "Check Kotlin code style."
description = "Check Kotlin code style including experimental rules."
classpath = configurations.ktlint
main = 'com.pinterest.ktlint.Main'
args '**/src/**/*.kt', '!**/resources/cli/**', '--baseline=ktlint-baseline.xml', '--verbose'
// Experimental rules run by default run on the ktlint code base itself. Experimental rules should not be released if
// we are not pleased ourselves with the results on the ktlint code base.
// Sources in "ktlint/src/test/resources" are excluded as those source contain lint errors that have to be detected by
// unit tests and should not be reported/fixed.
args '**/src/**/*.kt', '!ktlint/src/test/resources/**', '--baseline=ktlint/src/test/resources/test-baseline.xml', '--experimental', '--verbose'
}

/**
Expand Down
11 changes: 0 additions & 11 deletions ktlint-baseline.xml

This file was deleted.

10 changes: 2 additions & 8 deletions ktlint-core/src/main/kotlin/com/pinterest/ktlint/core/KtLint.kt
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public object KtLint {
val cb: (e: LintError, corrected: Boolean) -> Unit,
val script: Boolean = false,
val editorConfigPath: String? = null,
val debug: Boolean = false,
val debug: Boolean = false
)

/**
Expand Down Expand Up @@ -97,7 +97,7 @@ public object KtLint {
val editorConfigPath: String? = null,
val debug: Boolean = false,
val editorConfigOverride: EditorConfigOverridesMap = emptyMap(),
val isInvokedFromCli: Boolean = false,
val isInvokedFromCli: Boolean = false
) {
internal val normalizedFilePath: Path? get() = if (fileName == STDIN_FILE || fileName == null) {
null
Expand Down Expand Up @@ -358,12 +358,6 @@ public object KtLint {
@OptIn(FeatureInAlphaState::class)
public fun format(params: Params): String = format(toExperimentalParams(params))

/**
* Fix style violations.
*
* @throws ParseException if text is not a valid Kotlin code
* @throws RuleExecutionException in case of internal failure caused by a bug in rule implementation
*/
/**
* Fix style violations.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,18 @@ interface Reporter {
* It's guarantied to be called before any of the other [Reporter]s methods.
*/
fun beforeAll() {}

/**
* Called when file (matching the pattern) is found but before it's parsed.
*/
fun before(file: String) {}
fun onLintError(file: String, err: LintError, corrected: Boolean)

/**
* Called after ktlint is done with the file.
*/
fun after(file: String) {}

/**
* Called once, after all the files (if any) have been processed.
* It's guarantied to be called after all other [Reporter]s methods.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ abstract class Rule(val id: String) {
* (in other words, [visit] will be called on [FileASTNode] but not on [FileASTNode] children).
*/
interface RestrictToRoot

/**
* Marker interface to indicate that rule must be executed after all other rules (order among multiple
* [RestrictToRootLast] rules is not defined and should be assumed to be random).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ package com.pinterest.ktlint.core.api
@Target(
AnnotationTarget.CLASS,
AnnotationTarget.FUNCTION,
AnnotationTarget.TYPEALIAS,
AnnotationTarget.TYPEALIAS
)
public annotation class FeatureInAlphaState

Expand All @@ -20,6 +20,6 @@ public annotation class FeatureInAlphaState
@Target(
AnnotationTarget.CLASS,
AnnotationTarget.FUNCTION,
AnnotationTarget.TYPEALIAS,
AnnotationTarget.TYPEALIAS
)
public annotation class FeatureInBetaState
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ internal class EditorConfigGeneratorTest {

val generatedEditorConfig = editorConfigGenerator.generateEditorconfig(
filePath = tempFileSystem.normalizedPath(rootDir).resolve("test.kt"),
rules = rules,
rules = rules
)

assertThat(generatedEditorConfig.lines()).doesNotContainAnyElementsOf(listOf("root = true"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ internal class EditorConfigLoaderTest {
.isEqualTo(
mapOf(
"indent_size" to "2",
"tab_width" to "2",
"tab_width" to "2"
)
)
}
Expand Down Expand Up @@ -137,7 +137,7 @@ internal class EditorConfigLoaderTest {
mapOf(
"indent_size" to "2",
"tab_width" to "2",
"indent_style" to "space",
"indent_style" to "space"
)
)

Expand All @@ -149,7 +149,7 @@ internal class EditorConfigLoaderTest {
mapOf(
"indent_size" to "4",
"tab_width" to "4",
"indent_style" to "space",
"indent_style" to "space"
)
)

Expand All @@ -159,15 +159,17 @@ internal class EditorConfigLoaderTest {

assertThat(parsedEditorConfig).isEqualTo(
mapOf(
"end_of_line" to "lf",
"end_of_line" to "lf"
)
)
}

@Test
fun `Should parse assignment with spaces`() {
val projectDir = "/project"
@Language("EditorConfig") val editorconfigFile =

@Language("EditorConfig")
val editorconfigFile =
"""
[*.{kt,kts}]
insert_final_newline = true
Expand All @@ -183,15 +185,17 @@ internal class EditorConfigLoaderTest {
assertThat(parsedEditorConfig).isEqualTo(
mapOf(
"insert_final_newline" to "true",
"disabled_rules" to "import-ordering",
"disabled_rules" to "import-ordering"
)
)
}

@Test
fun `Should parse unset values`() {
val projectDir = "/project"
@Language("EditorConfig") val editorconfigFile =

@Language("EditorConfig")
val editorconfigFile =
"""
[*.{kt,kts}]
indent_size = unset
Expand All @@ -206,15 +210,17 @@ internal class EditorConfigLoaderTest {
assertThat(parsedEditorConfig).isEqualTo(
mapOf(
"indent_size" to "unset",
"tab_width" to "unset",
"tab_width" to "unset"
)
)
}

@Test
fun `Should parse list with spaces after comma`() {
val projectDir = "/project"
@Language("EditorConfig") val editorconfigFile =

@Language("EditorConfig")
val editorconfigFile =
"""
[*.{kt,kts}]
disabled_rules=import-ordering, no-wildcard-imports
Expand All @@ -228,7 +234,7 @@ internal class EditorConfigLoaderTest {
assertThat(parsedEditorConfig).isNotEmpty
assertThat(parsedEditorConfig).isEqualTo(
mapOf(
"disabled_rules" to "import-ordering, no-wildcard-imports",
"disabled_rules" to "import-ordering, no-wildcard-imports"
)
)
}
Expand All @@ -253,7 +259,8 @@ internal class EditorConfigLoaderTest {

@Test
fun `Should return properties for stdin from current directory`() {
@Language("EditorConfig") val editorconfigFile =
@Language("EditorConfig")
val editorconfigFile =
"""
[*.{kt,kts}]
insert_final_newline = true
Expand All @@ -265,7 +272,7 @@ internal class EditorConfigLoaderTest {
filePath = null,
isStdIn = true,
rules = rules,
debug = true,
debug = true
)
val parsedEditorConfig = editorConfigProperties.convertToRawValues()

Expand Down Expand Up @@ -377,7 +384,9 @@ internal class EditorConfigLoaderTest {
@Test
fun `Should support editorconfig globs when loading properties for file specified under such glob`() {
val projectDir = "/project"
@Language("EditorConfig") val editorconfigFile =

@Language("EditorConfig")
val editorconfigFile =
"""
[*.{kt,kts}]
insert_final_newline = true
Expand All @@ -398,15 +407,17 @@ internal class EditorConfigLoaderTest {
assertThat(parsedEditorConfig).isEqualTo(
mapOf(
"insert_final_newline" to "true",
"disabled_rules" to "class-must-be-internal",
"disabled_rules" to "class-must-be-internal"
)
)
}

@Test
fun `Should add property from override`() {
val projectDir = "/project"
@Language("EditorConfig") val editorconfigFile =

@Language("EditorConfig")
val editorconfigFile =
"""
[*.{kt,kts}]
disabled_rules=import-ordering, no-wildcard-imports
Expand Down Expand Up @@ -436,7 +447,9 @@ internal class EditorConfigLoaderTest {
@Test
fun `Should replace property from override`() {
val projectDir = "/project"
@Language("EditorConfig") val editorconfigFile =

@Language("EditorConfig")
val editorconfigFile =
"""
[*.{kt,kts}]
insert_final_newline = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,49 +16,34 @@ class BaselineReporterTest {
val reporter = BaselineReporter(PrintStream(out, true))
reporter.onLintError(
"$basePath/one-fixed-and-one-not.kt",
LintError(
1, 1, "rule-1",
"<\"&'>"
),
LintError(1, 1, "rule-1", "<\"&'>"),
false
)
reporter.onLintError(
"$basePath/one-fixed-and-one-not.kt",
LintError(
2, 1, "rule-2",
"And if you see my friend"
),
LintError(2, 1, "rule-2", "And if you see my friend"),
true
)

reporter.onLintError(
"$basePath/two-not-fixed.kt",
LintError(
1, 10, "rule-1",
"I thought I would again"
),
LintError(1, 10, "rule-1", "I thought I would again"),
false
)
reporter.onLintError(
"$basePath/two-not-fixed.kt",
LintError(
2, 20, "rule-2",
"A single thin straight line"
),
LintError(2, 20, "rule-2", "A single thin straight line"),
false
)

reporter.onLintError(
"$basePath/all-corrected.kt",
LintError(
1, 1, "rule-1",
"I thought we had more time"
),
LintError(1, 1, "rule-1", "I thought we had more time"),
true
)
reporter.afterAll()
assertThat(String(out.toByteArray())).isEqualTo(
"""
"""
<?xml version="1.0" encoding="utf-8"?>
<baseline version="1.0">
<file name="one-fixed-and-one-not.kt">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ class HtmlReporter(private val out: PrintStream) : Reporter {
}
body {
if (!acc.isEmpty()) {

h1 { text("Overview") }

paragraph {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class EnumEntryNameCaseRuleTest {
5,
"enum-entry-name-case",
EnumEntryNameCaseRule.ERROR_MESSAGE
),
)
)
)
}
Expand Down
Loading

0 comments on commit 77c60e5

Please # to comment.