[Gradle] Create kotlinOptions during task init and keep outputFile for js

This is so that existing build scripts using
withType() do not break. Also, fix the failing
test.

It was necessary to keep outputFile for the js compile task
as it was accessed from the build scripts. Instead, a new
property is introduced which uses Gradle lazy properties.
This commit is contained in:
Ivan Gavrilovic
2021-04-30 13:02:12 +01:00
committed by teamcityserver
parent 80181c1091
commit 4994cb3774
16 changed files with 56 additions and 53 deletions
@@ -6,8 +6,10 @@
package org.jetbrains.kotlin.gradle.dsl
import groovy.lang.Closure
import org.gradle.api.Action
import org.gradle.api.Task
import org.gradle.api.tasks.Internal
import org.gradle.util.ConfigureUtil
interface KotlinCompile<out T : KotlinCommonOptions> : Task {
@get:Internal
@@ -17,8 +19,11 @@ interface KotlinCompile<out T : KotlinCommonOptions> : Task {
kotlinOptions.fn()
}
fun kotlinOptions(fn: Action<in T>) {
fn.execute(kotlinOptions)
}
fun kotlinOptions(fn: Closure<*>) {
fn.delegate = kotlinOptions
fn.call()
ConfigureUtil.configure(fn, kotlinOptions)
}
}
@@ -106,7 +106,7 @@ internal class CompilationSpecificPluginPath {
// And each compilation task should have its own plugin classpath
val compileDesktop = project.tasks.getByName("compileKotlinDesktop") as KotlinCompile
val expectedConfig = project.configurations.getByName(pluginClassPathConfiguration("desktop", "main"))
assertEquals(expectedConfig, compileDesktop.pluginClasspath)
assertEquals(expectedConfig, compileDesktop.pluginClasspath.from.single())
}
@Test
@@ -216,7 +216,7 @@ internal class CompilationSpecificPluginPath {
.let {
when (it) {
is AbstractKotlinNativeCompile<*, *> -> it.compilerPluginClasspath
is AbstractKotlinCompile<*> -> it.pluginClasspath
is AbstractKotlinCompile<*> -> it.pluginClasspath.from.single()
else -> error("Unexpected task type with name $taskName. Is it kotlin compile task?")
}
}
@@ -34,7 +34,7 @@ import java.io.File
import java.util.concurrent.Callable
@CacheableTask
abstract class KaptGenerateStubsTask : KotlinCompile() {
abstract class KaptGenerateStubsTask : KotlinCompile(KotlinJvmOptionsImpl()) {
class Configurator(private val kotlinCompileTask: KotlinCompile, kotlinCompilation: KotlinCompilationData<*>) :
AbstractKotlinCompile.Configurator<KaptGenerateStubsTask>(kotlinCompilation) {
@@ -63,11 +63,9 @@ abstract class KaptGenerateStubsTask : KotlinCompile() {
}
}
)
task.kotlinOptionsProperty.value(KotlinJvmOptionsImpl()).disallowChanges()
}
}
@field:Transient
override val sourceRootsContainer = FilteringSourceRootsContainer(objects, { isSourceRootAllowed(it) })
@@ -261,7 +261,7 @@ internal class Kotlin2JsSourceSetProcessor(
project.whenEvaluated {
kotlinTask.configure { kotlinTaskInstance ->
val kotlinOptions = kotlinTaskInstance.kotlinOptions
val outputFile = kotlinTaskInstance.outputFile.get()
val outputFile = kotlinTaskInstance.outputFileProperty.get()
val outputDir: File = outputFile.parentFile
kotlinOptions.outputFile = if (!kotlinOptions.isProduceUnzippedKlib()) {
outputFile.absolutePath
@@ -78,7 +78,7 @@ class KotlinJsDcePlugin : Plugin<Project> {
dceTask.configure {
it.classpath = configuration
it.destinationDir = it.dceOptions.outputDirectory?.let { File(it) } ?: outputDir
it.source((kotlinTask.get() as Kotlin2JsCompile).outputFile.get())
it.source((kotlinTask.get() as Kotlin2JsCompile).outputFileProperty.get())
}
}
}
@@ -103,7 +103,7 @@ open class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
) { task ->
val entryFileProvider = binary.linkSyncTask.map {
it.destinationDir
.resolve(binary.linkTask.get().outputFile.get().name)
.resolve(binary.linkTask.get().outputFileProperty.get().name)
}
webpackMajorVersion.choose(
@@ -173,7 +173,7 @@ open class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
) { task ->
val entryFileProvider = binary.linkSyncTask.map {
it.destinationDir
.resolve(binary.linkTask.get().outputFile.get().name)
.resolve(binary.linkTask.get().outputFileProperty.get().name)
}
task.description = "build webpack ${mode.name.toLowerCase()} bundle"
@@ -23,7 +23,7 @@ import javax.inject.Inject
@CacheableTask
abstract class KotlinJsIrLink @Inject constructor(
objectFactory: ObjectFactory
): Kotlin2JsCompile(objectFactory) {
): Kotlin2JsCompile(KotlinJsOptionsImpl(), objectFactory) {
class Configurator(compilation: KotlinCompilationData<*>): Kotlin2JsCompile.Configurator<KotlinJsIrLink>(compilation) {
@@ -33,8 +33,7 @@ abstract class KotlinJsIrLink @Inject constructor(
task.entryModule.fileProvider(
(compilation as KotlinJsIrCompilation).output.classesDirs.elements.map { it.single().asFile }
).disallowChanges()
task.kotlinOptionsProperty.value(KotlinJsOptionsImpl()).disallowChanges()
task.destinationDirectory.fileProvider(task.outputFile.map { it.parentFile }).disallowChanges()
task.destinationDirectory.fileProvider(task.outputFileProperty.map { it.parentFile }).disallowChanges()
}
}
@@ -123,7 +123,7 @@ abstract class KotlinJsIrSubTarget(
project.layout.file(
binary.linkSyncTask.map {
it.destinationDir
.resolve(binary.linkTask.get().outputFile.get().name)
.resolve(binary.linkTask.get().outputFileProperty.get().name)
}
)
)
@@ -69,7 +69,7 @@ open class KotlinNodeJsIr @Inject constructor(target: KotlinJsIrTarget) :
project.layout.file(
binary.linkSyncTask.map {
it.destinationDir
.resolve(binary.linkTask.get().outputFile.get().name)
.resolve(binary.linkTask.get().outputFileProperty.get().name)
}
)
)
@@ -257,7 +257,7 @@ open class KotlinBrowserJs @Inject constructor(target: KotlinJsTarget) :
entryProperty.set(
project.layout.file(actualDceTaskProvider.map {
it.destinationDir.resolve(compilation.compileKotlinTask.outputFile.get().name)
it.destinationDir.resolve(compilation.compileKotlinTask.outputFileProperty.get().name)
})
)
@@ -300,7 +300,7 @@ open class KotlinBrowserJs @Inject constructor(target: KotlinJsTarget) :
?: compilation.npmProject.dir.resolve(if (dev) DCE_DEV_DIR else DCE_DIR)
it.defaultCompilerClasspath.setFrom(project.configurations.named(COMPILER_CLASSPATH_CONFIGURATION_NAME))
it.source(kotlinTask.map { it.outputFile.get() })
it.source(kotlinTask.map { it.outputFileProperty.get() })
}
}
@@ -103,7 +103,7 @@ abstract class KotlinJsSubTarget(
testJs.group = LifecycleBasePlugin.VERIFICATION_GROUP
testJs.description = testTaskDescription
val compileOutputFile = compileTask.flatMap { it.outputFile }
val compileOutputFile = compileTask.flatMap { it.outputFileProperty }
testJs.inputFileProperty.fileProvider(compileOutputFile)
testJs.dependsOn(nodeJs.npmInstallTaskProvider, compileTask, nodeJs.nodeJsSetupTaskProvider)
@@ -49,7 +49,7 @@ open class KotlinNodeJs @Inject constructor(target: KotlinJsTarget) :
) {
val runTaskHolder = NodeJsExec.create(compilation, disambiguateCamelCased(RUN_TASK_NAME)) {
group = taskGroupName
inputFileProperty.fileProvider(compilation.compileKotlinTaskProvider.flatMap { it.outputFile })
inputFileProperty.fileProvider(compilation.compileKotlinTaskProvider.flatMap { it.outputFileProperty })
}
target.runTask.dependsOn(runTaskHolder)
}
@@ -79,7 +79,7 @@ constructor(
@get:PathSensitive(PathSensitivity.ABSOLUTE)
@get:InputFile
val entryProperty: RegularFileProperty = objects.fileProperty().fileProvider(compilation.compileKotlinTask.outputFile)
val entryProperty: RegularFileProperty = objects.fileProperty().fileProvider(compilation.compileKotlinTask.outputFileProperty)
init {
onlyIf {
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.gradle.tasks
import org.gradle.api.Project
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.*
import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments
@@ -38,14 +37,16 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.refinesClosure
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
import org.jetbrains.kotlin.incremental.ChangedFiles
import java.io.File
import javax.inject.Inject
@CacheableTask
abstract class KotlinCompileCommon : AbstractKotlinCompile<K2MetadataCompilerArguments>(), KotlinCommonCompile {
abstract class KotlinCompileCommon @Inject constructor(
override val kotlinOptions: KotlinMultiplatformCommonOptions
) : AbstractKotlinCompile<K2MetadataCompilerArguments>(), KotlinCommonCompile {
class Configurator(compilation: KotlinCompilationData<*>) : AbstractKotlinCompile.Configurator<KotlinCompileCommon>(compilation) {
override fun configure(task: KotlinCompileCommon) {
super.configure(task)
task.kotlinOptionsProperty.value(compilation.kotlinOptions as KotlinMultiplatformCommonOptionsImpl).disallowChanges()
task.refinesMetadataPaths.from(getRefinesMetadataPaths(task.project)).disallowChanges()
task.expectActualLinker
.value(task.project.provider { (compilation as? KotlinCommonCompilation)?.isKlibCompilation == true || compilation is KotlinMetadataCompilationData })
@@ -76,8 +77,6 @@ abstract class KotlinCompileCommon : AbstractKotlinCompile<K2MetadataCompilerArg
}
}
override val kotlinOptionsProperty: Property<KotlinMultiplatformCommonOptions> = objects.property(KotlinMultiplatformCommonOptions::class.java)
override fun createCompilerArgs(): K2MetadataCompilerArguments =
K2MetadataCompilerArguments()
@@ -385,21 +385,16 @@ internal inline val <reified T : Task> T.thisTaskProvider: TaskProvider<out T>
get() = checkNotNull(project.locateTask<T>(name))
@CacheableTask
abstract class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), KotlinJvmCompile {
abstract class KotlinCompile @Inject constructor(
override val kotlinOptions: KotlinJvmOptions
) : AbstractKotlinCompile<K2JVMCompilerArguments>(), KotlinJvmCompile {
class Configurator(kotlinCompilation: KotlinCompilationData<*>) : AbstractKotlinCompile.Configurator<KotlinCompile>(kotlinCompilation) {
override fun configure(task: KotlinCompile) {
super.configure(task)
task.kotlinOptionsProperty.set(compilation.kotlinOptions as KotlinJvmOptions)
}
}
@get:Internal
internal val parentKotlinOptionsImpl: Property<KotlinJvmOptions> = objects.property(KotlinJvmOptions::class.java)
override val kotlinOptionsProperty: Property<KotlinJvmOptions> = objects.property(KotlinJvmOptions::class.java)
@get:Internal
@field:Transient
internal open val sourceRootsContainer = FilteringSourceRootsContainer(objects)
@@ -528,8 +523,9 @@ abstract class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(),
@CacheableTask
internal abstract class KotlinCompileWithWorkers @Inject constructor(
kotlinOptions: KotlinJvmOptions,
private val workerExecutor: WorkerExecutor
) : KotlinCompile() {
) : KotlinCompile(kotlinOptions) {
override fun compilerRunner(
javaExecutable: File,
@@ -544,9 +540,10 @@ internal abstract class KotlinCompileWithWorkers @Inject constructor(
@CacheableTask
internal abstract class Kotlin2JsCompileWithWorkers @Inject constructor(
kotlinOptions: KotlinJsOptions,
objectFactory: ObjectFactory,
private val workerExecutor: WorkerExecutor
) : Kotlin2JsCompile(objectFactory) {
) : Kotlin2JsCompile(kotlinOptions, objectFactory) {
override fun compilerRunner(
javaExecutable: File,
@@ -561,8 +558,9 @@ internal abstract class Kotlin2JsCompileWithWorkers @Inject constructor(
@CacheableTask
internal abstract class KotlinCompileCommonWithWorkers @Inject constructor(
kotlinOptions: KotlinMultiplatformCommonOptions,
private val workerExecutor: WorkerExecutor
) : KotlinCompileCommon() {
) : KotlinCompileCommon(kotlinOptions) {
override fun compilerRunner(
javaExecutable: File,
jdkToolsJar: File?
@@ -576,6 +574,7 @@ internal abstract class KotlinCompileCommonWithWorkers @Inject constructor(
@CacheableTask
abstract class Kotlin2JsCompile @Inject constructor(
override val kotlinOptions: KotlinJsOptions,
objectFactory: ObjectFactory
) : AbstractKotlinCompile<K2JSCompilerArguments>(), KotlinJsCompile {
@@ -588,24 +587,22 @@ abstract class Kotlin2JsCompile @Inject constructor(
override fun configure(task: T) {
super.configure(task)
task.kotlinOptionsProperty.set(compilation.kotlinOptions as KotlinJsOptions)
task.outputFile.value(
task.kotlinOptionsProperty.map {
it.outputFile?.let(::File)
task.outputFileProperty.value(
task.project.provider {
task.kotlinOptions.outputFile?.let(::File)
?: task.destinationDirectory.locationOnly.get().asFile.resolve("${compilation.ownModuleName}.js")
}
).disallowChanges()
task.optionalOutputFile.fileProvider(
task.kotlinOptionsProperty.flatMap { jsOptions ->
task.outputFile.takeIf { !jsOptions.isProduceUnzippedKlib() }
?: task.project.objects.fileProperty().asFile
task.outputFileProperty.flatMap { outputFile ->
task.project.provider {
outputFile.takeUnless { task.kotlinOptions.isProduceUnzippedKlib() }
}
}
).disallowChanges()
}
}
override val kotlinOptionsProperty: Property<KotlinJsOptions> = objectFactory.property(KotlinJsOptions::class.java)
@get:Input
internal var incrementalJsKlib: Boolean = true
@@ -619,7 +616,12 @@ abstract class Kotlin2JsCompile @Inject constructor(
// This can be file or directory
@get:Internal
abstract val outputFile: Property<File>
abstract val outputFileProperty: Property<File>
@Deprecated("Please use outputFileProperty, this is kept for backwards compatibility.", replaceWith = ReplaceWith("outputFileProperty"))
@get:Internal
val outputFile: File
get() = outputFileProperty.get()
@get:OutputFile
@get:Optional
@@ -636,13 +638,13 @@ abstract class Kotlin2JsCompile @Inject constructor(
super.setupCompilerArgs(args, defaultsOnly = defaultsOnly, ignoreClasspathResolutionErrors = ignoreClasspathResolutionErrors)
try {
outputFile.get().canonicalPath
outputFileProperty.get().canonicalPath
} catch (ex: Throwable) {
logger.warn("IO EXCEPTION: outputFile: ${outputFile.get().path}")
logger.warn("IO EXCEPTION: outputFile: ${outputFileProperty.get().path}")
throw ex
}
args.outputFile = outputFile.get().absoluteFile.normalize().absolutePath
args.outputFile = outputFileProperty.get().absoluteFile.normalize().absolutePath
if (defaultsOnly) return
@@ -89,7 +89,7 @@ internal open class KotlinTasksProvider {
): TaskProvider<out KotlinCompile> {
val properties = PropertiesProvider(project)
val taskClass = taskOrWorkersTask<KotlinCompile, KotlinCompileWithWorkers>(properties)
val result = project.registerTask(name, taskClass) {
val result = project.registerTask(name, taskClass, constructorArgs = listOf(compilation.kotlinOptions)) {
configureAction(it)
KotlinCompile.Configurator(compilation).configure(it)
}
@@ -105,7 +105,7 @@ internal open class KotlinTasksProvider {
): TaskProvider<out Kotlin2JsCompile> {
val properties = PropertiesProvider(project)
val taskClass = taskOrWorkersTask<Kotlin2JsCompile, Kotlin2JsCompileWithWorkers>(properties)
val result = project.registerTask(name, taskClass) {
val result = project.registerTask(name, taskClass, constructorArgs = listOf(compilation.kotlinOptions)) {
configureAction(it)
Kotlin2JsCompile.Configurator<Kotlin2JsCompile>(compilation).configure(it)
}
@@ -137,7 +137,7 @@ internal open class KotlinTasksProvider {
): TaskProvider<out KotlinCompileCommon> {
val properties = PropertiesProvider(project)
val taskClass = taskOrWorkersTask<KotlinCompileCommon, KotlinCompileCommonWithWorkers>(properties)
val result = project.registerTask(name, taskClass) {
val result = project.registerTask(name, taskClass, constructorArgs = listOf(compilation.kotlinOptions)) {
configureAction(it)
KotlinCompileCommon.Configurator(compilation).configure(it)
}