Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix detection of android kotlin source directories in AGP >= 7
Browse files Browse the repository at this point in the history
increase maximum gradle version to 8.5
increase maximum ktlint version to 1.1.0
increase maximum kotlin version to 1.9.21
fix lint failures

fixes #702
based on work in #703
wakingrufus committed Jan 8, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent a826dcd commit 03d6148
Showing 23 changed files with 305 additions and 68 deletions.
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@ indent_size = 4
ij_kotlin_packages_to_use_import_on_demand = unset
ij_kotlin_name_count_to_use_star_import = 999
ij_kotlin_name_count_to_use_star_import_for_members = 999
ktlint_code_style=intellij_idea

[*.{yml,yaml}]
indent_size = 2
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/).

## [Unreleased]

- fix detection of android kotlin source directories in AGP >= 7 [#733](https://github.com/JLLeitschuh/ktlint-gradle/pull/733)

## [12.0.3] - 2023-12-11

- fix: apply configuration for source sets and targets that are added after the plugin is
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -70,6 +70,8 @@ Minimal supported [Kotlin](https://kotlinlang.org) version: `1.4`

Minimal supported [ktlint](https://github.com/pinterest/ktlint) version: `0.47.1`

Minimal supported [Android Gradle plugin](https://developer.android.com/build) version: `4.1.0`

### Ktlint plugin

#### Simple setup
18 changes: 18 additions & 0 deletions plugin/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
root = true

[*]
charset = utf-8
insert_final_newline = true
trim_trailing_whitespace = true

[*.{kt,kts}]
indent_size = 4
ij_kotlin_packages_to_use_import_on_demand = unset
ij_kotlin_name_count_to_use_star_import = 999
ij_kotlin_name_count_to_use_star_import_for_members = 999
ij_kotlin_allow_trailing_comma = false
ij_kotlin_allow_trailing_comma_on_call_site = false
ktlint_code_style=intellij_idea

[*.{yml,yaml}]
indent_size = 2
2 changes: 1 addition & 1 deletion plugin/VERSION_LATEST_RELEASE.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
11.6.1
12.0.3
29 changes: 17 additions & 12 deletions plugin/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -30,6 +30,10 @@ java {
}
}

ktlint {
version = "1.1.0"
}

tasks.withType<KotlinCompile> {
kotlinOptions {
// target 1.4 as ktlint 0.49 requires it for inline classes
@@ -56,6 +60,7 @@ configurations {
}
configurations["compileOnly"].extendsFrom(shadowImplementation)
configurations["testImplementation"].extendsFrom(shadowImplementation)

sourceSets {
val adapter by creating {
}
@@ -88,13 +93,15 @@ sourceSets {
runtimeClasspath = adapters.map { it.output }.fold(runtimeClasspath) { a, b -> a + b }
}
}

val test by getting {
kotlin {
compileClasspath = adapters.map { it.output }.fold(compileClasspath) { a, b -> a + b }
runtimeClasspath = adapters.map { it.output }.fold(runtimeClasspath) { a, b -> a + b }
}
}
}

val adapterSources = listOf(
sourceSets.named("adapter"),
sourceSets.named("adapter47"),
@@ -140,12 +147,6 @@ dependencies {
// Explicitly added for shadow plugin to relocate implementation as well
shadowImplementation(libs.slf4j.nop)

/*
* Do not depend upon the gradle script kotlin plugin API. IE: gradleScriptKotlinApi()
* It's currently in flux and has binary breaking changes in gradle 4.0
* https://github.com/JLLeitschuh/ktlint-gradle/issues/9
*/

testImplementation(libs.junit.jupiter)
testImplementation(libs.assertj.core)
testImplementation(libs.kotlin.reflect)
@@ -165,12 +166,8 @@ kotlin {
}
}

// Test tasks loods plugin from local maven repository
tasks.named<Test>("test") {
dependsOn("publishToMavenLocal")
}

tasks.withType<Test> {
dependsOn("publishToMavenLocal")
useJUnitPlatform()
maxParallelForks = (Runtime.getRuntime().availableProcessors() / 2).takeIf { it > 0 } ?: 1
doFirst {
@@ -195,6 +192,12 @@ tasks.withType<Test> {
maxFailures.set(10)
}
}

javaLauncher.set(
javaToolchains.launcherFor {
languageVersion = JavaLanguageVersion.of(JavaVersion.current().majorVersion)
}
)
}

val relocateShadowJar = tasks.register<ConfigureShadowRelocation>("relocateShadowJar")
@@ -273,7 +276,9 @@ fun setupPublishingEnvironment() {

if (System.getProperty(keyProperty) == null || System.getProperty(secretProperty) == null) {
logger
.info("`$keyProperty` or `$secretProperty` were not set. Attempting to configure from environment variables")
.info(
"`$keyProperty` or `$secretProperty` were not set. Attempting to configure from environment variables"
)

val key: String? = System.getenv(keyEnvironmentVariable)
val secret: String? = System.getenv(secretEnvironmentVariable)
Original file line number Diff line number Diff line change
@@ -12,7 +12,8 @@ interface ReportersLoaderAdapter<
R,
RP : Serializable,
GR : GenericReporter<R>,
GRP : GenericReporterProvider<GR>> {
GRP : GenericReporterProvider<GR>
> {
fun loadAllReporterProviders(): List<ReporterProviderWrapper<RP>>
fun filterEnabledBuiltInProviders(
enabledReporters: Set<ReporterType>,
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@file:Suppress("ConstPropertyName")

package org.jlleitschuh.gradle.ktlint

import org.eclipse.jgit.lib.RepositoryBuilder
Original file line number Diff line number Diff line change
@@ -29,7 +29,7 @@ open class KtlintPlugin : Plugin<Project> {
private fun PluginHolder.addKtLintTasksToKotlinPlugin() {
target.plugins.withId("kotlin", applyKtLint())
target.plugins.withId("org.jetbrains.kotlin.js", applyKtLint())
target.plugins.withId("kotlin-android", applyKtLintToAndroid())
target.plugins.withId("org.jetbrains.kotlin.android", applyKtLintToAndroid())
target.plugins.withId(
"org.jetbrains.kotlin.multiplatform",
applyKtlintMultiplatform()
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
package org.jlleitschuh.gradle.ktlint.android

import com.android.build.api.dsl.AndroidSourceDirectorySet
import com.android.build.api.dsl.AndroidSourceSet
import com.android.build.api.dsl.BuildFeatures
import com.android.build.api.dsl.BuildType
import com.android.build.api.dsl.CommonExtension
import com.android.build.api.dsl.DefaultConfig
import com.android.build.api.dsl.ProductFlavor
import com.android.build.api.dsl.SigningConfig
import com.android.build.api.variant.Variant
import com.android.build.api.variant.VariantProperties
import com.android.build.gradle.internal.api.DefaultAndroidSourceDirectorySet
import org.gradle.api.Plugin
import org.gradle.api.file.FileCollection
@@ -21,6 +15,7 @@ import org.jlleitschuh.gradle.ktlint.createGenerateReportsTask
import org.jlleitschuh.gradle.ktlint.setCheckTaskDependsOnGenerateReportsTask
import org.jlleitschuh.gradle.ktlint.tasks.GenerateReportsTask
import java.util.concurrent.Callable
import kotlin.reflect.full.memberProperties

internal fun KtlintPlugin.PluginHolder.applyKtLintToAndroid(): (Plugin<in Any>) -> Unit {
return {
@@ -43,33 +38,32 @@ internal fun KtlintPlugin.PluginHolder.applyKtLintToAndroid(): (Plugin<in Any>)
}
}

@Suppress("UnstableApiUsage")
private typealias AndroidCommonExtension = CommonExtension<
AndroidSourceSet,
BuildFeatures,
BuildType,
DefaultConfig,
ProductFlavor,
SigningConfig,
Variant<VariantProperties>,
VariantProperties
>

/*
* Variant manager returns all sources for variant,
* so most probably main source set maybe checked several times.
* This approach creates one check tasks per one source set.
*/
@Suppress("UNCHECKED_CAST", "UnstableApiUsage")
@Suppress("UnstableApiUsage")
private fun androidPluginConfigureAction(
pluginHolder: KtlintPlugin.PluginHolder
): (Plugin<Any>) -> Unit = {
pluginHolder.target.extensions.configure(CommonExtension::class.java) {
val androidCommonExtension = this as AndroidCommonExtension

androidCommonExtension.sourceSets.all {
// https://issuetracker.google.com/u/1/issues/170650362
val androidSourceSet = java as DefaultAndroidSourceDirectorySet
// kotlin property exists in AGP >= 7
val kotlinProperty = AndroidSourceSet::class.memberProperties.firstOrNull { it.name == "kotlin" }
if (kotlinProperty == null) {
pluginHolder.target.logger.warn(
buildString {
append("In AGP <7 kotlin source directories are not auto-detected. ")
append("In order to lint kotlin sources, manually add the directory to the source set. ")
append("""For example: sourceSets.getByName("main").java.srcDirs("src/main/kotlin/")""")
}
)
}
val sourceMember: AndroidSourceSet.() -> AndroidSourceDirectorySet = {
kotlinProperty?.get(this) as AndroidSourceDirectorySet? ?: this.java
}
sourceSets.all {
val androidSourceSet = sourceMember(this) as DefaultAndroidSourceDirectorySet
// Passing Callable, so returned FileCollection, will lazy evaluate it
// only when task will need it.
// Solves the problem of having additional source dirs in
Original file line number Diff line number Diff line change
@@ -190,7 +190,8 @@ abstract class GenerateReportsTask @Inject constructor(
internal enum class LintType(
val suffix: String
) {
CHECK("Check"), FORMAT("Format")
CHECK("Check"),
FORMAT("Format")
}

internal companion object {
9 changes: 9 additions & 0 deletions plugin/src/test/kotlin/org/assertj/core/api/Assertions.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.assertj.core.api

import org.gradle.testkit.runner.BuildTask
import org.gradle.testkit.runner.TaskOutcome

fun ObjectAssert<BuildTask?>.hasOutcome(outcome: TaskOutcome) {
this.objects.assertNotNull(this.info, this.actual)
this.objects.assertEqual(this.info, this.actual!!.outcome, outcome)
}
Original file line number Diff line number Diff line change
@@ -28,8 +28,7 @@ abstract class AbstractPluginTest {
GenerateReportsTask.LintType.CHECK
)

protected
fun File.withCleanSources() = createSourceFile(
protected fun File.withCleanSources() = createSourceFile(
"src/main/kotlin/CleanSource.kt",
"""
val foo = "bar"
@@ -53,12 +52,10 @@ abstract class AbstractPluginTest {
""".trimIndent()
)

protected
fun File.withAlternativeFailingSources(baseDir: String) =
protected fun File.withAlternativeFailingSources(baseDir: String) =
createSourceFile("$baseDir/FailSource.kt", """val foo = "bar"""")

protected
fun File.createSourceFile(sourceFilePath: String, contents: String) {
protected fun File.createSourceFile(sourceFilePath: String, contents: String) {
val sourceFile = resolve(sourceFilePath)
sourceFile.parentFile.mkdirs()
sourceFile.writeText(contents)
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ import com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses
@AnalyzeClasses(
packages = ["org.jlleitschuh.gradle.ktlint.."]
)
@Suppress("PropertyName")
internal class KtLintClassesUsageScopeTest {
@ArchTest
val `Non-worker plugin classes should not use ktlint classes` = noClasses()
Original file line number Diff line number Diff line change
@@ -181,7 +181,8 @@ class KtLintSupportedVersionsTest : AbstractPluginTest() {
"0.49.1",
"0.50.0",
"1.0.0",
"1.0.1"
"1.0.1",
"1.1.0"
)

override fun provideArguments(
Original file line number Diff line number Diff line change
@@ -677,7 +677,8 @@ class KtlintPluginTest : AbstractPluginTest() {

removeSourceFile(fileOne)
val fileThree = "src/main/kotlin/FileThree.kt"
createSourceFile( // Need to add or modify a source to repro file not found error.
// Need to add or modify a source to repro file not found error.
createSourceFile(
fileThree,
"""
val bar = "foo"
Original file line number Diff line number Diff line change
@@ -3,7 +3,9 @@ package org.jlleitschuh.gradle.ktlint
import org.assertj.core.api.Assertions.assertThat
import org.gradle.util.GradleVersion
import org.jlleitschuh.gradle.ktlint.testdsl.buildAndFail
import org.jlleitschuh.gradle.ktlint.testdsl.getMajorJavaVersion
import org.jlleitschuh.gradle.ktlint.testdsl.project
import org.junit.jupiter.api.Assumptions
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.condition.DisabledOnOs
@@ -14,7 +16,15 @@ class UnsupportedGradleTest : AbstractPluginTest() {
@Test
@DisabledOnOs(OS.WINDOWS)
internal fun errorOnOldGradleVersion() {
project(GradleVersion.version("6.9.2")) {
/**
* This test ensures the proper error message is printed when an unsupported version of gradle is used.
* However, our minimum version of gradle is still 7.x, which will not run at all on Java 21.
* Gradle 8.5 is needed for Java 21.
* So if java 21 is currently being used, skip this test
*/
Assumptions.assumeFalse(getMajorJavaVersion() >= 21)

project(GradleVersion.version("7.4.1")) {
buildAndFail(CHECK_PARENT_TASK_NAME) {
assertThat(output).contains(
"Current version of plugin supports minimal Gradle version: " +
Loading

0 comments on commit 03d6148

Please sign in to comment.