From f4951990cdaca94b92245d0e4480ba235adfad70 Mon Sep 17 00:00:00 2001 From: Hanbin Lee Date: Tue, 24 Jan 2023 02:23:05 +0900 Subject: [PATCH] =?UTF-8?q?[#31]=20feat:=20BuildService=20=EC=9D=B4?= =?UTF-8?q?=EC=9A=A9=ED=95=9C=20gradle=20lifecycle=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - test finished 경우에 result logging 출력을 위한 gradle lifecycle 테스트 진행중 - 전반적인 리팩토링 --- .gitignore | 1 + Jenkinsfile => Jenkinsfile-service | 0 build.gradle.kts | 89 ++++++++++--------- .../kotlin/plugin/BuildLifecyclePlugin.kt | 19 ++++ .../kotlin/plugin/BuildOperationService.kt | 22 +++++ .../src/main/kotlin/plugin/TestSummary.kt | 25 ++++++ 6 files changed, 115 insertions(+), 41 deletions(-) rename Jenkinsfile => Jenkinsfile-service (100%) create mode 100644 buildSrc/src/main/kotlin/plugin/BuildLifecyclePlugin.kt create mode 100644 buildSrc/src/main/kotlin/plugin/BuildOperationService.kt create mode 100644 buildSrc/src/main/kotlin/plugin/TestSummary.kt diff --git a/.gitignore b/.gitignore index c426c32..679caf1 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ bin/ out/ !**/src/main/**/out/ !**/src/test/**/out/ +lib/ ### NetBeans ### /nbproject/private/ diff --git a/Jenkinsfile b/Jenkinsfile-service similarity index 100% rename from Jenkinsfile rename to Jenkinsfile-service diff --git a/build.gradle.kts b/build.gradle.kts index ae2ed0f..742326a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,6 +2,8 @@ import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.api.tasks.testing.logging.TestLogEvent import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.springframework.boot.gradle.tasks.bundling.BootJar +import plugin.BuildLifecyclePlugin +import plugin.TestSummary plugins { id(Plugins.Spring.boot).version(Version.Spring.boot) @@ -34,7 +36,10 @@ subprojects { plugin(Plugins.Kotlin.kotlinJpa) } - java.sourceCompatibility = JavaVersion.VERSION_17 + java.apply { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } dependencies { // Spring Boot Project @@ -81,7 +86,6 @@ subprojects { events = setOf( TestLogEvent.FAILED, TestLogEvent.SKIPPED, - TestLogEvent.STANDARD_OUT, TestLogEvent.STANDARD_ERROR ) @@ -98,53 +102,56 @@ subprojects { override fun afterSuite(desc: TestDescriptor, result: TestResult) { if (desc.parent != null) return - val summary = TestOutcome().apply { - add("${project.name}:${name} Test result: ${result.resultType}") - add("Test summary: ${result.testCount} tests, ${result.successfulTestCount} succeeded, ${result.failedTestCount} failed, ${result.skippedTestCount} skipped") - add("report file: ${reports.html.entryPoint}") - } + val summary = TestSummary( + projectName = project.name, + taskName = name, + result = result + ) - if (result.resultType == TestResult.ResultType.SUCCESS) { - testResults.add(0, summary) - } else { - testResults.add(summary) - } +// if (result.resultType == TestResult.ResultType.SUCCESS) { +// testResults.add(0, summary) +// } else { +// testResults.add(summary) +// } } override fun beforeTest(testDescriptor: TestDescriptor?) {} override fun afterTest(testDescriptor: TestDescriptor?, result: TestResult?) {} }) } + + // for logging when build finished + apply() } -gradle.buildFinished { - if (testResults.isNotEmpty()) { - printResults(testResults) - } -} +//gradle.buildFinished { +// if (testResults.isNotEmpty()) { +// printResults(testResults) +// } +//} -fun printResults(allResults:List) { - val maxLength = allResults.maxOfOrNull { it.maxWidth() } ?: 0 +//fun printResults(allResults:List) { +// val maxLength = allResults.maxOfOrNull { it.maxWidth() } ?: 0 +// +// println("┌${"─".repeat(maxLength)}┐") +// +// println(allResults.joinToString("├${"─".repeat(maxLength)}┤\n") { testOutcome -> +// testOutcome.lines.joinToString("│\n│", "│", "│") { +// it + " ".repeat(maxLength - it.length) +// } +// }) +// +// println("└${"─".repeat(maxLength)}┘") +//} +// +//val testResults by extra(mutableListOf()) // Container for tests summaries - println("┌${"─".repeat(maxLength)}┐") - - println(allResults.joinToString("├${"─".repeat(maxLength)}┤\n") { testOutcome -> - testOutcome.lines.joinToString("│\n│", "│", "│") { - it + " ".repeat(maxLength - it.length) - } - }) - - println("└${"─".repeat(maxLength)}┘") -} - -val testResults by extra(mutableListOf()) // Container for tests summaries - -data class TestOutcome(val lines: MutableList = mutableListOf()) { - fun add(line: String) { - lines.add(line) - } - - fun maxWidth(): Int { - return lines.maxBy { it.length }?.length ?: 0 - } -} \ No newline at end of file +//data class TestOutcome(val lines: MutableList = mutableListOf()) { +// fun add(line: String) { +// lines.add(line) +// } +// +// fun maxWidth(): Int { +// return lines.maxByOrNull { it.length }?.length ?: 0 +// } +//} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/plugin/BuildLifecyclePlugin.kt b/buildSrc/src/main/kotlin/plugin/BuildLifecyclePlugin.kt new file mode 100644 index 0000000..a606ab9 --- /dev/null +++ b/buildSrc/src/main/kotlin/plugin/BuildLifecyclePlugin.kt @@ -0,0 +1,19 @@ +package plugin + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.internal.build.event.BuildEventListenerRegistryInternal +import org.gradle.invocation.DefaultGradle + +class BuildLifecyclePlugin : Plugin { + override fun apply(project: Project) { + val gradle = project.gradle + + val services = (gradle as DefaultGradle).services + val registry = services[BuildEventListenerRegistryInternal::class.java] + + val operationService = gradle.sharedServices.registerIfAbsent("operationService", BuildOperationService::class.java) {} + + registry.subscribe(operationService) + } +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/plugin/BuildOperationService.kt b/buildSrc/src/main/kotlin/plugin/BuildOperationService.kt new file mode 100644 index 0000000..cab7b36 --- /dev/null +++ b/buildSrc/src/main/kotlin/plugin/BuildOperationService.kt @@ -0,0 +1,22 @@ +package plugin + +import org.gradle.api.services.BuildService +import org.gradle.api.services.BuildServiceParameters +import org.gradle.tooling.events.FinishEvent +import org.gradle.tooling.events.OperationCompletionListener +import org.gradle.tooling.events.task.TaskFinishEvent + +abstract class BuildOperationService : BuildService, OperationCompletionListener { + private val targetProjects = listOf("dongne-account-api", "dongne-service-api") + private val targetTask = "test" + + override fun onFinish(event: FinishEvent?) { + if (event == null || event !is TaskFinishEvent) { + return + } + + if (event.descriptor.taskPath in targetProjects.map { ":$it:$targetTask" }) { + println("####### onFinish 222 ${event}") + } + } +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/plugin/TestSummary.kt b/buildSrc/src/main/kotlin/plugin/TestSummary.kt new file mode 100644 index 0000000..e96b402 --- /dev/null +++ b/buildSrc/src/main/kotlin/plugin/TestSummary.kt @@ -0,0 +1,25 @@ +package plugin + +import org.gradle.api.tasks.testing.TestResult + +data class TestSummary( + val projectName: String? = null, + val taskName: String? = null, + val result: TestResult, + val lines: MutableList = mutableListOf() +) { + fun add(line: String) { + lines.add(line) + } + + fun maxWidth(): Int { + return lines.maxByOrNull { it.length }?.length ?: 0 + } + + fun toLogList(): List { + return listOf( + "${projectName}:${taskName} Test result: ${result.resultType}", + "Test summary: ${result.testCount} tests, ${result.successfulTestCount} succeeded, ${result.failedTestCount} failed, ${result.skippedTestCount} skipped" + ) + } +} \ No newline at end of file