From f327391ba33e4757719cd3a08e39087e1d1cf68a Mon Sep 17 00:00:00 2001 From: "Nataliya.Valtman" Date: Wed, 24 Jan 2024 13:47:36 +0100 Subject: [PATCH] Add validation for empty kotlin.build.report.json.directory property #KT-66314: Fixed (cherry picked from commit c2023142f5e6714a6dffea270d238c38f9577dce) --- .../gradle/plugin/PropertiesProvider.kt | 13 +++--- .../kotlin/gradle/report/configureReporing.kt | 26 ++++++++--- .../report/ConfigureReportingTest.kt | 44 +++++++++++++++++++ 3 files changed, 72 insertions(+), 11 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/report/ConfigureReportingTest.kt diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt index 627f6107d0a94..a66c0f5b704f0 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt @@ -71,8 +71,8 @@ internal class PropertiesProvider private constructor(private val project: Proje val singleBuildMetricsFile: File? get() = property("kotlin.internal.single.build.metrics.file").orNull?.let { File(it) } - val buildReportSingleFile: File? - get() = property(PropertyNames.KOTLIN_BUILD_REPORT_SINGLE_FILE).orNull?.let { File(it) } + val buildReportSingleFile: String? + get() = property(PropertyNames.KOTLIN_BUILD_REPORT_SINGLE_FILE).orNull val buildReportOutputs: List get() = property("kotlin.build.report.output").orNull?.split(",") ?: emptyList() @@ -80,8 +80,8 @@ internal class PropertiesProvider private constructor(private val project: Proje val buildReportLabel: String? get() = property("kotlin.build.report.label").orNull - val buildReportFileOutputDir: File? - get() = property("kotlin.build.report.file.output_dir").orNull?.let { File(it) } + val buildReportFileOutputDir: String? + get() = property(PropertyNames.KOTLIN_BUILD_REPORT_FILE_DIR).orNull val buildReportHttpUrl: String? get() = property(PropertyNames.KOTLIN_BUILD_REPORT_HTTP_URL).orNull @@ -110,8 +110,8 @@ internal class PropertiesProvider private constructor(private val project: Proje val buildReportMetrics: Boolean get() = booleanProperty("kotlin.build.report.metrics") ?: false - val buildReportJsonDir: File? - get() = property(PropertyNames.KOTLIN_BUILD_REPORT_JSON_DIR).orNull?.let { File(it) } + val buildReportJsonDir: String? + get() = property(PropertyNames.KOTLIN_BUILD_REPORT_JSON_DIR).orNull val buildReportVerbose: Boolean get() = booleanProperty("kotlin.build.report.verbose") ?: false @@ -627,6 +627,7 @@ internal class PropertiesProvider private constructor(private val project: Proje val KOTLIN_BUILD_REPORT_SINGLE_FILE = property("kotlin.build.report.single_file") val KOTLIN_BUILD_REPORT_HTTP_URL = property("kotlin.build.report.http.url") val KOTLIN_BUILD_REPORT_JSON_DIR = property("kotlin.build.report.json.directory") + val KOTLIN_BUILD_REPORT_FILE_DIR = property("kotlin.build.report.file.output_dir") val KOTLIN_OPTIONS_SUPPRESS_FREEARGS_MODIFICATION_WARNING = property("kotlin.options.suppressFreeCompilerArgsModificationWarning") val KOTLIN_NATIVE_USE_XCODE_MESSAGE_STYLE = property("kotlin.native.useXcodeMessageStyle") val KOTLIN_COMPILER_USE_PRECISE_COMPILATION_RESULTS_BACKUP = property("kotlin.compiler.preciseCompilationResultsBackup") diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/configureReporing.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/configureReporing.kt index 97bcaea42840c..d3937bd971b31 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/configureReporing.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/configureReporing.kt @@ -13,11 +13,13 @@ import org.jetbrains.kotlin.build.report.metrics.BuildTime import org.jetbrains.kotlin.build.report.metrics.GradleBuildPerformanceMetric import org.jetbrains.kotlin.build.report.metrics.GradleBuildTime import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider +import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_BUILD_REPORT_FILE_DIR import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_BUILD_REPORT_SINGLE_FILE import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_BUILD_REPORT_HTTP_URL import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_BUILD_REPORT_JSON_DIR import org.jetbrains.kotlin.gradle.plugin.internal.isProjectIsolationEnabled import org.jetbrains.kotlin.util.capitalizeDecapitalize.toUpperCaseAsciiOnly +import java.io.File private val availableMetrics = GradleBuildTime.values().map { it.name } + GradleBuildPerformanceMetric.values().map { it.name } @@ -38,7 +40,10 @@ internal fun reportingSettings(project: Project): ReportingSettings { else -> BuildReportMode.VERBOSE } val fileReportSettings = if (buildReportOutputTypes.contains(BuildReportType.FILE)) { - val buildReportDir = properties.buildReportFileOutputDir ?: (if (project.isProjectIsolationEnabled) { + val buildReportDir = properties.buildReportFileOutputDir?.let { + validateFileName(it, KOTLIN_BUILD_REPORT_FILE_DIR) + File(it) + } ?: (if (project.isProjectIsolationEnabled) { // TODO: it's a workaround for KT-52963, should be reworked – KT-55763 project.rootDir.resolve("build") } else { @@ -74,13 +79,17 @@ internal fun reportingSettings(project: Project): ReportingSettings { } val singleOutputFile = if (buildReportOutputTypes.contains(BuildReportType.SINGLE_FILE)) { - properties.buildReportSingleFile - ?: throw IllegalStateException("Can't configure single file report: '$KOTLIN_BUILD_REPORT_SINGLE_FILE' property is mandatory") + properties.buildReportSingleFile?.let { + validateFileName(it, KOTLIN_BUILD_REPORT_SINGLE_FILE) + File(it) + } ?: throw IllegalStateException("Can't configure single file report: '$KOTLIN_BUILD_REPORT_SINGLE_FILE' property is mandatory") } else null val jsonReportDir = if (buildReportOutputTypes.contains(BuildReportType.JSON)) { - properties.buildReportJsonDir - ?: throw IllegalStateException("Can't configure json report: '$KOTLIN_BUILD_REPORT_JSON_DIR' property is mandatory") + properties.buildReportJsonDir?.let { + validateFileName(it, KOTLIN_BUILD_REPORT_JSON_DIR) + File(it) + } ?: throw IllegalStateException("Can't configure json report: '$KOTLIN_BUILD_REPORT_JSON_DIR' property is mandatory") } else null //temporary solution. support old property @@ -100,4 +109,11 @@ internal fun reportingSettings(project: Project): ReportingSettings { ) } +private fun validateFileName(fileName: String, propertyName: String) { + if (fileName.isBlank()) { + throw IllegalStateException("The property '$propertyName' must not be empty. Please provide a valid value.") + } +} + + diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/report/ConfigureReportingTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/report/ConfigureReportingTest.kt new file mode 100644 index 0000000000000..4b034adbf5b0c --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/report/ConfigureReportingTest.kt @@ -0,0 +1,44 @@ +/* + * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.gradle.unitTests.report + +import org.gradle.api.internal.plugins.PluginApplicationException +import org.jetbrains.kotlin.gradle.util.applyKotlinJvmPlugin +import org.jetbrains.kotlin.gradle.util.buildProject +import org.jetbrains.kotlin.gradle.util.propertiesExtension +import org.junit.jupiter.api.assertThrows +import kotlin.test.Test +import kotlin.test.assertEquals + +class ConfigureReportingTest { + + @Test + fun validateMandatoryJsonDirectory() { + val exception = + assertThrows("The property 'kotlin.build.report.json.directory' is mandatory for JSON output. Validation should fail.") { + buildProject { + propertiesExtension.set("kotlin.build.report.output", "json") + applyKotlinJvmPlugin() + } + } + + assertEquals("Can't configure json report: 'kotlin.build.report.json.directory' property is mandatory", exception.cause?.message) + } + + @Test + fun validateInvalidJsonDirectory() { + val exception = + assertThrows("The property 'kotlin.build.report.json.directory' should not be empty. Validation should fail.") { + buildProject { + propertiesExtension.set("kotlin.build.report.output", "json") + propertiesExtension.set("kotlin.build.report.json.directory", "") + applyKotlinJvmPlugin() + } + } + + assertEquals("The property 'kotlin.build.report.json.directory' must not be empty. Please provide a valid value.", exception.cause?.message) + } +} \ No newline at end of file