Skip to content

Commit

Permalink
Ktlint 1.0 support (fixes #706) (#708)
Browse files Browse the repository at this point in the history
Allow editorconfig overrides in ktlint 0.49+ (fixes #707) using pinterest/ktlint#2194
  • Loading branch information
wakingrufus committed Sep 18, 2023
1 parent e5e6038 commit 96dfaab
Show file tree
Hide file tree
Showing 17 changed files with 357 additions and 43 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/).

## [Unreleased]

- ktlint 1.0 support [#708](https://github.com/JLLeitschuh/ktlint-gradle/pull/708)
- Allow editorconfig overrides in ktlint 0.49+ [#708](https://github.com/JLLeitschuh/ktlint-gradle/pull/708)
- update latest version text file manually [#700](https://github.com/JLLeitschuh/ktlint-gradle/pull/700)

## [11.5.1] - 2023-08-07
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,8 @@ object will be used.

The version of ktlint used by default _may change_ between patch versions of this plugin.
If you don't want to inherit these changes then make sure you lock your version here.
Consult the [ktlint release notes](https://github.com/pinterest/ktlint/releases) for more information about the differences between ktlint versions.

<details>
<summary>Groovy</summary>

Expand All @@ -287,6 +289,9 @@ ktlint {
ignoreFailures = true
enableExperimentalRules = true
additionalEditorconfigFile = file("/some/additional/.editorconfig") // not supported with ktlint 0.47+
additionalEditorconfig = [ // not supported until ktlint 0.49
"max_line_length": "20"
]
disabledRules = ["final-newline"] // not supported with ktlint 0.48+
baseline = file("my-project-ktlint-baseline.xml")
reporters {
Expand Down Expand Up @@ -339,6 +344,11 @@ configure<org.jlleitschuh.gradle.ktlint.KtlintExtension> {
ignoreFailures.set(true)
enableExperimentalRules.set(true)
additionalEditorconfigFile.set(file("/some/additional/.editorconfig")) // not supported with ktlint 0.47+
additionalEditorconfig.set( // not supported until ktlint 0.49
mapOf(
"max_line_length" to "20"
)
)
disabledRules.set(setOf("final-newline")) // not supported with ktlint 0.48+
baseline.set(file("my-project-ktlint-baseline.xml"))
reporters {
Expand Down
14 changes: 12 additions & 2 deletions plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ sourceSets {
val adapter50 by creating {
compileClasspath += adapter.output
}
val adapter100 by creating {
compileClasspath += adapter.output
}
val adapters = listOf(
adapter,
adapter34,
Expand All @@ -97,7 +100,8 @@ sourceSets {
adapter47,
adapter48,
adapter49,
adapter50
adapter50,
adapter100
)
val main by getting {
kotlin {
Expand All @@ -121,7 +125,8 @@ val adapterSources = listOf(
sourceSets.named("adapter47"),
sourceSets.named("adapter48"),
sourceSets.named("adapter49"),
sourceSets.named("adapter50")
sourceSets.named("adapter50"),
sourceSets.named("adapter100")
)
tasks.named<Jar>("shadowJar") {
this.from(adapterSources.map { sourceSet -> sourceSet.map { it.output.classesDirs } })
Expand Down Expand Up @@ -159,6 +164,11 @@ dependencies {
add("adapter50CompileOnly", "com.pinterest.ktlint:ktlint-ruleset-standard:0.50.0")
add("adapter50CompileOnly", "com.pinterest.ktlint:ktlint-reporter-baseline:0.50.0")

add("adapter100CompileOnly", "com.pinterest.ktlint:ktlint-cli-reporter-core:1.0.0")
add("adapter100CompileOnly", "com.pinterest.ktlint:ktlint-rule-engine:1.0.0")
add("adapter100CompileOnly", "com.pinterest.ktlint:ktlint-ruleset-standard:1.0.0")
add("adapter100CompileOnly", "com.pinterest.ktlint:ktlint-cli-reporter-baseline:1.0.0")

compileOnly(libs.kotlin.gradle.plugin)
compileOnly(libs.android.gradle.plugin)
compileOnly(kotlin("stdlib-jdk8"))
Expand Down
2 changes: 1 addition & 1 deletion plugin/settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ pluginManagement {
val latestRelease = file("VERSION_LATEST_RELEASE.txt").readText().trim()
plugins {
id("org.jlleitschuh.gradle.ktlint") version latestRelease
id("org.jetbrains.kotlin.jvm") version "1.7.21"
id("org.jetbrains.kotlin.jvm") version "1.9.0"
id("com.gradle.plugin-publish") version "0.15.0"
`java-gradle-plugin`
`maven-publish`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package org.jlleitschuh.gradle.ktlint.worker

import com.pinterest.ktlint.cli.ruleset.core.api.RuleSetProviderV3
import com.pinterest.ktlint.rule.engine.api.Code
import com.pinterest.ktlint.rule.engine.api.EditorConfigOverride
import com.pinterest.ktlint.rule.engine.api.EditorConfigPropertyRegistry
import com.pinterest.ktlint.rule.engine.api.KtLintRuleEngine
import com.pinterest.ktlint.rule.engine.api.LintError
import com.pinterest.ktlint.rule.engine.core.api.RuleProvider
import java.io.File
import java.util.ServiceLoader

class KtLintInvocation100(
private val engine: KtLintRuleEngine
) : KtLintInvocation {
companion object Factory : KtLintInvocationFactory {
fun initialize(editorConfigOverrides: Map<String, String>): KtLintInvocation {
val ruleProviders = loadRuleSetsFromClasspathWithRuleSetProviderV3()
val editorConfigPropertyRegistry = EditorConfigPropertyRegistry(ruleProviders)
val engine = if (editorConfigOverrides.isEmpty()) {
KtLintRuleEngine(ruleProviders = ruleProviders)
} else {
KtLintRuleEngine(
ruleProviders = ruleProviders,
editorConfigOverride = EditorConfigOverride.from(
*editorConfigOverrides
.mapKeys { editorConfigPropertyRegistry.find(it.key) }
.entries
.map { it.key to it.value }
.toTypedArray()
)
)
}
return KtLintInvocation100(engine)
}

private fun loadRuleSetsFromClasspathWithRuleSetProviderV3(): Set<RuleProvider> {
return ServiceLoader
.load(RuleSetProviderV3::class.java)
.flatMap { it.getRuleProviders() }
.toSet()
}
}

override fun invokeLint(file: File): LintErrorResult {
val errors = mutableListOf<Pair<SerializableLintError, Boolean>>()
engine.lint(Code.fromFile(file)) { le: LintError ->
errors.add(le.toSerializable() to false)
}
return LintErrorResult(file, errors)
}

override fun invokeFormat(file: File): Pair<String, LintErrorResult> {
val errors = mutableListOf<Pair<SerializableLintError, Boolean>>()
val newCode =
engine.format(Code.fromFile(file)) { le, boolean ->
errors.add(le.toSerializable() to boolean)
}
return newCode to LintErrorResult(file, errors)
}

override fun trimMemory() {
engine.trimMemory()
}
}

internal fun LintError.toSerializable(): SerializableLintError {
return SerializableLintError(line, col, ruleId.value, detail, canBeAutoCorrected)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.jlleitschuh.gradle.ktlint.worker

import com.pinterest.ktlint.core.KtLint
import com.pinterest.ktlint.core.LintError
import com.pinterest.ktlint.core.RuleSet
import com.pinterest.ktlint.core.RuleSetProvider
import com.pinterest.ktlint.core.api.DefaultEditorConfigProperties
import com.pinterest.ktlint.core.api.EditorConfigOverride
Expand All @@ -10,7 +11,7 @@ import java.util.ServiceLoader

class KtLintInvocation46(
private val editorConfigPath: String?,
private val ruleSets: Set<com.pinterest.ktlint.core.RuleSet>,
private val ruleSets: Set<RuleSet>,
private val userData: Map<String, String>,
private val debug: Boolean
) : KtLintInvocation {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,34 @@ package org.jlleitschuh.gradle.ktlint.worker

import com.pinterest.ktlint.cli.ruleset.core.api.RuleSetProviderV3
import com.pinterest.ktlint.rule.engine.api.Code
import com.pinterest.ktlint.rule.engine.api.EditorConfigOverride
import com.pinterest.ktlint.rule.engine.api.KtLintRuleEngine
import com.pinterest.ktlint.rule.engine.api.LintError
import com.pinterest.ktlint.rule.engine.core.api.RuleProvider
import com.pinterest.ktlint.rule.engine.core.api.editorconfig.EditorConfigProperty
import java.io.File
import java.util.ServiceLoader

class KtLintInvocation49(
private val engine: KtLintRuleEngine
) : KtLintInvocation {
companion object Factory : KtLintInvocationFactory {
fun initialize(): KtLintInvocation {
val engine = KtLintRuleEngine(
ruleProviders = loadRuleSetsFromClasspathWithRuleSetProviderV3()
)
fun initialize(editorConfigOverrides: Map<String, String>): KtLintInvocation {
val ruleProviders = loadRuleSetsFromClasspathWithRuleSetProviderV3()
val engine = if (editorConfigOverrides.isEmpty()) {
KtLintRuleEngine(ruleProviders = ruleProviders)
} else {
KtLintRuleEngine(
ruleProviders = ruleProviders,
editorConfigOverride = EditorConfigOverride.from(
*editorConfigOverrides
.mapKeys { ruleProviders.findEditorConfigProperty(it.key) }
.entries
.map { it.key to it.value }
.toTypedArray()
)
)
}
return KtLintInvocation49(engine)
}

Expand Down Expand Up @@ -52,3 +66,21 @@ class KtLintInvocation49(
internal fun LintError.toSerializable(): SerializableLintError {
return SerializableLintError(line, col, ruleId.value, detail, canBeAutoCorrected)
}

private fun Set<RuleProvider>.findEditorConfigProperty(propertyName: String): EditorConfigProperty<*> {
val properties =
map { it.createNewRuleInstance() }
.flatMap { it.usesEditorConfigProperties }
.distinct()
return properties
.find { it.type.name == propertyName }
?: throw RuntimeException(
properties
.map { it.type.name }
.sorted()
.joinToString(
prefix = "Property with name '$propertyName' is not found in any of given rules. Available properties:\n\t",
separator = "\n\t"
) { "- $it" }
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,34 @@ package org.jlleitschuh.gradle.ktlint.worker

import com.pinterest.ktlint.cli.ruleset.core.api.RuleSetProviderV3
import com.pinterest.ktlint.rule.engine.api.Code
import com.pinterest.ktlint.rule.engine.api.EditorConfigOverride
import com.pinterest.ktlint.rule.engine.api.KtLintRuleEngine
import com.pinterest.ktlint.rule.engine.api.LintError
import com.pinterest.ktlint.rule.engine.core.api.RuleProvider
import com.pinterest.ktlint.rule.engine.core.api.editorconfig.EditorConfigProperty
import java.io.File
import java.util.ServiceLoader

class KtLintInvocation50(
private val engine: KtLintRuleEngine
) : KtLintInvocation {
companion object Factory : KtLintInvocationFactory {
fun initialize(): KtLintInvocation {
val engine = KtLintRuleEngine(
ruleProviders = loadRuleSetsFromClasspathWithRuleSetProviderV3()
)
fun initialize(editorConfigOverrides: Map<String, String>): KtLintInvocation {
val ruleProviders = loadRuleSetsFromClasspathWithRuleSetProviderV3()
val engine = if (editorConfigOverrides.isEmpty()) {
KtLintRuleEngine(ruleProviders = ruleProviders)
} else {
KtLintRuleEngine(
ruleProviders = ruleProviders,
editorConfigOverride = EditorConfigOverride.from(
*editorConfigOverrides
.mapKeys { ruleProviders.findEditorConfigProperty(it.key) }
.entries
.map { it.key to it.value }
.toTypedArray()
)
)
}
return KtLintInvocation50(engine)
}

Expand Down Expand Up @@ -52,3 +66,21 @@ class KtLintInvocation50(
internal fun LintError.toSerializable(): SerializableLintError {
return SerializableLintError(line, col, ruleId.value, detail, canBeAutoCorrected)
}

private fun Set<RuleProvider>.findEditorConfigProperty(propertyName: String): EditorConfigProperty<*> {
val properties =
map { it.createNewRuleInstance() }
.flatMap { it.usesEditorConfigProperties }
.distinct()
return properties
.find { it.type.name == propertyName }
?: throw RuntimeException(
properties
.map { it.type.name }
.sorted()
.joinToString(
prefix = "Property with name '$propertyName' is not found in any of given rules. Available properties:\n\t",
separator = "\n\t"
) { "- $it" }
)
}
Loading

0 comments on commit 96dfaab

Please sign in to comment.