mirror of
https://github.com/ethauvin/kobalt.git
synced 2025-04-26 00:17:11 -07:00
Bubble up test result messages.
This commit is contained in:
parent
f276eb3001
commit
6401a9d2af
16 changed files with 63 additions and 32 deletions
|
@ -1,3 +1,8 @@
|
||||||
package com.beust.kobalt
|
package com.beust.kobalt
|
||||||
|
|
||||||
open public class TaskResult(val success: Boolean = true, val errorMessage: String? = null)
|
class TestResult(val success: Boolean, val shortMessage: String? = null, val longMessage: String? = null)
|
||||||
|
|
||||||
|
open class TaskResult(val success: Boolean = true,
|
||||||
|
val testResult: TestResult? = null,
|
||||||
|
val errorMessage: String? = null
|
||||||
|
)
|
||||||
|
|
|
@ -4,8 +4,12 @@ package com.beust.kobalt.api
|
||||||
* Plug-ins that listen to build events.
|
* Plug-ins that listen to build events.
|
||||||
*/
|
*/
|
||||||
interface IBuildListener : IListener {
|
interface IBuildListener : IListener {
|
||||||
|
|
||||||
|
class TaskEndInfo(val success: Boolean, val shortMessage: String? = null,
|
||||||
|
val longMessage: String? = null)
|
||||||
|
|
||||||
fun taskStart(project: Project, context: KobaltContext, taskName: String) {}
|
fun taskStart(project: Project, context: KobaltContext, taskName: String) {}
|
||||||
fun taskEnd(project: Project, context: KobaltContext, taskName: String, success: Boolean) {}
|
fun taskEnd(project: Project, context: KobaltContext, taskName: String, info: TaskEndInfo) {}
|
||||||
|
|
||||||
fun projectStart(project: Project, context: KobaltContext) {}
|
fun projectStart(project: Project, context: KobaltContext) {}
|
||||||
fun projectEnd(project: Project, context: KobaltContext, status: ProjectBuildStatus) {}
|
fun projectEnd(project: Project, context: KobaltContext, status: ProjectBuildStatus) {}
|
||||||
|
|
|
@ -23,7 +23,7 @@ class DynamicTask(override val plugin: IPlugin, override val name: String, overr
|
||||||
|
|
||||||
override fun call(): TaskResult2<ITask> {
|
override fun call(): TaskResult2<ITask> {
|
||||||
val taskResult = closure.invoke(project)
|
val taskResult = closure.invoke(project)
|
||||||
return TaskResult2(taskResult.success, taskResult.errorMessage, this)
|
return TaskResult2(taskResult.success, errorMessage = taskResult.errorMessage, value = this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString() = "[DynamicTask $name dependsOn=$dependsOn reverseDependsOn=$reverseDependsOn]"
|
override fun toString() = "[DynamicTask $name dependsOn=$dependsOn reverseDependsOn=$reverseDependsOn]"
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.beust.kobalt.internal
|
package com.beust.kobalt.internal
|
||||||
|
|
||||||
|
import com.beust.kobalt.TestResult
|
||||||
|
import com.beust.kobalt.api.IBuildListener
|
||||||
import com.beust.kobalt.api.KobaltContext
|
import com.beust.kobalt.api.KobaltContext
|
||||||
import com.beust.kobalt.api.Project
|
import com.beust.kobalt.api.Project
|
||||||
import com.beust.kobalt.api.ProjectBuildStatus
|
import com.beust.kobalt.api.ProjectBuildStatus
|
||||||
|
@ -25,9 +27,14 @@ abstract class BaseProjectRunner {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun runBuildListenersForTask(project: Project, context: KobaltContext, taskName: String, start: Boolean,
|
fun runBuildListenersForTask(project: Project, context: KobaltContext, taskName: String, start: Boolean,
|
||||||
success: Boolean = false) {
|
success: Boolean = false, testResult: TestResult? = null) {
|
||||||
context.pluginInfo.buildListeners.forEach {
|
context.pluginInfo.buildListeners.forEach {
|
||||||
if (start) it.taskStart(project, context, taskName) else it.taskEnd(project, context, taskName, success)
|
if (start) {
|
||||||
|
it.taskStart(project, context, taskName)
|
||||||
|
} else {
|
||||||
|
val info = IBuildListener.TaskEndInfo(success, testResult?.shortMessage, testResult?.longMessage)
|
||||||
|
it.taskEnd(project, context, taskName, info)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,8 @@ import java.util.concurrent.ConcurrentHashMap
|
||||||
*/
|
*/
|
||||||
class BuildListeners : IBuildListener, IBuildReportContributor {
|
class BuildListeners : IBuildListener, IBuildReportContributor {
|
||||||
class ProfilerInfo(val taskName: String, val durationMillis: Long)
|
class ProfilerInfo(val taskName: String, val durationMillis: Long)
|
||||||
class ProjectInfo(val projectName: String, var durationMillis: Long = 0)
|
class ProjectInfo(val projectName: String, var durationMillis: Long = 0,
|
||||||
|
var shortMessage: String? = null, var longMessage: String? = null)
|
||||||
|
|
||||||
private val startTimes = ConcurrentHashMap<String, Long>()
|
private val startTimes = ConcurrentHashMap<String, Long>()
|
||||||
private val timings = arrayListOf<ProfilerInfo>()
|
private val timings = arrayListOf<ProfilerInfo>()
|
||||||
|
@ -29,18 +30,21 @@ class BuildListeners : IBuildListener, IBuildReportContributor {
|
||||||
}
|
}
|
||||||
|
|
||||||
// IBuildListener
|
// IBuildListener
|
||||||
override fun taskEnd(project: Project, context: KobaltContext, taskName: String, success: Boolean) {
|
override fun taskEnd(project: Project, context: KobaltContext, taskName: String, info: IBuildListener.TaskEndInfo) {
|
||||||
|
val success = info.success
|
||||||
if (! success) hasFailures = true
|
if (! success) hasFailures = true
|
||||||
startTimes[taskName]?.let {
|
startTimes[taskName]?.let {
|
||||||
val taskTime = System.currentTimeMillis() - it
|
val taskTime = System.currentTimeMillis() - it
|
||||||
timings.add(ProfilerInfo(taskName, taskTime))
|
timings.add(ProfilerInfo(taskName, taskTime))
|
||||||
projectInfos[project.name]?.let {
|
projectInfos[project.name]?.let {
|
||||||
it.durationMillis += taskTime.toLong()
|
it.durationMillis += taskTime
|
||||||
|
if (info.shortMessage != null && it.shortMessage == null) it.shortMessage = info.shortMessage
|
||||||
|
if (info.longMessage != null && it.longMessage == null) it.longMessage = info.longMessage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val projectStatuses = arrayListOf<Pair<Project, ProjectBuildStatus>>()
|
private val projectStatuses = arrayListOf<Pair<Project, String>>()
|
||||||
|
|
||||||
// IBuildListener
|
// IBuildListener
|
||||||
override fun projectStart(project: Project, context: KobaltContext) {
|
override fun projectStart(project: Project, context: KobaltContext) {
|
||||||
|
@ -49,7 +53,9 @@ class BuildListeners : IBuildListener, IBuildReportContributor {
|
||||||
|
|
||||||
// IBuildListener
|
// IBuildListener
|
||||||
override fun projectEnd(project: Project, context: KobaltContext, status: ProjectBuildStatus) {
|
override fun projectEnd(project: Project, context: KobaltContext, status: ProjectBuildStatus) {
|
||||||
projectStatuses.add(Pair(project, status))
|
val shortMessage = projectInfos[project.name]?.shortMessage
|
||||||
|
val statusText = status.toString() + (if (shortMessage != null) " ($shortMessage)" else "")
|
||||||
|
projectStatuses.add(Pair(project, statusText))
|
||||||
}
|
}
|
||||||
|
|
||||||
// IBuildReportContributor
|
// IBuildReportContributor
|
||||||
|
|
|
@ -7,7 +7,8 @@ import java.lang.reflect.InvocationTargetException
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.*
|
import java.util.concurrent.*
|
||||||
|
|
||||||
open class TaskResult2<T>(success: Boolean, errorMessage: String?, val value: T) : TaskResult(success, errorMessage) {
|
open class TaskResult2<T>(success: Boolean, testResult: TestResult? = null,
|
||||||
|
errorMessage: String? = null, val value: T) : TaskResult(success, testResult, errorMessage) {
|
||||||
override fun toString() = com.beust.kobalt.misc.toString("TaskResult", "value", value, "success", success)
|
override fun toString() = com.beust.kobalt.misc.toString("TaskResult", "value", value, "success", success)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,7 +394,7 @@ fun main(argv: Array<String>) {
|
||||||
object: IWorker<String> {
|
object: IWorker<String> {
|
||||||
override fun call(): TaskResult2<String>? {
|
override fun call(): TaskResult2<String>? {
|
||||||
kobaltLog(1, " Running worker $it")
|
kobaltLog(1, " Running worker $it")
|
||||||
return TaskResult2(true, null, it)
|
return TaskResult2(true, value = it)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val priority: Int get() = 0
|
override val priority: Int get() = 0
|
||||||
|
|
|
@ -16,6 +16,8 @@ abstract class GenericTestRunner: ITestRunnerContributor {
|
||||||
abstract val mainClass: String
|
abstract val mainClass: String
|
||||||
abstract val annotationPackage: String
|
abstract val annotationPackage: String
|
||||||
abstract val runnerName: String
|
abstract val runnerName: String
|
||||||
|
open val shortMessage: String? = null//""Short message"
|
||||||
|
open val longMessage: String? = null//""Long message"
|
||||||
|
|
||||||
abstract fun args(project: Project, context: KobaltContext, classpath: List<IClasspathDependency>,
|
abstract fun args(project: Project, context: KobaltContext, classpath: List<IClasspathDependency>,
|
||||||
testConfig: TestConfig) : List<String>
|
testConfig: TestConfig) : List<String>
|
||||||
|
@ -25,8 +27,10 @@ abstract class GenericTestRunner: ITestRunnerContributor {
|
||||||
open fun filterTestClasses(classes: List<String>) : List<String> = classes
|
open fun filterTestClasses(classes: List<String>) : List<String> = classes
|
||||||
|
|
||||||
override fun run(project: Project, context: KobaltContext, configName: String,
|
override fun run(project: Project, context: KobaltContext, configName: String,
|
||||||
classpath: List<IClasspathDependency>)
|
classpath: List<IClasspathDependency>) : TaskResult {
|
||||||
= TaskResult(runTests(project, context, classpath, configName))
|
val tr = runTests(project, context, classpath, configName)
|
||||||
|
return TaskResult(tr.success, testResult = tr)
|
||||||
|
}
|
||||||
|
|
||||||
override fun affinity(project: Project, context: KobaltContext) : Int {
|
override fun affinity(project: Project, context: KobaltContext) : Int {
|
||||||
val result =
|
val result =
|
||||||
|
@ -99,7 +103,7 @@ abstract class GenericTestRunner: ITestRunnerContributor {
|
||||||
* @return true if all the tests passed
|
* @return true if all the tests passed
|
||||||
*/
|
*/
|
||||||
open fun runTests(project: Project, context: KobaltContext, classpath: List<IClasspathDependency>,
|
open fun runTests(project: Project, context: KobaltContext, classpath: List<IClasspathDependency>,
|
||||||
configName: String) : Boolean {
|
configName: String) : TestResult {
|
||||||
var result = false
|
var result = false
|
||||||
|
|
||||||
context.logger.log(project.name, 1, "Running tests with " + runnerName)
|
context.logger.log(project.name, 1, "Running tests with " + runnerName)
|
||||||
|
@ -140,7 +144,8 @@ abstract class GenericTestRunner: ITestRunnerContributor {
|
||||||
} else {
|
} else {
|
||||||
throw KobaltException("Couldn't find a test configuration named \"$configName\"")
|
throw KobaltException("Couldn't find a test configuration named \"$configName\"")
|
||||||
}
|
}
|
||||||
return result
|
|
||||||
|
return TestResult(result, shortMessage, longMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -54,12 +54,12 @@ class ParallelProjectRunner(val tasksByNames: (Project) -> ListMultimap<String,
|
||||||
runBuildListenersForTask(project, context, task.name, start = true)
|
runBuildListenersForTask(project, context, task.name, start = true)
|
||||||
logger.log(project.name, 1,
|
logger.log(project.name, 1,
|
||||||
AsciiArt.taskColor(AsciiArt.horizontalSingleLine + " ${project.name}:${task.name}"))
|
AsciiArt.taskColor(AsciiArt.horizontalSingleLine + " ${project.name}:${task.name}"))
|
||||||
val thisResult = if (dryRun) TaskResult2(true, null, task) else task.call()
|
val thisResult = if (dryRun) TaskResult2(true, value = task) else task.call()
|
||||||
if (lastResult.success) {
|
if (lastResult.success) {
|
||||||
lastResult = thisResult
|
lastResult = thisResult
|
||||||
}
|
}
|
||||||
runBuildListenersForTask(project, context, task.name, start = false,
|
runBuildListenersForTask(project, context, task.name, start = false,
|
||||||
success = thisResult.success)
|
success = thisResult.success, testResult = thisResult.testResult)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
graph.freeNodes.forEach { graph.removeNode(it) }
|
graph.freeNodes.forEach { graph.removeNode(it) }
|
||||||
|
@ -69,7 +69,7 @@ class ParallelProjectRunner(val tasksByNames: (Project) -> ListMultimap<String,
|
||||||
runBuildListenersForProject(project, context, false,
|
runBuildListenersForProject(project, context, false,
|
||||||
if (lastResult.success) ProjectBuildStatus.SUCCESS else ProjectBuildStatus.FAILED)
|
if (lastResult.success) ProjectBuildStatus.SUCCESS else ProjectBuildStatus.FAILED)
|
||||||
|
|
||||||
return TaskResult2(lastResult.success, lastResult.errorMessage, this)
|
return TaskResult2(lastResult.success, errorMessage = lastResult.errorMessage, value = this)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -272,7 +272,8 @@ class TaskManager @Inject constructor(val args: Args,
|
||||||
object : BasePluginTask(plugin, name, description, group, project) {
|
object : BasePluginTask(plugin, name, description, group, project) {
|
||||||
override fun call(): TaskResult2<ITask> {
|
override fun call(): TaskResult2<ITask> {
|
||||||
val taskResult = task(project)
|
val taskResult = task(project)
|
||||||
return TaskResult2(taskResult.success, taskResult.errorMessage, this)
|
return TaskResult2(taskResult.success, errorMessage = taskResult.errorMessage, value = this,
|
||||||
|
testResult = taskResult.testResult)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
dependsOn.forEach { dependsOn(it, name) }
|
dependsOn.forEach { dependsOn(it, name) }
|
||||||
|
@ -321,7 +322,7 @@ class TaskWorker(val tasks: List<ITask>, val dryRun: Boolean, val pluginInfo: Pl
|
||||||
success = success and tr.success
|
success = success and tr.success
|
||||||
if (tr.errorMessage != null) errorMessages.add(tr.errorMessage)
|
if (tr.errorMessage != null) errorMessages.add(tr.errorMessage)
|
||||||
}
|
}
|
||||||
return TaskResult2(success, errorMessages.joinToString("\n"), tasks[0])
|
return TaskResult2(success, errorMessage = errorMessages.joinToString("\n"), value = tasks[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
// override val timeOut : Long = 10000
|
// override val timeOut : Long = 10000
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.beust.kobalt.internal
|
||||||
|
|
||||||
import com.beust.kobalt.AsciiArt
|
import com.beust.kobalt.AsciiArt
|
||||||
import com.beust.kobalt.TestConfig
|
import com.beust.kobalt.TestConfig
|
||||||
|
import com.beust.kobalt.TestResult
|
||||||
import com.beust.kobalt.api.IClasspathDependency
|
import com.beust.kobalt.api.IClasspathDependency
|
||||||
import com.beust.kobalt.api.KobaltContext
|
import com.beust.kobalt.api.KobaltContext
|
||||||
import com.beust.kobalt.api.Project
|
import com.beust.kobalt.api.Project
|
||||||
|
@ -64,7 +65,7 @@ class TestNgRunner : GenericTestRunner() {
|
||||||
|
|
||||||
fun _runTests(project: Project, context: KobaltContext, classpath: List<IClasspathDependency>,
|
fun _runTests(project: Project, context: KobaltContext, classpath: List<IClasspathDependency>,
|
||||||
// override fun runTests(project: Project, context: KobaltContext, classpath: List<IClasspathDependency>,
|
// override fun runTests(project: Project, context: KobaltContext, classpath: List<IClasspathDependency>,
|
||||||
configName: String): Boolean {
|
configName: String): TestResult {
|
||||||
|
|
||||||
val testConfig = project.testConfigs.firstOrNull { it.name == configName }
|
val testConfig = project.testConfigs.firstOrNull { it.name == configName }
|
||||||
|
|
||||||
|
@ -85,7 +86,7 @@ class TestNgRunner : GenericTestRunner() {
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
} else {
|
} else {
|
||||||
return true
|
return TestResult(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +103,8 @@ class TestNgRunner : GenericTestRunner() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun displayPrettyColors(project: Project, context: KobaltContext,
|
private fun displayPrettyColors(project: Project, context: KobaltContext,
|
||||||
classpath: List<IClasspathDependency>, testConfig: TestConfig, versions: Pair<String, String>): Boolean {
|
classpath: List<IClasspathDependency>, testConfig: TestConfig, versions: Pair<String, String>)
|
||||||
|
: TestResult {
|
||||||
val port = 2345
|
val port = 2345
|
||||||
// launchRemoteServer(project, context, classpath, testConfig, versions, port)
|
// launchRemoteServer(project, context, classpath, testConfig, versions, port)
|
||||||
|
|
||||||
|
@ -151,7 +153,7 @@ class TestNgRunner : GenericTestRunner() {
|
||||||
val top = it.stackTrace.substring(0, it.stackTrace.indexOf("\n"))
|
val top = it.stackTrace.substring(0, it.stackTrace.indexOf("\n"))
|
||||||
kobaltLog(1, " " + it.cls + "." + it.method + "\n " + top)
|
kobaltLog(1, " " + it.cls + "." + it.method + "\n " + top)
|
||||||
}
|
}
|
||||||
return failed.isEmpty() && skipped.isEmpty()
|
return TestResult(failed.isEmpty() && skipped.isEmpty())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun launchRemoteServer(project: Project, context: KobaltContext, classpath: List<IClasspathDependency>,
|
fun launchRemoteServer(project: Project, context: KobaltContext, classpath: List<IClasspathDependency>,
|
||||||
|
|
|
@ -11,7 +11,7 @@ class Git @Inject constructor() {
|
||||||
if (uploadResult.success && enabled) {
|
if (uploadResult.success && enabled) {
|
||||||
val tagSuccess = tagRelease(project, annotated, tag, message)
|
val tagSuccess = tagRelease(project, annotated, tag, message)
|
||||||
if (! tagSuccess) {
|
if (! tagSuccess) {
|
||||||
TaskResult(false, "Couldn't tag the project")
|
TaskResult(false, errorMessage = "Couldn't tag the project")
|
||||||
} else {
|
} else {
|
||||||
TaskResult()
|
TaskResult()
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,11 +94,11 @@ class JavaCompiler @Inject constructor(val jvmCompiler: JvmCompiler, val kobaltL
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (result) {
|
return if (result) {
|
||||||
TaskResult(true, "Compilation succeeded")
|
TaskResult(true, errorMessage = "Compilation succeeded")
|
||||||
} else {
|
} else {
|
||||||
val message = "Compilation errors, command:\n$command\n" + errorMessage
|
val message = "Compilation errors, command:\n$command\n" + errorMessage
|
||||||
logk(1, message)
|
logk(1, message)
|
||||||
TaskResult(false, message)
|
TaskResult(false, errorMessage = message)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,7 @@ class KotlinCompiler @Inject constructor(
|
||||||
// The Kotlin compiler issues warnings on stderr :-(
|
// The Kotlin compiler issues warnings on stderr :-(
|
||||||
containsErrors = { errors: List<String> -> errors.any { it.contains("rror")} }
|
containsErrors = { errors: List<String> -> errors.any { it.contains("rror")} }
|
||||||
}).invoke()
|
}).invoke()
|
||||||
return TaskResult(result == 0, "Error while compiling")
|
return TaskResult(result == 0, errorMessage = "Error while compiling")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun invokeCompilerDirectly(projectName: String, outputDir: String?, info: CompilerActionInfo,
|
private fun invokeCompilerDirectly(projectName: String, outputDir: String?, info: CompilerActionInfo,
|
||||||
|
|
|
@ -204,7 +204,7 @@ class BintrayApi @Inject constructor(val http: Http,
|
||||||
return TaskResult()
|
return TaskResult()
|
||||||
} else {
|
} else {
|
||||||
error(" Errors while uploading:\n" + errorMessages.map { " $it" }.joinToString("\n"))
|
error(" Errors while uploading:\n" + errorMessages.map { " $it" }.joinToString("\n"))
|
||||||
return TaskResult(false, errorMessages.joinToString("\n"))
|
return TaskResult(false, errorMessage = errorMessages.joinToString("\n"))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
warn("Found no artifacts to upload")
|
warn("Found no artifacts to upload")
|
||||||
|
|
|
@ -153,7 +153,7 @@ class PublishPlugin @Inject constructor(val files: KFiles, val factory: PomGener
|
||||||
TaskResult()
|
TaskResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
val result = TaskResult(tmpResult.success, messages.joinToString("\n "))
|
val result = TaskResult(tmpResult.success, errorMessage = messages.joinToString("\n "))
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ class DynamicGraphTest {
|
||||||
override fun call() : TaskResult2<T> {
|
override fun call() : TaskResult2<T> {
|
||||||
kobaltLog(2, "Running node $n")
|
kobaltLog(2, "Running node $n")
|
||||||
runNodes.add(n)
|
runNodes.add(n)
|
||||||
return TaskResult2(errorFunction(n), null, n)
|
return TaskResult2(errorFunction(n), value = n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue