Add build reports for diagnosing build problems in Gradle

#KT-12700 Fixed

To turn build reports, add 'kotlin.build.report.enable=true' to
gradle.properties file
(or pass it in CLI via`-Pkotlin.build.report.enable=true`).
By default build reports are created in
`rootProject/build/reports/kotlin-build`.
Build report dir can be customized via `kotlin.build.report.dir`
property.
This commit is contained in:
Alexey Tsvetkov
2019-01-28 15:35:26 +03:00
parent 8fc8b95d83
commit 98ef00b957
15 changed files with 375 additions and 27 deletions
@@ -26,5 +26,6 @@ interface CompilationResults : Remote {
}
enum class CompilationResultCategory(val code: Int) {
IC_COMPILE_ITERATION(0)
IC_COMPILE_ITERATION(0),
IC_LOG(1)
}
@@ -511,13 +511,18 @@ class CompileServiceImpl(
val workingDir = incrementalCompilationOptions.workingDir
val modulesApiHistory = ModulesApiHistoryJs(incrementalCompilationOptions.modulesInfo)
val compiler = IncrementalJsCompilerRunner(
workingDir = workingDir,
reporter = reporter,
buildHistoryFile = incrementalCompilationOptions.multiModuleICSettings.buildHistoryFile,
modulesApiHistory = modulesApiHistory
)
return compiler.compile(allKotlinFiles, args, compilerMessageCollector, changedFiles)
return try {
compiler.compile(allKotlinFiles, args, compilerMessageCollector, changedFiles)
} finally {
reporter.flush()
}
}
private fun execIncrementalCompiler(
@@ -570,6 +575,8 @@ class CompileServiceImpl(
val workingDir = incrementalCompilationOptions.workingDir
val modulesApiHistory = incrementalCompilationOptions.run {
reporter.report { "Use module detection: ${multiModuleICSettings.useModuleDetection}" }
if (!multiModuleICSettings.useModuleDetection) {
ModulesApiHistoryJvm(modulesInfo)
} else {
@@ -587,7 +594,11 @@ class CompileServiceImpl(
modulesApiHistory = modulesApiHistory,
kotlinSourceFilesExtensions = allKotlinExtensions
)
return compiler.compile(allKotlinFiles, k2jvmArgs, compilerMessageCollector, changedFiles)
return try {
compiler.compile(allKotlinFiles, k2jvmArgs, compilerMessageCollector, changedFiles)
} finally {
reporter.flush()
}
}
override fun leaseReplSession(
@@ -22,26 +22,54 @@ import org.jetbrains.kotlin.incremental.ICReporter
import java.io.File
internal class RemoteICReporter(
private val servicesFacade: CompilerServicesFacadeBase,
private val compilationResults: CompilationResults,
compilationOptions: CompilationOptions
private val servicesFacade: CompilerServicesFacadeBase,
private val compilationResults: CompilationResults,
compilationOptions: IncrementalCompilationOptions
) : ICReporter {
private val rootDir = compilationOptions.modulesInfo.projectRoot
private val shouldReportMessages = ReportCategory.IC_MESSAGE.code in compilationOptions.reportCategories
private val isVerbose = compilationOptions.reportSeverity == ReportSeverity.DEBUG.code
private val shouldReportCompileIteration = CompilationResultCategory.IC_COMPILE_ITERATION.code in compilationOptions.requestedCompilationResults
private val shouldReportCompileIteration =
CompilationResultCategory.IC_COMPILE_ITERATION.code in compilationOptions.requestedCompilationResults
private val shouldReportICLog = CompilationResultCategory.IC_LOG.code in compilationOptions.requestedCompilationResults
private val icLogLines = arrayListOf<String>()
override fun report(message: () -> String) {
val lazyMessage = lazy { message() }
if (shouldReportMessages && isVerbose) {
servicesFacade.report(ReportCategory.IC_MESSAGE, ReportSeverity.DEBUG, message())
servicesFacade.report(ReportCategory.IC_MESSAGE, ReportSeverity.DEBUG, lazyMessage.value)
}
if (shouldReportICLog) {
icLogLines.add(lazyMessage.value)
}
}
override fun reportCompileIteration(sourceFiles: Collection<File>, exitCode: ExitCode) {
if (shouldReportCompileIteration) {
compilationResults.add(CompilationResultCategory.IC_COMPILE_ITERATION.code,
CompileIterationResult(sourceFiles, exitCode.toString())
compilationResults.add(
CompilationResultCategory.IC_COMPILE_ITERATION.code,
CompileIterationResult(sourceFiles, exitCode.toString())
)
}
if (shouldReportICLog) {
icLogLines.add("compile iteration:")
sourceFiles.relativePaths(rootDir).forEach {
icLogLines.add(" $it")
}
}
}
fun flush() {
if (shouldReportICLog) {
compilationResults.add(CompilationResultCategory.IC_LOG.code, icLogLines)
}
}
private fun File.relativeOrCanonical(base: File): String =
relativeToOrNull(base)?.path ?: canonicalPath
private fun Iterable<File>.relativePaths(base: File): List<String> =
map { it.relativeOrCanonical(base) }.sorted()
}