KTIJ-25563: Add upToDateWhen condition to CInterop task outputs
This commit is contained in:
committed by
Space Team
parent
503c1a2eb6
commit
b672ba8eaf
+4
-19
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.gradle.native
|
||||
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.testbase.*
|
||||
import org.jetbrains.kotlin.konan.file.File
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import kotlin.io.path.writeText
|
||||
|
||||
@@ -35,24 +34,10 @@ class CInteropIdeaSyncIT : KGPBaseTest() {
|
||||
assertOutputContains(ideaSyncWarningMessage)
|
||||
}
|
||||
|
||||
/*
|
||||
The implementation before fixing KT-52243 considered the cinterop task as *not* up-to-date
|
||||
when it was previously running in the IDE and therefore failing leniently. It would have always tried to re-run
|
||||
this task to anticipate untracked environmental changes.
|
||||
|
||||
This cannot be easily implemented whilst also fixing KT-52243, which is more desirable.
|
||||
A new mechanism for 'run tasks at import' leniency is proposed (using --continue), which is supposed to replace
|
||||
the special cinterop mechanism.
|
||||
|
||||
https://youtrack.jetbrains.com/issue/KT-52243/
|
||||
https://github.com/JetBrains/kotlin/pull/4812#issuecomment-1117287222
|
||||
*/
|
||||
runCatching {
|
||||
/* Task is not considered up-to-date after lenient failure */
|
||||
build("commonize", buildOptions = ideaSyncBuildOptions) {
|
||||
assertTasksExecuted(interopTaskName)
|
||||
assertOutputContains(ideaSyncWarningMessage)
|
||||
}
|
||||
/* Task is not considered up-to-date after lenient failure */
|
||||
build("commonize", buildOptions = ideaSyncBuildOptions) {
|
||||
assertTasksExecuted(interopTaskName)
|
||||
assertOutputContains(ideaSyncWarningMessage)
|
||||
}
|
||||
|
||||
/* Remove noise that causes failure */
|
||||
|
||||
+15
-8
@@ -5,48 +5,55 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.targets.native.tasks
|
||||
|
||||
import org.gradle.api.Task
|
||||
import org.jetbrains.kotlin.build.report.metrics.BuildMetrics
|
||||
import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporter
|
||||
import org.jetbrains.kotlin.build.report.metrics.GradleBuildPerformanceMetric
|
||||
import org.jetbrains.kotlin.build.report.metrics.GradleBuildTime
|
||||
import org.jetbrains.kotlin.compilerRunner.KotlinNativeCInteropRunner
|
||||
import org.jetbrains.kotlin.compilerRunner.KotlinNativeToolRunner
|
||||
import org.jetbrains.kotlin.compilerRunner.KotlinToolRunner
|
||||
import org.jetbrains.kotlin.gradle.report.GradleBuildMetricsReporter
|
||||
import org.jetbrains.kotlin.gradle.tasks.CInteropProcess
|
||||
import org.jetbrains.kotlin.gradle.utils.listFilesOrEmpty
|
||||
|
||||
internal fun KotlinNativeCInteropRunner.Companion.createExecutionContext(
|
||||
task: Task,
|
||||
task: CInteropProcess,
|
||||
isInIdeaSync: Boolean,
|
||||
runnerSettings: KotlinNativeToolRunner.Settings,
|
||||
gradleExecutionContext: KotlinToolRunner.GradleExecutionContext,
|
||||
metricsReporter: BuildMetricsReporter<GradleBuildTime, GradleBuildPerformanceMetric>
|
||||
): KotlinNativeCInteropRunner.ExecutionContext {
|
||||
return if (isInIdeaSync) IdeaSyncKotlinNativeCInteropRunnerExecutionContext(runnerSettings, gradleExecutionContext, task, metricsReporter)
|
||||
else DefaultKotlinNativeCInteropRunnerExecutionContext(runnerSettings, gradleExecutionContext, metricsReporter)
|
||||
else DefaultKotlinNativeCInteropRunnerExecutionContext(runnerSettings, gradleExecutionContext, task, metricsReporter)
|
||||
}
|
||||
|
||||
private class DefaultKotlinNativeCInteropRunnerExecutionContext(
|
||||
override val runnerSettings: KotlinNativeToolRunner.Settings,
|
||||
override val gradleExecutionContext: KotlinToolRunner.GradleExecutionContext,
|
||||
private val task: CInteropProcess,
|
||||
override val metricsReporter: BuildMetricsReporter<GradleBuildTime, GradleBuildPerformanceMetric>
|
||||
) : KotlinNativeCInteropRunner.ExecutionContext {
|
||||
override fun runWithContext(action: () -> Unit) = action()
|
||||
override fun runWithContext(action: () -> Unit) {
|
||||
task.errorFileProvider.get().delete()
|
||||
action()
|
||||
}
|
||||
}
|
||||
|
||||
private class IdeaSyncKotlinNativeCInteropRunnerExecutionContext(
|
||||
override val runnerSettings: KotlinNativeToolRunner.Settings,
|
||||
override val gradleExecutionContext: KotlinToolRunner.GradleExecutionContext,
|
||||
private val task: Task,
|
||||
private val task: CInteropProcess,
|
||||
override val metricsReporter: BuildMetricsReporter<GradleBuildTime, GradleBuildPerformanceMetric>
|
||||
) : KotlinNativeCInteropRunner.ExecutionContext {
|
||||
|
||||
override fun runWithContext(action: () -> Unit) {
|
||||
val errorFile = task.errorFileProvider.get()
|
||||
errorFile.delete()
|
||||
try {
|
||||
action()
|
||||
} catch (t: Throwable) {
|
||||
task.logger.warn("Warning: Failed to generate cinterop for ${task.path}: ${t.message ?: ""}", t)
|
||||
val errorText = "Warning: Failed to generate cinterop for ${task.path}: ${t.message ?: ""}"
|
||||
task.logger.warn(errorText, t)
|
||||
task.outputs.files.forEach { file -> file.deleteRecursively() }
|
||||
errorFile.writeText(errorText)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
@@ -45,6 +45,7 @@ import org.jetbrains.kotlin.gradle.targets.native.tasks.*
|
||||
import org.jetbrains.kotlin.gradle.utils.*
|
||||
import org.jetbrains.kotlin.gradle.utils.GradleLoggerAdapter
|
||||
import org.jetbrains.kotlin.gradle.utils.listFilesOrEmpty
|
||||
import org.jetbrains.kotlin.incremental.deleteDirectoryContents
|
||||
import org.jetbrains.kotlin.ir.linkage.partial.PartialLinkageMode
|
||||
import org.jetbrains.kotlin.konan.library.KLIB_INTEROP_IR_PROVIDER_IDENTIFIER
|
||||
import org.jetbrains.kotlin.konan.properties.saveToFile
|
||||
@@ -1086,6 +1087,19 @@ abstract class CInteropProcess @Inject internal constructor(params: Params) :
|
||||
@OutputFile
|
||||
val outputFileProvider: Provider<File> = project.provider { destinationDir.get().resolve(outputFileName) }
|
||||
|
||||
//Error file will be written only for errors during a project sync because for the sync task mustn't fail
|
||||
//see: org.jetbrains.kotlin.gradle.targets.native.tasks.IdeaSyncKotlinNativeCInteropRunnerExecutionContext
|
||||
@get:OutputFile
|
||||
internal val errorFileProvider: Provider<File> = project.provider { destinationDir.get().resolve("cinterop_error.out") }
|
||||
|
||||
init {
|
||||
//KTIJ-25563:
|
||||
//Failed CInterop task is successful if it was run during import to have properly imported project.
|
||||
//But successful task is up-to-date for next invocations.
|
||||
//We have to check up-to-date-ness only if CInterop didn't generate an error file
|
||||
outputs.upToDateWhen { !errorFileProvider.get().exists() }
|
||||
}
|
||||
|
||||
@get:InputFile
|
||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||
@get:NormalizeLineEndings
|
||||
|
||||
Reference in New Issue
Block a user