diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCompilerRunnerWithWorkers.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCompilerRunnerWithWorkers.kt index 05604a1e482..42178d3cd6a 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCompilerRunnerWithWorkers.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCompilerRunnerWithWorkers.kt @@ -79,13 +79,12 @@ internal class GradleCompilerRunnerWithWorkers( // In the other cases where there is nothing the user can fix in their project, we should not restore the outputs. // Otherwise, the next build(s) will likely fail in exactly the same way as this build because their inputs and outputs are // the same. - if (taskOutputsBackup != null && (e is CompilationErrorException || e is OOMErrorException)) { + taskOutputsBackup?.tryRestoringOnRecoverableException(e) { restoreAction -> parameters.metricsReporter.get().measure(GradleBuildTime.RESTORE_OUTPUT_FROM_BACKUP) { - logger.info("Restoring task outputs to pre-compilation state") - taskOutputsBackup.restoreOutputs() + logger.info(DEFAULT_BACKUP_RESTORE_MESSAGE) + restoreAction() } } - throw e } finally { taskOutputsBackup?.deleteSnapshot() diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt index 81644d615fc..6873543b5b2 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt @@ -253,12 +253,11 @@ internal open class GradleCompilerRunner( kotlinCompilerRunnable.run() } catch (e: FailedCompilationException) { // Restore outputs only for CompilationErrorException or OOMErrorException (see GradleKotlinCompilerWorkAction.execute) - if (taskOutputsBackup != null && (e is CompilationErrorException || e is OOMErrorException)) { + taskOutputsBackup?.tryRestoringOnRecoverableException(e) { restoreAction -> buildMetrics.measure(GradleBuildTime.RESTORE_OUTPUT_FROM_BACKUP) { - taskOutputsBackup.restoreOutputs() + restoreAction() } } - throw e } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/btapi/BuildToolsApiCompilationWork.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/btapi/BuildToolsApiCompilationWork.kt index 74535911d31..44726295622 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/btapi/BuildToolsApiCompilationWork.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/btapi/BuildToolsApiCompilationWork.kt @@ -27,7 +27,6 @@ import org.jetbrains.kotlin.gradle.plugin.BuildFinishedListenerService import org.jetbrains.kotlin.gradle.plugin.internal.BuildIdService import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskLoggers import org.jetbrains.kotlin.gradle.tasks.* -import org.jetbrains.kotlin.gradle.tasks.CompilationErrorException import org.jetbrains.kotlin.gradle.tasks.FailedCompilationException import org.jetbrains.kotlin.gradle.tasks.OOMErrorException import org.jetbrains.kotlin.gradle.tasks.TaskOutputsBackup @@ -171,15 +170,9 @@ internal abstract class BuildToolsApiCompilationWork @Inject constructor( } throwExceptionIfCompilationFailed(result.asExitCode, executionStrategy) } catch (e: FailedCompilationException) { - // Restore outputs only in cases where we expect that the user will make some changes to their project: - // - For a compilation error, the user will need to fix their source code - // - For an OOM error, the user will need to increase their memory settings - // In the other cases where there is nothing the user can fix in their project, we should not restore the outputs. - // Otherwise, the next build(s) will likely fail in exactly the same way as this build because their inputs and outputs are - // the same. - if (backup != null && (e is CompilationErrorException || e is OOMErrorException)) { - log.info("Restoring task outputs to pre-compilation state") - backup.restoreOutputs() + backup?.tryRestoringOnRecoverableException(e) { restoreAction -> + log.info(DEFAULT_BACKUP_RESTORE_MESSAGE) + restoreAction() } throw e } finally { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/TasksOutputsBackup.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/TasksOutputsBackup.kt index c7f59ce974e..89c34b6a068 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/TasksOutputsBackup.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/TasksOutputsBackup.kt @@ -166,3 +166,26 @@ internal class TaskOutputsBackup( private val Int.asSnapshotDirectoryName: String get() = "$this" } + +internal fun interface BackupRestoreWrapper { + fun wrap(restoreAction: () -> Unit) +} + +internal fun TaskOutputsBackup.tryRestoringOnRecoverableException( + e: FailedCompilationException, + restoreWrapper: BackupRestoreWrapper, +) { + // Restore outputs only in cases where we expect that the user will make some changes to their project: + // - For a compilation error, the user will need to fix their source code + // - For an OOM error, the user will need to increase their memory settings + // In the other cases where there is nothing the user can fix in their project, we should not restore the outputs. + // Otherwise, the next build(s) will likely fail in exactly the same way as this build because their inputs and outputs are + // the same. + if (e is CompilationErrorException || e is OOMErrorException) { + restoreWrapper.wrap { + restoreOutputs() + } + } +} + +internal const val DEFAULT_BACKUP_RESTORE_MESSAGE = "Restoring task outputs to pre-compilation state" \ No newline at end of file