Always clear local state directories for non-incremental build

This commit is contained in:
Alexey Tsvetkov
2018-11-02 02:08:43 +03:00
parent 21289722b7
commit 4678a00324
9 changed files with 53 additions and 46 deletions
@@ -14,6 +14,7 @@ internal class GradleCompilerEnvironment(
val compilerClasspath: List<File>,
messageCollector: GradleMessageCollector,
outputItemsCollector: OutputItemsCollector,
val localStateDirectories: List<File>,
val incrementalCompilationEnvironment: IncrementalCompilationEnvironment? = null
) : CompilerEnvironment(Services.EMPTY, messageCollector, outputItemsCollector) {
val toolsJar: File? by lazy { findToolsJar() }
@@ -134,7 +134,8 @@ internal open class GradleCompilerRunner(protected val project: Project) {
isVerbose = compilerArgs.verbose,
incrementalCompilationEnvironment = incrementalCompilationEnvironment,
incrementalModuleInfo = modulesInfo,
buildFile = buildFile
buildFile = buildFile,
localStateDirectories = environment.localStateDirectories
)
runCompilerAsync(workArgs)
}
@@ -14,8 +14,8 @@ import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.daemon.common.*
import org.jetbrains.kotlin.gradle.plugin.kotlinDebug
import org.jetbrains.kotlin.gradle.plugin.kotlinInfo
import org.jetbrains.kotlin.gradle.tasks.GradleMessageCollector
import org.jetbrains.kotlin.gradle.tasks.clearLocalStateDirectories
import org.jetbrains.kotlin.gradle.tasks.throwGradleExceptionIfError
import org.jetbrains.kotlin.incremental.ChangedFiles
import org.jetbrains.kotlin.incremental.DELETE_MODULE_FILE_PROPERTY
@@ -52,7 +52,8 @@ internal class GradleKotlinCompilerWorkArguments(
val isVerbose: Boolean,
val incrementalCompilationEnvironment: IncrementalCompilationEnvironment?,
val incrementalModuleInfo: IncrementalModuleInfo?,
val buildFile: File?
val buildFile: File?,
val localStateDirectories: List<File>
) : Serializable {
companion object {
const val serialVersionUID: Long = 0
@@ -79,6 +80,7 @@ internal class GradleKotlinCompilerWork @Inject constructor(
private val incrementalCompilationEnvironment = config.incrementalCompilationEnvironment
private val incrementalModuleInfo = config.incrementalModuleInfo
private val buildFile = config.buildFile
private val localStateDirectories = config.localStateDirectories
private val log: KotlinLogger =
SL4JKotlinLogger(LoggerFactory.getLogger("GradleKotlinCompilerWork"))
@@ -88,8 +90,15 @@ internal class GradleKotlinCompilerWork @Inject constructor(
get() = incrementalCompilationEnvironment != null
override fun run() {
if (!isIncremental) {
clearLocalStateDirectories(log, localStateDirectories, "IC is disabled")
}
val exitCode = try {
compileWithDaemonOrFallbackImpl()
} catch (e: Throwable) {
clearLocalStateDirectories(log, localStateDirectories, "exception when running compiler")
throw e
} finally {
if (buildFile != null && System.getProperty(DELETE_MODULE_FILE_PROPERTY) != "false") {
buildFile.delete()
@@ -102,28 +111,13 @@ internal class GradleKotlinCompilerWork @Inject constructor(
}
if (exitCode != ExitCode.OK) {
// for non-incremental compilation cleanup is always performed before compiler is called
cleanupOnError(incrementalCompilationEnvironment)
clearLocalStateDirectories(log, localStateDirectories, "exit code: $exitCode")
}
}
throwGradleExceptionIfError(exitCode)
}
private fun cleanupOnError(incrementalCompilationEnvironment: IncrementalCompilationEnvironment) {
val localStateDirs = incrementalCompilationEnvironment.localStateDirs
log.info("Deleting output directories on error: ${localStateDirs.joinToString()}")
for (dir in localStateDirs) {
if (dir.exists()) {
if (dir.deleteRecursively()) {
log.debug("Deleted $dir")
} else {
log.debug("Could not delete $dir")
}
}
}
}
private fun compileWithDaemonOrFallbackImpl(): ExitCode {
with(log) {
kotlinDebug { "Kotlin compiler class: ${compilerClassName}" }
@@ -240,7 +234,7 @@ internal class GradleKotlinCompilerWork @Inject constructor(
compilerMode = CompilerMode.INCREMENTAL_COMPILER,
targetPlatform = targetPlatform,
usePreciseJavaTracking = icEnv.usePreciseJavaTracking,
localStateDirs = icEnv.localStateDirs,
localStateDirs = localStateDirectories,
multiModuleICSettings = icEnv.multiModuleICSettings,
modulesInfo = incrementalModuleInfo!!
)
@@ -14,7 +14,6 @@ internal class IncrementalCompilationEnvironment(
val changedFiles: ChangedFiles,
val workingDir: File,
val usePreciseJavaTracking: Boolean = false,
val localStateDirs: List<File> = emptyList(),
val disableMultiModuleIC: Boolean = false,
val multiModuleICSettings: MultiModuleICSettings
) : Serializable {
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl
import org.jetbrains.kotlin.gradle.plugin.PLUGIN_CLASSPATH_CONFIGURATION_NAME
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
import org.jetbrains.kotlin.gradle.tasks.GradleMessageCollector
import org.jetbrains.kotlin.gradle.tasks.clearOutputDirectories
import org.jetbrains.kotlin.gradle.tasks.localStateDirectories
import org.jetbrains.kotlin.gradle.utils.toSortedPathsArray
open class KaptWithKotlincTask : KaptTask(), CompilerArgumentAwareWithInput<K2JVMCompilerArguments> {
@@ -55,15 +55,14 @@ open class KaptWithKotlincTask : KaptTask(), CompilerArgumentAwareWithInput<K2JV
fun compile() {
logger.debug("Running kapt annotation processing using the Kotlin compiler")
/** Delete everything inside generated sources and classes output directory
* (annotation processing is not incremental) */
clearOutputDirectories()
val args = prepareCompilerArguments()
val messageCollector = GradleMessageCollector(GradleKotlinLogger(logger))
val outputItemCollector = OutputItemsCollectorImpl()
val environment = GradleCompilerEnvironment(compilerClasspath, messageCollector, outputItemCollector)
val environment = GradleCompilerEnvironment(
compilerClasspath, messageCollector, outputItemCollector,
localStateDirectories = localStateDirectories()
)
if (environment.toolsJar == null && !isAtLeastJava9) {
throw GradleException("Could not find tools.jar in system classpath, which is required for kapt to work")
}
@@ -13,7 +13,7 @@ import org.gradle.workers.IsolationMode
import org.gradle.workers.WorkerExecutor
import org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin.Companion.KAPT_WORKER_DEPENDENCIES_CONFIGURATION_NAME
import org.jetbrains.kotlin.gradle.plugin.KotlinAndroidPluginWrapper
import org.jetbrains.kotlin.gradle.tasks.clearOutputDirectories
import org.jetbrains.kotlin.gradle.tasks.clearLocalStateDirectories
import org.jetbrains.kotlin.gradle.tasks.findKotlinStdlibClasspath
import org.jetbrains.kotlin.gradle.tasks.findToolsJar
import org.jetbrains.kotlin.utils.PathUtil
@@ -48,7 +48,7 @@ open class KaptWithoutKotlincTask @Inject constructor(private val workerExecutor
fun compile() {
logger.info("Running kapt annotation processing using the Gradle Worker API")
clearOutputDirectories()
clearLocalStateDirectories()
val compileClasspath = classpath.files.toMutableList()
if (project.plugins.none { it is KotlinAndroidPluginWrapper }) {
@@ -67,7 +67,10 @@ internal open class KotlinCompileCommon : AbstractKotlinCompile<K2MetadataCompil
val messageCollector = GradleMessageCollector(logger)
val outputItemCollector = OutputItemsCollectorImpl()
val compilerRunner = compilerRunner()
val environment = GradleCompilerEnvironment(computedCompilerClasspath, messageCollector, outputItemCollector)
val environment = GradleCompilerEnvironment(
computedCompilerClasspath, messageCollector, outputItemCollector,
localStateDirectories = localStateDirectories()
)
compilerRunner.runMetadataCompilerAsync(sourceRoots.kotlinSourceFiles, args, environment)
}
}
@@ -397,16 +397,16 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
if (hasFilesInTaskBuildDirectory()) changedFiles else ChangedFiles.Unknown(),
taskBuildDirectory,
usePreciseJavaTracking = usePreciseJavaTracking,
localStateDirs = outputDirectories,
disableMultiModuleIC = disableMultiModuleIC(),
multiModuleICSettings = multiModuleICSettings
)
} else {
clearOutputDirectories(reason = "IC is disabled for the task")
null
}
} else null
val environment = GradleCompilerEnvironment(computedCompilerClasspath, messageCollector, outputItemCollector, icEnv)
val environment = GradleCompilerEnvironment(
computedCompilerClasspath, messageCollector, outputItemCollector,
localStateDirectories = localStateDirectories(),
incrementalCompilationEnvironment = icEnv
)
compilerRunner.runJvmCompilerAsync(
sourceRoots.kotlinSourceFiles,
commonSourceSet.toList(),
@@ -554,7 +554,11 @@ open class Kotlin2JsCompile() : AbstractKotlinCompile<K2JSCompilerArguments>(),
)
} else null
val environment = GradleCompilerEnvironment(computedCompilerClasspath, messageCollector, outputItemCollector, icEnv)
val environment = GradleCompilerEnvironment(
computedCompilerClasspath, messageCollector, outputItemCollector,
localStateDirectories = localStateDirectories(),
incrementalCompilationEnvironment = icEnv
)
compilerRunner.runJsCompilerAsync(sourceRoots.kotlinSourceFiles, commonSourceSet.toList(), args, environment)
}
}
@@ -3,6 +3,8 @@ package org.jetbrains.kotlin.gradle.tasks
import org.gradle.api.GradleException
import org.gradle.api.Task
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.compilerRunner.GradleKotlinLogger
import org.jetbrains.kotlin.compilerRunner.KotlinLogger
import org.jetbrains.kotlin.gradle.plugin.kotlinDebug
import org.jetbrains.kotlin.gradle.utils.outputsCompatible
import java.io.File
@@ -18,23 +20,27 @@ fun throwGradleExceptionIfError(exitCode: ExitCode) {
}
}
internal val <T : Task> T.outputDirectories: List<File>
get() = outputsCompatible.files.files.filter { it.isDirectory }
internal fun <T : Task> T.localStateDirectories(): List<File> =
outputsCompatible.files.files.filter { it.isDirectory }
internal fun <T : Task> T.clearOutputDirectories(reason: String? = null) {
logger.kotlinDebug {
internal fun <T : Task> T.clearLocalStateDirectories(reason: String? = null) {
clearLocalStateDirectories(GradleKotlinLogger(logger), localStateDirectories(), reason)
}
internal fun clearLocalStateDirectories(log: KotlinLogger, localStateDirectories: List<File>, reason: String?) {
log.kotlinDebug {
val suffix = reason?.let { " ($it)" }.orEmpty()
"Clearing output directories for task '$path'$suffix:"
"Clearing output directories$suffix:"
}
val outputDirectories = outputDirectories
for (dir in outputDirectories) {
for (dir in localStateDirectories) {
if (!dir.exists()) continue
when {
dir.isDirectory -> {
dir.deleteRecursively()
dir.mkdirs()
logger.kotlinDebug { " deleted $dir" }
log.kotlinDebug { " deleted $dir" }
}
else -> logger.kotlinDebug { " skipping $dir (not a directory)" }
else -> log.kotlinDebug { " skipping $dir (not a directory)" }
}
}
}