Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reload Ktlint's caches when .editorconfig changes #265

Merged
merged 3 commits into from
Sep 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package org.jmailen.gradle.kotlinter.support

import com.pinterest.ktlint.core.KtLint
import com.pinterest.ktlint.core.api.DefaultEditorConfigProperties
import com.pinterest.ktlint.core.api.EditorConfigOverride
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.ProjectLayout
import org.gradle.api.logging.Logger
import java.io.File

internal fun editorConfigOverride(ktLintParams: KtLintParams): EditorConfigOverride {
Expand All @@ -15,6 +18,17 @@ internal fun editorConfigOverride(ktLintParams: KtLintParams): EditorConfigOverr
}
}

internal fun resetEditorconfigCacheIfNeeded(
changedEditorconfigFiles: ConfigurableFileCollection,
logger: Logger,
) {
val changedFiles = changedEditorconfigFiles.files
if (changedFiles.any()) {
logger.info("Editorconfig changed, resetting KtLint caches")
changedFiles.map(File::toPath).forEach(KtLint::reloadEditorConfigFile)
jeremymailen marked this conversation as resolved.
Show resolved Hide resolved
}
}

internal fun ProjectLayout.findApplicableEditorConfigFiles(): Sequence<File> {
jeremymailen marked this conversation as resolved.
Show resolved Hide resolved
val projectEditorConfig = projectDirectory.file(".editorconfig").asFile

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.SourceTask
import org.gradle.internal.exceptions.MultiCauseException
import org.gradle.work.FileChange
import org.gradle.work.Incremental
import org.gradle.work.InputChanges
import org.jmailen.gradle.kotlinter.KotlinterExtension.Companion.DEFAULT_DISABLED_RULES
import org.jmailen.gradle.kotlinter.KotlinterExtension.Companion.DEFAULT_EXPERIMENTAL_RULES
import org.jmailen.gradle.kotlinter.support.KtLintParams
Expand All @@ -31,6 +34,7 @@ abstract class ConfigurableKtLintTask(

@get:InputFiles
@get:PathSensitive(PathSensitivity.RELATIVE)
@get:Incremental
internal val editorconfigFiles: FileCollection = objectFactory.fileCollection().apply {
from(projectLayout.findApplicableEditorConfigFiles().toList())
}
Expand All @@ -40,6 +44,13 @@ abstract class ConfigurableKtLintTask(
experimentalRules = experimentalRules.get(),
disabledRules = disabledRules.get(),
)

protected fun getChangedEditorconfigFiles(inputChanges: InputChanges) =
if (inputChanges.isIncremental) {
inputChanges.getFileChanges(editorconfigFiles).map(FileChange::getFile)
} else {
emptyList()
}
}

internal inline fun <reified T> ObjectFactory.property(default: T? = null): Property<T> =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import org.gradle.api.model.ObjectFactory
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import org.gradle.work.InputChanges
import org.gradle.workers.WorkerExecutor
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
import org.jmailen.gradle.kotlinter.support.KotlinterError
Expand All @@ -31,14 +32,15 @@ open class FormatTask @Inject constructor(
}

@TaskAction
fun run() {
fun run(inputChanges: InputChanges) {
val result = with(workerExecutor.noIsolation()) {
submit(FormatWorkerAction::class.java) { p ->
p.name.set(name)
p.files.from(source)
p.projectDirectory.set(projectLayout.projectDirectory.asFile)
p.ktLintParams.set(getKtLintParams())
p.output.set(report)
p.changedEditorConfigFiles.from(getChangedEditorconfigFiles(inputChanges))
}
runCatching { await() }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import org.gradle.api.tasks.OutputFiles
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
import org.gradle.work.InputChanges
import org.gradle.workers.WorkerExecutor
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
import org.jmailen.gradle.kotlinter.KotlinterExtension.Companion.DEFAULT_IGNORE_FAILURES
Expand Down Expand Up @@ -43,14 +44,15 @@ open class LintTask @Inject constructor(
val ignoreFailures: Property<Boolean> = objectFactory.property(default = DEFAULT_IGNORE_FAILURES)

@TaskAction
fun run() {
fun run(inputChanges: InputChanges) {
val result = with(workerExecutor.noIsolation()) {
submit(LintWorkerAction::class.java) { p ->
p.name.set(name)
p.files.from(source)
p.projectDirectory.set(projectLayout.projectDirectory.asFile)
p.reporters.putAll(reports)
p.ktLintParams.set(getKtLintParams())
p.changedEditorconfigFiles.from(getChangedEditorconfigFiles(inputChanges))
}
runCatching { await() }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import org.jmailen.gradle.kotlinter.support.KotlinterError
import org.jmailen.gradle.kotlinter.support.KtLintParams
import org.jmailen.gradle.kotlinter.support.defaultRuleSetProviders
import org.jmailen.gradle.kotlinter.support.editorConfigOverride
import org.jmailen.gradle.kotlinter.support.resetEditorconfigCacheIfNeeded
import org.jmailen.gradle.kotlinter.support.resolveRuleProviders
import org.jmailen.gradle.kotlinter.tasks.FormatTask
import java.io.File
Expand All @@ -25,6 +26,11 @@ abstract class FormatWorkerAction : WorkAction<FormatWorkerParameters> {
private val output: File? = parameters.output.asFile.orNull

override fun execute() {
resetEditorconfigCacheIfNeeded(
changedEditorconfigFiles = parameters.changedEditorConfigFiles,
logger = logger,
)

val fixes = mutableListOf<String>()
try {
files.forEach { file ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import org.jmailen.gradle.kotlinter.support.KtLintParams

interface FormatWorkerParameters : WorkParameters {
val name: Property<String>
val changedEditorConfigFiles: ConfigurableFileCollection
val files: ConfigurableFileCollection
val projectDirectory: RegularFileProperty
val ktLintParams: Property<KtLintParams>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import org.jmailen.gradle.kotlinter.support.defaultRuleSetProviders
import org.jmailen.gradle.kotlinter.support.editorConfigOverride
import org.jmailen.gradle.kotlinter.support.reporterFor
import org.jmailen.gradle.kotlinter.support.reporterPathFor
import org.jmailen.gradle.kotlinter.support.resetEditorconfigCacheIfNeeded
import org.jmailen.gradle.kotlinter.support.resolveRuleProviders
import org.jmailen.gradle.kotlinter.tasks.LintTask
import java.io.File
Expand All @@ -30,6 +31,10 @@ abstract class LintWorkerAction : WorkAction<LintWorkerParameters> {
private val ktLintParams: KtLintParams = parameters.ktLintParams.get()

override fun execute() {
resetEditorconfigCacheIfNeeded(
changedEditorconfigFiles = parameters.changedEditorconfigFiles,
logger = logger,
)
var hasError = false

try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import java.io.File

interface LintWorkerParameters : WorkParameters {
val name: Property<String>
val changedEditorconfigFiles: ConfigurableFileCollection
val files: ConfigurableFileCollection
val projectDirectory: RegularFileProperty
val reporters: MapProperty<String, File>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package org.jmailen.gradle.kotlinter.functional

import org.gradle.testkit.runner.TaskOutcome
import org.jmailen.gradle.kotlinter.functional.utils.editorConfig
import org.jmailen.gradle.kotlinter.functional.utils.kotlinClass
import org.jmailen.gradle.kotlinter.functional.utils.resolve
import org.jmailen.gradle.kotlinter.functional.utils.settingsFile
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
Expand Down Expand Up @@ -55,9 +57,10 @@ internal class EditorConfigTest : WithGradleTest.Kotlin() {
fun `plugin respects disabled_rules set in editorconfig`() {
projectRoot.resolve(".editorconfig") {
appendText(
// language=editorconfig
"""
[*.{kt,kts}]
disabled_rules=filename
ktlint_disabled_rules = filename
""".trimIndent(),
)
}
Expand All @@ -71,9 +74,10 @@ internal class EditorConfigTest : WithGradleTest.Kotlin() {
}

@Test
fun `plugin respects 'indent_size' set in editorconfig`() {
fun `plugin respects 'indent_size' set in editorconfig`() {
projectRoot.resolve(".editorconfig") {
appendText(
// language=editorconfig
"""
[*.{kt,kts}]
indent_size = 6
Expand All @@ -99,4 +103,75 @@ internal class EditorConfigTest : WithGradleTest.Kotlin() {
assertTrue(output.contains("[indent] Unexpected indentation (2) (should be 6)"))
}
}

@Test
fun `editorconfig changes are taken into account on lint task re-runs`() {
projectRoot.resolve(".editorconfig") {
writeText(
// language=editorconfig
"""
[*.{kt,kts}]
ktlint_disabled_rules = filename
""".trimIndent(),
)
}
projectRoot.resolve("src/main/kotlin/FileName.kt") {
writeText(kotlinClass("DifferentClassName"))
}
build("lintKotlin").apply {
assertEquals(TaskOutcome.SUCCESS, task(":lintKotlinMain")?.outcome)
assertFalse(output.contains("resetting KtLint caches"))
}

projectRoot.resolve(".editorconfig") {
writeText(editorConfig)
}
buildAndFail("lintKotlin", "--info").apply {
assertEquals(TaskOutcome.FAILED, task(":lintKotlinMain")?.outcome)
assertTrue(output.contains("[filename] File 'FileName.kt' contains a single top level declaration"))
assertTrue(output.contains("resetting KtLint caches"))
}

projectRoot.resolve("src/main/kotlin/FileName.kt") {
writeText(kotlinClass("FileName"))
}
build("lintKotlin").apply {
assertEquals(TaskOutcome.SUCCESS, task(":lintKotlinMain")?.outcome)
assertFalse(output.contains("resetting KtLint caches"))
}
build("lintKotlin").apply {
assertEquals(TaskOutcome.UP_TO_DATE, task(":lintKotlinMain")?.outcome)
assertFalse(output.contains("resetting KtLint caches"))
}
}

@Test
fun `editorconfig changes are ignored for format task re-runs`() {
projectRoot.resolve(".editorconfig") {
writeText(editorConfig)
}

projectRoot.resolve("src/main/kotlin/FileName.kt") {
writeText(kotlinClass("DifferentClassName"))
}
build("formatKotlin").apply {
assertEquals(TaskOutcome.SUCCESS, task(":formatKotlinMain")?.outcome)
assertTrue(output.contains("Format could not fix > [filename] File 'FileName.kt' contains a single top level declaration"))
}

projectRoot.resolve(".editorconfig") {
writeText(
// language=editorconfig
"""
[*.{kt,kts}]
ktlint_disabled_rules = filename
""".trimIndent(),
)
}
build("formatKotlin", "--info").apply {
assertEquals(TaskOutcome.SUCCESS, task(":formatKotlinMain")?.outcome)
assertTrue(output.contains("Format could not fix"))
assertFalse(output.contains("resetting KtLint caches"))
}
}
}