[Gradle] Read 'local.properties' in project isolation compatible way

^KT-59826 In Progress
This commit is contained in:
Yahor Berdnikau
2023-08-21 19:21:44 +02:00
committed by Space Team
parent b1965e746f
commit d6becee2ce
15 changed files with 194 additions and 119 deletions
@@ -55,68 +55,57 @@ import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinIrJsGeneratedTSValidation
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrOutputGranularity
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilerExecutionStrategy
import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader
import org.jetbrains.kotlin.gradle.utils.loadProperty
import org.jetbrains.kotlin.gradle.utils.localProperties
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.target.presetName
import org.jetbrains.kotlin.statistics.metrics.StringMetrics
import org.jetbrains.kotlin.tooling.core.UnsafeApi
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toUpperCaseAsciiOnly
import org.jetbrains.kotlin.util.prefixIfNot
import java.io.File
import java.util.*
@OptIn(UnsafeApi::class)
internal class PropertiesProvider private constructor(private val project: Project) {
private val localProperties: Properties by lazy {
Properties().apply {
val localPropertiesFile = File(project.rootDir, "local.properties")
if (localPropertiesFile.isFile) {
localPropertiesFile.inputStream().use {
load(it)
}
}
}
}
@Deprecated(message = "Please use kotlin.build.report.output=SINGLE_FILE and kotlin.build.report.single_file ")
val singleBuildMetricsFile: File?
get() = this.property("kotlin.internal.single.build.metrics.file")?.let { File(it) }
get() = property("kotlin.internal.single.build.metrics.file").orNull?.let { File(it) }
val buildReportSingleFile: File?
get() = this.property(PropertyNames.KOTLIN_BUILD_REPORT_SINGLE_FILE)?.let { File(it) }
get() = property(PropertyNames.KOTLIN_BUILD_REPORT_SINGLE_FILE).orNull?.let { File(it) }
val buildReportOutputs: List<String>
get() = this.property("kotlin.build.report.output")?.split(",") ?: emptyList()
get() = property("kotlin.build.report.output").orNull?.split(",") ?: emptyList()
val buildReportLabel: String?
get() = this.property("kotlin.build.report.label")
get() = property("kotlin.build.report.label").orNull
val buildReportFileOutputDir: File?
get() = this.property("kotlin.build.report.file.output_dir")?.let { File(it) }
get() = property("kotlin.build.report.file.output_dir").orNull?.let { File(it) }
val buildReportHttpUrl: String?
get() = this.property(PropertyNames.KOTLIN_BUILD_REPORT_HTTP_URL)
get() = property(PropertyNames.KOTLIN_BUILD_REPORT_HTTP_URL).orNull
val buildReportHttpUser: String?
get() = this.property("kotlin.build.report.http.user")
get() = property("kotlin.build.report.http.user").orNull
val buildReportHttpPassword: String?
get() = this.property("kotlin.build.report.http.password")
get() = property("kotlin.build.report.http.password").orNull
val buildReportHttpVerboseEnvironment: Boolean
get() = property("kotlin.build.report.http.verbose_environment")?.toBoolean() ?: false
get() = property("kotlin.build.report.http.verbose_environment").orNull?.toBoolean() ?: false
val buildReportHttpIncludeGitBranchName: Boolean
get() = property("kotlin.build.report.http.include_git_branch.name")?.toBoolean() ?: false
get() = property("kotlin.build.report.http.include_git_branch.name").orNull?.toBoolean() ?: false
val buildReportIncludeCompilerArguments: Boolean
get() = booleanProperty("kotlin.build.report.include_compiler_arguments") ?: true
val buildReportBuildScanCustomValuesLimit: Int
get() = property("kotlin.build.report.build_scan.custom_values_limit")?.toInt() ?: 1000
get() = property("kotlin.build.report.build_scan.custom_values_limit").orNull?.toInt() ?: 1000
val buildReportBuildScanMetrics: String?
get() = property("kotlin.build.report.build_scan.metrics")
get() = property("kotlin.build.report.build_scan.metrics").orNull
val buildReportMetrics: Boolean
get() = booleanProperty("kotlin.build.report.metrics") ?: false
@@ -126,7 +115,7 @@ internal class PropertiesProvider private constructor(private val project: Proje
@Deprecated("Please use \"kotlin.build.report.file.output_dir\" property instead")
val buildReportDir: File?
get() = this.property("kotlin.build.report.dir")?.let { File(it) }
get() = property("kotlin.build.report.dir").orNull?.let { File(it) }
val incrementalJvm: Boolean?
get() = booleanProperty("kotlin.incremental")
@@ -144,22 +133,24 @@ internal class PropertiesProvider private constructor(private val project: Proje
get() = booleanProperty(PropertyNames.KOTLIN_NATIVE_INCREMENTAL_COMPILATION)
val jsIrOutputGranularity: KotlinJsIrOutputGranularity
get() = this.property("kotlin.js.ir.output.granularity")?.let { KotlinJsIrOutputGranularity.byArgument(it) }
get() = property("kotlin.js.ir.output.granularity").orNull?.let { KotlinJsIrOutputGranularity.byArgument(it) }
?: KotlinJsIrOutputGranularity.PER_MODULE
val jsIrGeneratedTypeScriptValidationDevStrategy: KotlinIrJsGeneratedTSValidationStrategy
get() = this.property("kotlin.js.ir.development.typescript.validation.strategy")?.let {
KotlinIrJsGeneratedTSValidationStrategy.byArgument(
it
)
} ?: KotlinIrJsGeneratedTSValidationStrategy.IGNORE
get() = property("kotlin.js.ir.development.typescript.validation.strategy")
.orNull?.let {
KotlinIrJsGeneratedTSValidationStrategy.byArgument(
it
)
} ?: KotlinIrJsGeneratedTSValidationStrategy.IGNORE
val jsIrGeneratedTypeScriptValidationProdStrategy: KotlinIrJsGeneratedTSValidationStrategy
get() = this.property("kotlin.js.ir.production.typescript.validation.strategy")?.let {
KotlinIrJsGeneratedTSValidationStrategy.byArgument(
it
)
} ?: KotlinIrJsGeneratedTSValidationStrategy.IGNORE
get() = property("kotlin.js.ir.production.typescript.validation.strategy")
.orNull?.let {
KotlinIrJsGeneratedTSValidationStrategy.byArgument(
it
)
} ?: KotlinIrJsGeneratedTSValidationStrategy.IGNORE
val incrementalMultiplatform: Boolean?
get() = booleanProperty("kotlin.incremental.multiplatform")
@@ -251,7 +242,7 @@ internal class PropertiesProvider private constructor(private val project: Proje
get() = booleanProperty(KOTLIN_MPP_ANDROID_GRADLE_PLUGIN_COMPATIBILITY_NO_WARN) ?: false
val mppAndroidSourceSetLayoutVersion: Int?
get() = this.property(KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_VERSION)?.toIntOrNull()
get() = this.property(KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_VERSION).orNull?.toIntOrNull()
val ignoreMppAndroidSourceSetLayoutV2AndroidStyleDirs: Boolean
get() = booleanProperty(KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_ANDROID_STYLE_NO_WARN) ?: false
@@ -280,7 +271,7 @@ internal class PropertiesProvider private constructor(private val project: Proje
* - prebuilt - Includes all platform libraries.
*/
val nativeDistributionType: String?
get() = this.property("kotlin.native.distribution.type")
get() = property("kotlin.native.distribution.type").orNull
/**
* Allows overriding Kotlin/Native base download url.
@@ -288,7 +279,7 @@ internal class PropertiesProvider private constructor(private val project: Proje
* When Kotlin/native will try to download native compiler, it will append compiler version and os type to this url.
*/
val nativeBaseDownloadUrl: String
get() = this.property("kotlin.native.distribution.baseDownloadUrl") ?: NativeCompilerDownloader.BASE_DOWNLOAD_URL
get() = property("kotlin.native.distribution.baseDownloadUrl").orNull ?: NativeCompilerDownloader.BASE_DOWNLOAD_URL
/**
* Allows downloading Kotlin/Native distribution with maven.
@@ -332,7 +323,7 @@ internal class PropertiesProvider private constructor(private val project: Proje
* Allows a user to specify free compiler arguments for K/N linker.
*/
val nativeLinkArgs: List<String>
get() = this.property("kotlin.native.linkArgs").orEmpty().split(' ').filterNot { it.isBlank() }
get() = property("kotlin.native.linkArgs").orNull.orEmpty().split(' ').filterNot { it.isBlank() }
/**
* Forces to run a compilation in a separate JVM.
@@ -390,7 +381,7 @@ internal class PropertiesProvider private constructor(private val project: Proje
}
val commonizerLogLevel: String?
get() = this.property("kotlin.mpp.commonizerLogLevel")
get() = property("kotlin.mpp.commonizerLogLevel").orNull
val enableNativeDistributionCommonizationCache: Boolean
get() = booleanProperty("kotlin.mpp.enableNativeDistributionCommonizationCache") ?: true
@@ -408,25 +399,25 @@ internal class PropertiesProvider private constructor(private val project: Proje
* Dependencies caching strategy for all targets that support caches.
*/
val nativeCacheKind: NativeCacheKind?
get() = this.property("kotlin.native.cacheKind")?.let { NativeCacheKind.byCompilerArgument(it) }
get() = property("kotlin.native.cacheKind").orNull?.let { NativeCacheKind.byCompilerArgument(it) }
/**
* Dependencies caching strategy for [target].
*/
fun nativeCacheKindForTarget(target: KonanTarget): NativeCacheKind? =
this.property("kotlin.native.cacheKind.${target.presetName}")?.let { NativeCacheKind.byCompilerArgument(it) }
property("kotlin.native.cacheKind.${target.presetName}").orNull?.let { NativeCacheKind.byCompilerArgument(it) }
/**
* Dependencies caching orchestration machinery.
*/
val nativeCacheOrchestration: NativeCacheOrchestration?
get() = this.property(PropertyNames.KOTLIN_NATIVE_CACHE_ORCHESTRATION)?.let { NativeCacheOrchestration.byCompilerArgument(it) }
get() = property(PropertyNames.KOTLIN_NATIVE_CACHE_ORCHESTRATION).orNull?.let { NativeCacheOrchestration.byCompilerArgument(it) }
/**
* Native backend threads.
*/
val nativeParallelThreads: Int?
get() = this.property(PropertyNames.KOTLIN_NATIVE_PARALLEL_THREADS)?.toInt()
get() = this.property(PropertyNames.KOTLIN_NATIVE_PARALLEL_THREADS).orNull?.toInt()
/**
* Ignore overflow in [org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessageOutputStreamHandler]
@@ -441,7 +432,7 @@ internal class PropertiesProvider private constructor(private val project: Proje
* Use Kotlin/JS backend compiler type
*/
val jsCompiler: KotlinJsCompilerType?
get() = this.property(jsCompilerProperty)?.let { KotlinJsCompilerType.byArgumentOrNull(it) }
get() = this.property(jsCompilerProperty).orNull?.let { KotlinJsCompilerType.byArgumentOrNull(it) }
/**
* Use Kotlin/JS backend compiler publishing attribute
@@ -480,11 +471,11 @@ internal class PropertiesProvider private constructor(private val project: Proje
)
val kotlinDaemonJvmArgs: String?
get() = this.property("kotlin.daemon.jvmargs")
get() = property("kotlin.daemon.jvmargs").orNull
val kotlinCompilerExecutionStrategy: KotlinCompilerExecutionStrategy
get() = KotlinCompilerExecutionStrategy.fromProperty(
this.property("kotlin.compiler.execution.strategy")?.toLowerCaseAsciiOnly()
this.property("kotlin.compiler.execution.strategy").orNull?.toLowerCaseAsciiOnly()
)
val kotlinDaemonUseFallbackStrategy: Boolean
@@ -534,10 +525,10 @@ internal class PropertiesProvider private constructor(private val project: Proje
get() = booleanProperty(KOTLIN_INTERNAL_DIAGNOSTICS_SHOW_STACKTRACE)
val suppressedGradlePluginWarnings: List<String>
get() = property(PropertyNames.KOTLIN_SUPPRESS_GRADLE_PLUGIN_WARNINGS)?.split(",").orEmpty()
get() = property(PropertyNames.KOTLIN_SUPPRESS_GRADLE_PLUGIN_WARNINGS).orNull?.split(",").orEmpty()
val suppressedGradlePluginErrors: List<String>
get() = property(PropertyNames.KOTLIN_SUPPRESS_GRADLE_PLUGIN_ERRORS)?.split(",").orEmpty()
get() = property(PropertyNames.KOTLIN_SUPPRESS_GRADLE_PLUGIN_ERRORS).orNull?.split(",").orEmpty()
val suppressExperimentalArtifactsDslWarning: Boolean
get() = booleanProperty(KOTLIN_NATIVE_SUPPRESS_EXPERIMENTAL_ARTIFACTS_DSL_WARNING) ?: false
@@ -547,7 +538,7 @@ internal class PropertiesProvider private constructor(private val project: Proje
* This property takes precedence over the 'KONAN_DATA_DIR' environment variable.
*/
val konanDataDir: String?
get() = property(PropertyNames.KONAN_DATA_DIR)
get() = property(PropertyNames.KONAN_DATA_DIR).orNull
/**
* Allows suppressing the diagnostic [KotlinToolingDiagnostics.BuildToolsApiVersionInconsistency].
@@ -561,49 +552,37 @@ internal class PropertiesProvider private constructor(private val project: Proje
* @see KOTLIN_JS_KARMA_BROWSERS
*/
fun jsKarmaBrowsers(target: KotlinTarget? = null): String? =
target?.name?.prefixIfNot("$KOTLIN_JS_KARMA_BROWSERS.")?.let(::property) ?: property(KOTLIN_JS_KARMA_BROWSERS)
target?.name?.prefixIfNot("$KOTLIN_JS_KARMA_BROWSERS.")?.let { property(it).orNull }
?: property(KOTLIN_JS_KARMA_BROWSERS).orNull
private fun propertyWithDeprecatedVariant(propName: String, deprecatedPropName: String): String? {
val deprecatedProperty = this.property(deprecatedPropName)
val deprecatedProperty = property(deprecatedPropName).orNull
if (deprecatedProperty != null) {
project.reportDiagnosticOncePerBuild(KotlinToolingDiagnostics.DeprecatedPropertyWithReplacement(deprecatedProperty, propName))
}
return this.property(propName) ?: deprecatedProperty
return property(propName).orNull ?: deprecatedProperty
}
private fun booleanProperty(propName: String): Boolean? =
this.property(propName)?.toBoolean()
property(propName).orNull?.toBoolean()
private inline fun <reified T : Enum<T>> enumProperty(
propName: String,
defaultValue: T,
): T = this.property(propName)?.let { enumValueOf<T>(it.toUpperCaseAsciiOnly()) } ?: defaultValue
): T = this.property(propName).orNull?.let { enumValueOf<T>(it.toUpperCaseAsciiOnly()) } ?: defaultValue
/**
* Looks up the property in the following sources with decreasing priority:
* 1. Project properties (-P, gradle.properties, etc...)
* 2. `local.properties`
*
* Please prefer using dedicated properties for proper defaults handling.
* Use this API only if you specifically need declared project properties disregarding defaults.
*/
@UnsafeApi
internal fun property(propName: String): String? =
if (project.hasProperty(propName)) {
project.property(propName) as? String
} else {
localProperties.getProperty(propName)
}
private val localProperties = project.localProperties
internal fun property(propName: String): Provider<String> = project.loadProperty(propName, localProperties)
private fun propertiesWithPrefix(prefix: String): Map<String, String> {
val result: MutableMap<String, String> = mutableMapOf()
project.properties.forEach { (name, value) ->
if (name.startsWith(prefix) && value is String) {
result.put(name, value)
result[name] = value
}
}
localProperties.forEach { (name, value) ->
if (name is String && name.startsWith(prefix) && value is String) {
localProperties.orNull?.forEach { (name, value) ->
if (name.startsWith(prefix)) {
// Project properties have higher priority.
result.putIfAbsent(name, value)
}
@@ -12,15 +12,13 @@ import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinGradleProjectChecker
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinGradleProjectCheckerContext
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnosticsCollector
import org.jetbrains.kotlin.tooling.core.UnsafeApi
internal object InternalGradlePropertiesUsageChecker : KotlinGradleProjectChecker {
override suspend fun KotlinGradleProjectCheckerContext.runChecks(collector: KotlinToolingDiagnosticsCollector) {
KotlinPluginLifecycle.Stage.ReadyForExecution.await()
val internalPropertiesUsed = PropertiesProvider.PropertyNames.allInternalProperties().filter { name ->
@OptIn(UnsafeApi::class)
kotlinPropertiesProvider.property(name) != null
kotlinPropertiesProvider.property(name).orNull != null
}
val internalPropertiesFiltered = internalPropertiesUsed.minus(PropertiesProvider.PropertyNames.MPP_13X_FLAGS_SET_BY_PLUGIN)
if (internalPropertiesFiltered.isEmpty()) return
@@ -0,0 +1,52 @@
/*
* Copyright 2010-2023 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.plugin.internal
import org.gradle.api.Describable
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.ValueSource
import org.gradle.api.provider.ValueSourceParameters
import java.util.*
/**
* Allow loading a properties file content in configuration cache and project isolation compatible way by specifying
* [Parameters.propertiesFile].
*
* Returned type is `Map<String, String>` due to the following [bug in Gradle](https://github.com/gradle/gradle/pull/24846) which
* prevents proper serialization of [Properties] type.
*
* If the file does not exist - returned provider will be empty.
*
* Usage:
* ```
* project
* .providers
* .of(CustomFileValueSource::class.java) {
* it.parameters.propertiesFile.set(project.layout.projectDirectory.file("my-properties-file-to-load"))
* }
* ```
*/
internal abstract class CustomPropertiesFileValueSource : ValueSource<Map<String, String>, CustomPropertiesFileValueSource.Parameters>,
Describable {
interface Parameters : ValueSourceParameters {
val propertiesFile: RegularFileProperty
}
override fun getDisplayName(): String = "properties file ${parameters.propertiesFile.get().asFile.absolutePath}"
override fun obtain(): Map<String, String>? {
val customFile = parameters.propertiesFile.get().asFile
return if (customFile.exists()) {
customFile.bufferedReader().use {
@Suppress("UNCHECKED_CAST")
Properties().apply { load(it) }.toMap() as Map<String, String>
}
} else {
null
}
}
}
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLI
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_NATIVE_DEPENDENCY_PROPAGATION
import org.jetbrains.kotlin.gradle.plugin.diagnostics.KotlinToolingDiagnostics
import org.jetbrains.kotlin.gradle.plugin.diagnostics.kotlinToolingDiagnosticsCollector
import org.jetbrains.kotlin.tooling.core.UnsafeApi
internal fun runDeprecationDiagnostics(project: Project) {
checkAndReportDeprecatedMppProperties(project)
@@ -32,8 +31,7 @@ private fun checkAndReportDeprecatedMppProperties(project: Project) {
if (propertyName in propertiesSetByPlugin && projectProperties.mpp13XFlagsSetByPlugin)
return@mapNotNull null
@OptIn(UnsafeApi::class)
propertyName.takeIf { projectProperties.property(propertyName) != null }
propertyName.takeIf { projectProperties.property(propertyName).orNull != null }
}
if (usedProperties.isEmpty()) return
@@ -9,16 +9,16 @@ import org.gradle.api.Project
import org.gradle.api.file.Directory
import org.gradle.api.file.RegularFile
import org.gradle.api.provider.Provider
import org.jetbrains.kotlin.gradle.plugin.extraProperties
import org.jetbrains.kotlin.gradle.plugin.getOrNull
import org.jetbrains.kotlin.gradle.plugin.internal.CustomPropertiesFileValueSource
import org.jetbrains.kotlin.gradle.plugin.internal.configurationTimePropertiesAccessor
import org.jetbrains.kotlin.gradle.plugin.internal.usedAtConfigurationTime
import java.io.File
import java.io.IOException
import java.nio.file.Files
import java.nio.file.Paths
internal fun File.isJavaFile() =
extension.equals("java", ignoreCase = true)
internal fun File.isKotlinFile(sourceFilesExtensions: List<String>): Boolean =
!isJavaFile() && sourceFilesExtensions.any { it.equals(extension, ignoreCase = true) }
import java.util.*
/**
* Create all possible case-sensitive permutations for given [String].
@@ -52,9 +52,6 @@ internal fun File.relativeOrAbsolute(base: File): String =
internal fun Iterable<File>.pathsAsStringRelativeTo(base: File): String =
map { it.relativeOrAbsolute(base) }.sorted().joinToString()
internal fun File.relativeToRoot(project: Project): String =
relativeOrAbsolute(project.rootProject.rootDir)
internal fun Iterable<File>.toPathsArray(): Array<String> =
map { it.normalize().absolutePath }.toTypedArray()
@@ -89,22 +86,13 @@ internal fun File.absolutePathWithoutExtension(): String =
internal fun File.listFilesOrEmpty() = (if (exists()) listFiles() else null).orEmpty()
internal inline fun <T> withTemporaryDirectory(prefix: String, action: (directory: File) -> T): T {
val directory = Files.createTempDirectory(prefix).toFile()
return try {
action(directory)
} finally {
directory.deleteRecursively()
}
}
fun contentEquals(file1: File, file2: File): Boolean {
file1.useLines { seq1 ->
file2.useLines { seq2 ->
val iterator1 = seq1.iterator()
val iterator2 = seq2.iterator()
while(iterator1.hasNext() == iterator2.hasNext()) {
while (iterator1.hasNext() == iterator2.hasNext()) {
if (!iterator1.hasNext()) return true
@@ -130,7 +118,6 @@ internal fun Provider<RegularFile>.getFile(): File = get().asFile
@JvmName("getDirectoryAsFile") // avoids jvm signature clash
internal fun Provider<Directory>.getFile(): File = get().asFile
/**
* Checks if the file exists, taking into account compatibility with different versions of Gradle.
* It should be used instead of [File.exists] in checking UPD inputs. See KT-54232 for more info.
@@ -144,4 +131,43 @@ internal fun File.existsCompat(): Boolean =
true
} else {
exists()
}
}
/**
* Looks up the property in the following sources with decreasing priority:
* 1. Current project extra properties
* 2. Project Gradle properties (-P, gradle.properties, etc...)
* 3. `local.properties` file located in the rootDir
*
* If multiple properties are loaded from a same caller, it is better to cache `localProperties` into local variable.
*/
internal fun Project.loadProperty(
propName: String,
localPropertiesProvider: Provider<Map<String, String>> = localProperties
): Provider<String> = providers
.provider<String> {
extraProperties.getOrNull(propName) as? String
}
.orElse(
project.providers
.gradleProperty(propName)
.usedAtConfigurationTime(configurationTimePropertiesAccessor)
)
.orElse(
@Suppress("TYPE_MISMATCH")
localPropertiesProvider.map { it[propName] }
)
/**
* Loads 'local.properties' file content as [Properties].
*
* If it does not exist, returned [Provider] will be empty.
*/
internal val Project.localProperties: Provider<Map<String, String>>
get() = providers
.of(CustomPropertiesFileValueSource::class.java) {
it.parameters.propertiesFile.set(
project.rootDir.resolve("local.properties")
)
}
.usedAtConfigurationTime(configurationTimePropertiesAccessor)
@@ -20,14 +20,20 @@ import kotlin.test.Test
import kotlin.test.fail
class KT60388PlainJvmDependingOnJvmWithJavaTest {
private val rootProject = buildProject {
allprojects { project -> project.enableDefaultStdlibDependency(false) }
}
private val rootProject = buildProject()
@Test
fun `test - plain jvm - depends on - jvm withJava`() {
val producer = buildProjectWithMPP(projectBuilder = { withName("producer").withParent(rootProject) })
val consumer = buildProjectWithJvm(projectBuilder = { withName("consumer").withParent(rootProject) })
val producer = buildProjectWithMPP(
projectBuilder = { withName("producer").withParent(rootProject) },
preApplyCode = {
enableDefaultStdlibDependency(false)
}
)
val consumer = buildProjectWithJvm(
projectBuilder = { withName("consumer").withParent(rootProject) },
preApplyCode = { enableDefaultStdlibDependency(false) }
)
producer.multiplatformExtension.apply {
jvm().withJava()
@@ -44,8 +50,14 @@ class KT60388PlainJvmDependingOnJvmWithJavaTest {
@Test
fun `test - plain jvm - depends on - jvm withJava and java plugin`() {
val producer = buildProjectWithMPP(projectBuilder = { withName("producer").withParent(rootProject) })
val consumer = buildProjectWithJvm(projectBuilder = { withName("consumer").withParent(rootProject) })
val producer = buildProjectWithMPP(
projectBuilder = { withName("producer").withParent(rootProject) },
preApplyCode = { enableDefaultStdlibDependency(false) }
)
val consumer = buildProjectWithJvm(
projectBuilder = { withName("consumer").withParent(rootProject) },
preApplyCode = { enableDefaultStdlibDependency(false) }
)
producer.multiplatformExtension.apply {
producer.plugins.apply("java")
@@ -37,7 +37,12 @@ fun buildProject(
.apply(configureProject)
.let { it as ProjectInternal }
fun buildProjectWithMPP(projectBuilder: ProjectBuilder.() -> Unit = { }, code: Project.() -> Unit = {}) = buildProject(projectBuilder) {
fun buildProjectWithMPP(
projectBuilder: ProjectBuilder.() -> Unit = { },
preApplyCode: Project.() -> Unit = {},
code: Project.() -> Unit = {}
) = buildProject(projectBuilder) {
preApplyCode()
project.applyMultiplatformPlugin()
disableLegacyWarning(project)
code()
@@ -48,7 +53,12 @@ fun buildProjectWithKPM(projectBuilder: ProjectBuilder.() -> Unit = { }, code: P
code()
}
fun buildProjectWithJvm(projectBuilder: ProjectBuilder.() -> Unit = {}, code: Project.() -> Unit = {}) = buildProject(projectBuilder) {
fun buildProjectWithJvm(
projectBuilder: ProjectBuilder.() -> Unit = {},
preApplyCode: Project.() -> Unit = {},
code: Project.() -> Unit = {}
) = buildProject(projectBuilder) {
preApplyCode()
project.applyKotlinJvmPlugin()
code()
}
@@ -131,8 +131,8 @@ open class KotlinPlatformAndroidPlugin : KotlinPlatformImplementationPluginBase(
open class KotlinPlatformCommonPlugin : KotlinPlatformPluginBase("common") {
override fun apply(project: Project) {
warnAboutKotlin12xMppDeprecation(project)
project.applyPlugin<KotlinCommonPluginWrapper>()
warnAboutKotlin12xMppDeprecation(project)
}
}
@@ -136,8 +136,8 @@ open class KotlinPlatformAndroidPlugin : KotlinPlatformImplementationPluginBase(
open class KotlinPlatformCommonPlugin : KotlinPlatformPluginBase("common") {
override fun apply(project: Project) {
warnAboutKotlin12xMppDeprecation(project)
project.applyPlugin<KotlinCommonPluginWrapper>()
warnAboutKotlin12xMppDeprecation(project)
}
}
@@ -134,8 +134,8 @@ open class KotlinPlatformAndroidPlugin : KotlinPlatformImplementationPluginBase(
open class KotlinPlatformCommonPlugin : KotlinPlatformPluginBase("common") {
override fun apply(project: Project) {
warnAboutKotlin12xMppDeprecation(project)
project.applyPlugin<KotlinCommonPluginWrapper>()
warnAboutKotlin12xMppDeprecation(project)
}
}
@@ -133,8 +133,8 @@ open class KotlinPlatformAndroidPlugin : KotlinPlatformImplementationPluginBase(
open class KotlinPlatformCommonPlugin : KotlinPlatformPluginBase("common") {
override fun apply(project: Project) {
warnAboutKotlin12xMppDeprecation(project)
project.applyPlugin<KotlinCommonPluginWrapper>()
warnAboutKotlin12xMppDeprecation(project)
}
}
@@ -133,8 +133,8 @@ open class KotlinPlatformAndroidPlugin : KotlinPlatformImplementationPluginBase(
open class KotlinPlatformCommonPlugin : KotlinPlatformPluginBase("common") {
override fun apply(project: Project) {
warnAboutKotlin12xMppDeprecation(project)
project.applyPlugin<KotlinCommonPluginWrapper>()
warnAboutKotlin12xMppDeprecation(project)
}
}
@@ -133,8 +133,8 @@ open class KotlinPlatformAndroidPlugin : KotlinPlatformImplementationPluginBase(
open class KotlinPlatformCommonPlugin : KotlinPlatformPluginBase("common") {
override fun apply(project: Project) {
warnAboutKotlin12xMppDeprecation(project)
project.applyPlugin<KotlinCommonPluginWrapper>()
warnAboutKotlin12xMppDeprecation(project)
}
}
@@ -133,8 +133,8 @@ open class KotlinPlatformAndroidPlugin : KotlinPlatformImplementationPluginBase(
open class KotlinPlatformCommonPlugin : KotlinPlatformPluginBase("common") {
override fun apply(project: Project) {
warnAboutKotlin12xMppDeprecation(project)
project.applyPlugin<KotlinCommonPluginWrapper>()
warnAboutKotlin12xMppDeprecation(project)
}
}
@@ -135,8 +135,8 @@ open class KotlinPlatformAndroidPlugin : KotlinPlatformImplementationPluginBase(
open class KotlinPlatformCommonPlugin : KotlinPlatformPluginBase("common") {
override fun apply(project: Project) {
warnAboutKotlin12xMppDeprecation(project)
project.applyPlugin<KotlinCommonPluginWrapper>()
warnAboutKotlin12xMppDeprecation(project)
}
}