Skip to content

Commit

Permalink
Allow editorconfig overrides in ktlint 0.49+
Browse files Browse the repository at this point in the history
  • Loading branch information
wakingrufus committed Aug 22, 2023
1 parent e5e6038 commit 059252a
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 20 deletions.
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,32 @@ 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 +64,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,33 @@ 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.EditorConfigOverride.Companion.plus
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 +65,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" },
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,11 @@ internal fun createKtlintConfiguration(target: Project, extension: KtlintExtensi
val dependencyProvider = target.provider {
val ktlintVersion = extension.version.get()
target.logger.info("Add dependency: ktlint version $ktlintVersion")
target.dependencies.create("${resolveGroup(ktlintVersion)}:ktlint:$ktlintVersion")
target.dependencies.create("com.pinterest:ktlint:$ktlintVersion")
}
dependencies.addLater(dependencyProvider)
}

private fun resolveGroup(ktlintVersion: String) = when {
SemVer.parse(ktlintVersion) < SemVer(0, 32, 0) -> "com.github.shyiko"
else -> "com.pinterest"
}

internal fun createKtlintRulesetConfiguration(
target: Project,
ktLintConfiguration: Configuration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import org.gradle.api.file.ConfigurableFileTree
import org.gradle.api.file.ProjectLayout
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.MapProperty
import org.gradle.api.provider.Property
import org.gradle.api.provider.SetProperty
import org.gradle.api.tasks.util.PatternFilterable
Expand Down Expand Up @@ -107,6 +108,10 @@ internal constructor(
*/
@Deprecated("not supported with ktlint 0.47+")
val additionalEditorconfigFile: RegularFileProperty = objectFactory.fileProperty()
val additionalEditorconfig: MapProperty<String, String> =
objectFactory.mapProperty(String::class.java, String::class.java).apply {
convention(emptyMap())
}

/**
* Disable particular rules, by default enabled in ktlint, using rule id.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ private fun BaseKtLintCheckTask.configureBaseCheckTask(
ktLintClasspath.setFrom(pluginHolder.ktlintConfiguration)
ktLintVersion.set(pluginHolder.extension.version)
additionalEditorconfigFile.set(pluginHolder.extension.additionalEditorconfigFile)
additionalEditorconfig.set(pluginHolder.extension.additionalEditorconfig)
debug.set(pluginHolder.extension.debug)
ruleSetsClasspath.setFrom(pluginHolder.ktlintRulesetConfiguration)
android.set(pluginHolder.extension.android)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import org.gradle.api.file.FileType
import org.gradle.api.file.ProjectLayout
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.MapProperty
import org.gradle.api.provider.Property
import org.gradle.api.provider.SetProperty
import org.gradle.api.specs.Spec
Expand Down Expand Up @@ -55,6 +56,8 @@ abstract class BaseKtLintCheckTask @Inject constructor(

@get:Internal
internal abstract val additionalEditorconfigFile: RegularFileProperty
@get:Internal
internal abstract val additionalEditorconfig: MapProperty<String, String>

@get:Incremental
@get:PathSensitive(PathSensitivity.RELATIVE)
Expand Down Expand Up @@ -285,6 +288,7 @@ abstract class BaseKtLintCheckTask @Inject constructor(
params.disabledRules.set(disabledRules)
params.debug.set(debug)
params.additionalEditorconfigFile.set(additionalEditorconfigFile)
params.additionalEditorconfig.set(additionalEditorconfig)
params.formatSource.set(formatSources)
params.discoveredErrorsFile.set(discoveredErrors)
params.ktLintVersion.set(ktLintVersion)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.gradle.api.GradleException
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.logging.Logging
import org.gradle.api.provider.MapProperty
import org.gradle.api.provider.Property
import org.gradle.api.provider.SetProperty
import org.gradle.workers.WorkAction
Expand Down Expand Up @@ -38,6 +39,11 @@ abstract class KtLintWorkAction : WorkAction<KtLintWorkAction.KtLintWorkParamete
) {
logger.warn("additionalEditorconfigFile no longer supported in ktlint 0.47+")
}
if (parameters.additionalEditorconfig.isPresent &&
parameters.ktLintVersion.map { SemVer.parse(it) }.get() < SemVer(0, 49)
) {
logger.warn("additionalEditorconfig not supported until ktlint 0.49")
}
val ktlintInvoker: KtLintInvocation = when (
val ktlintInvokerFactory = selectInvocation(parameters.ktLintVersion.get())
) {
Expand Down Expand Up @@ -82,11 +88,11 @@ abstract class KtLintWorkAction : WorkAction<KtLintWorkAction.KtLintWorkParamete
}

is KtLintInvocation49.Factory -> {
ktlintInvokerFactory.initialize()
ktlintInvokerFactory.initialize(parameters.additionalEditorconfig.get())
}

is KtLintInvocation50.Factory -> {
ktlintInvokerFactory.initialize()
ktlintInvokerFactory.initialize(parameters.additionalEditorconfig.get())
}
else -> {
throw GradleException("Incompatible ktlint version ${parameters.ktLintVersion}")
Expand Down Expand Up @@ -161,6 +167,7 @@ abstract class KtLintWorkAction : WorkAction<KtLintWorkAction.KtLintWorkParamete
val enableExperimental: Property<Boolean>
val debug: Property<Boolean>
val additionalEditorconfigFile: RegularFileProperty
val additionalEditorconfig: MapProperty<String, String>
val formatSource: Property<Boolean>
val discoveredErrorsFile: RegularFileProperty
val ktLintVersion: Property<String>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@ class KtLintSupportedVersionsTest : AbstractPluginTest() {
}
}

@DisplayName("Lint should use editorconfig override")
@DisplayName("Lint should use editorconfig file override")
@ParameterizedTest(name = "{0} with KtLint {1}: {displayName}")
@ArgumentsSource(SupportedKtlintVersionsProvider::class)
internal fun `Lint should use editorconfig override`(
internal fun `Lint should use editorconfig file override`(
gradleVersion: GradleVersion,
ktLintVersion: String
) {
Expand All @@ -93,7 +93,39 @@ class KtLintSupportedVersionsTest : AbstractPluginTest() {
if (SemVer.parse(ktLintVersion) >= SemVer(0, 47)) {
buildAndFail(CHECK_PARENT_TASK_NAME) {
assertThat(task(":$mainSourceSetCheckTaskName")?.outcome).isEqualTo(TaskOutcome.FAILED)
assertThat(output.contains("additionalEditorconfigFile no longer supported in ktlint 0.47+"))
assertThat(output).contains("additionalEditorconfigFile no longer supported in ktlint 0.47+")
}
} else {
build(CHECK_PARENT_TASK_NAME) {
assertThat(task(":$mainSourceSetCheckTaskName")?.outcome).isEqualTo(TaskOutcome.SUCCESS)
}
}
}
}

@DisplayName("Lint should use editorconfig override")
@ParameterizedTest(name = "{0} with KtLint {1}: {displayName}")
@ArgumentsSource(SupportedKtlintVersionsProvider::class)
internal fun `Lint should use editorconfig override`(
gradleVersion: GradleVersion,
ktLintVersion: String
) {
project(gradleVersion) {
//language=Groovy
buildGradle.appendText(
"""
ktlint.version = "$ktLintVersion"
ktlint.additionalEditorconfig = [
"ktlint_standard_no-multi-spaces": "disabled"
]
""".trimIndent()
)
withFailingSources()
if (SemVer.parse(ktLintVersion) < SemVer(0, 49)) {
buildAndFail(CHECK_PARENT_TASK_NAME) {
assertThat(task(":$mainSourceSetCheckTaskName")?.outcome).isEqualTo(TaskOutcome.FAILED)
assertThat(output).contains("additionalEditorconfig not supported until ktlint 0.49")
}
} else {
build(CHECK_PARENT_TASK_NAME) {
Expand Down

0 comments on commit 059252a

Please sign in to comment.