Fix Kapt generate stubs doesn't know about java sources from main task

Restore configuration to set to KaptGenerateStubsTask java sources
set to related KotlinCompile task.

^KT-52761 Fixed
This commit is contained in:
Yahor Berdnikau
2022-07-27 13:59:43 +02:00
committed by Space
parent bcd6a54ffb
commit 21b8e1a0c8
8 changed files with 121 additions and 18 deletions
@@ -936,7 +936,6 @@ open class Kapt3IT : Kapt3BaseIT() {
}
@DisplayName("KT-46651: kapt is tracking source files properly with configuration cache enabled")
@GradleTestVersions(minVersion = TestVersions.Gradle.G_6_7)
@GradleTest
fun kaptGenerateStubsShouldNotCaptureSourcesStateInConfigurationCache(gradleVersion: GradleVersion) {
project(
@@ -1007,4 +1006,12 @@ open class Kapt3IT : Kapt3BaseIT() {
}
}
}
@DisplayName("KT-52761: generated sources attached to compile task are also used by generate stubs task")
@GradleTest
fun testGeneratedSourcesUsedInGenerateStubsTask(gradleVersion: GradleVersion) {
project("generatedSources".withPrefix, gradleVersion) {
build("assemble")
}
}
}
@@ -0,0 +1,23 @@
plugins {
id "org.jetbrains.kotlin.jvm"
id "org.jetbrains.kotlin.kapt"
}
repositories {
mavenLocal()
mavenCentral()
}
tasks.named("compileKotlin", org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile.class) {
source("src/proto/generated")
}
tasks.withType(JavaCompile.class).configureEach {
source("src/proto/generated")
}
dependencies {
// Mapstruct
implementation("org.mapstruct:mapstruct:1.5.1.Final")
kapt("org.mapstruct:mapstruct-processor:1.5.1.Final")
}
@@ -0,0 +1,4 @@
data class UserInfo2(
val name: String,
val email: String
)
@@ -0,0 +1,7 @@
import User.UserInfo
import org.mapstruct.Mapper
@Mapper
interface UserMapper {
fun mapUserInfo(source: UserInfo): UserInfo2
}
@@ -0,0 +1,31 @@
public final class User {
private User() {}
public static final class UserInfo {
private UserInfo() {
name_ = "";
email_ = "";
}
private volatile String name_;
public String getName() {
return name_;
}
public void setName(String name) {
name_ = name;
}
private volatile String email_;
public String getEmail() {
return email_;
}
public void setEmail(String email) {
email_ = email;
}
}
}
@@ -67,10 +67,6 @@ abstract class KaptGenerateStubsTask @Inject constructor(
@get:Incremental
abstract val additionalSources: ConfigurableFileCollection
private fun File.isSourceRootAllowed(): Boolean =
!destinationDirectory.get().asFile.isParentOf(this) &&
!stubsDir.asFile.get().isParentOf(this)
override fun skipCondition(): Boolean = sources.isEmpty && javaSources.isEmpty
// Task need to run even if there is no Kotlin sources, but only Java
@@ -79,10 +75,6 @@ abstract class KaptGenerateStubsTask @Inject constructor(
@get:IgnoreEmptyDirectories
@get:PathSensitive(PathSensitivity.RELATIVE)
override val sources: FileCollection = super.sources
.asFileTree
.matching { patternFilterable ->
patternFilterable.include { it.isDirectory || it.file.isSourceRootAllowed() }
}
@get:Internal
override val scriptSources: FileCollection = objectFactory.fileCollection()
@@ -99,12 +91,6 @@ abstract class KaptGenerateStubsTask @Inject constructor(
classpathSnapshotProperties.classpathSnapshot
)
override val javaSources: FileCollection = super.javaSources
.asFileTree
.matching { patternFilterable ->
patternFilterable.include { it.isDirectory || it.file.isSourceRootAllowed() }
}
@get:Internal
internal abstract val compileKotlinArgumentsContributor: Property<CompilerArgumentsContributor<K2JVMCompilerArguments>>
@@ -6,13 +6,14 @@
package org.jetbrains.kotlin.gradle.tasks.configuration
import org.gradle.api.Project
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.Provider
import org.gradle.api.specs.Spec
import org.gradle.api.tasks.TaskProvider
import org.jetbrains.kotlin.gradle.dsl.KotlinTopLevelExtension
import org.jetbrains.kotlin.gradle.internal.*
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.KAPT_SUBPLUGIN_ID
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.isIncludeCompileClasspath
import org.jetbrains.kotlin.gradle.internal.KaptGenerateStubsTask
import org.jetbrains.kotlin.gradle.internal.KaptTask
import org.jetbrains.kotlin.gradle.internal.KotlinJvmCompilerArgumentsContributor
import org.jetbrains.kotlin.gradle.internal.buildKaptSubpluginOptions
import org.jetbrains.kotlin.gradle.plugin.KaptExtension
@@ -20,7 +21,9 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompilerArgumentsProvider
import java.util.concurrent.Callable
import org.jetbrains.kotlin.gradle.utils.isParentOf
import java.io.File
import java.nio.file.Files
internal class KaptGenerateStubsConfig : BaseKotlinCompileConfig<KaptGenerateStubsTask> {
@@ -33,6 +36,26 @@ internal class KaptGenerateStubsConfig : BaseKotlinCompileConfig<KaptGenerateStu
task.libraries.from({ kotlinCompileTask.libraries })
task.compileKotlinArgumentsContributor.set(providers.provider { kotlinCompileTask.compilerArgumentsContributor })
task.pluginOptions.addAll(kotlinCompileTask.pluginOptions)
// KotlinCompile will also have as input output from KaptGenerateStubTask and KaptTask
// We are filtering them to avoid failed UP-TO-DATE checks
val kaptJavaSourcesDir = Kapt3GradleSubplugin.getKaptGeneratedSourcesDir(
project,
compilation.compilationPurpose
)
val kaptKotlinSourcesDir = Kapt3GradleSubplugin.getKaptGeneratedKotlinSourcesDir(
project,
compilation.compilationPurpose
)
val destinationDirectory = task.destinationDirectory
val stubsDir = task.stubsDir
task.source(
kotlinCompileTask
.javaSources
.filter(KaptFilterSpec(destinationDirectory, stubsDir, kaptJavaSourcesDir)),
kotlinCompileTask
.sources
.filter(KaptFilterSpec(destinationDirectory, stubsDir, kaptKotlinSourcesDir))
)
}
}
@@ -82,4 +105,25 @@ internal class KaptGenerateStubsConfig : BaseKotlinCompileConfig<KaptGenerateStu
return@provider compilerPluginOptions
}
}
// Drop `isEmptyDirectory` check after min supported Gradle version will be bumped to 6.8
// It will be covered by '@IgnoreEmptyDirectories' input annotation
private class KaptFilterSpec(
private val destinationDirectory: DirectoryProperty,
private val stubsDir: DirectoryProperty,
private val additionalParentToCheck: File
) : Spec<File> {
override fun isSatisfiedBy(element: File): Boolean {
return !element.isEmptyDirectory &&
element.isSourceRootAllowed()
}
private val File.isEmptyDirectory: Boolean
get() = with(toPath()) { Files.isDirectory(this) && !Files.list(this).use { it.findFirst().isPresent } }
private fun File.isSourceRootAllowed(): Boolean =
!destinationDirectory.get().asFile.isParentOf(this) &&
!stubsDir.asFile.get().isParentOf(this) &&
!additionalParentToCheck.isParentOf(this)
}
}