From a6e488e2b4e0a76b13998e2927fe2b4377db39b5 Mon Sep 17 00:00:00 2001 From: Vyacheslav Karpukhin Date: Thu, 7 Nov 2019 20:18:37 +0100 Subject: [PATCH] Android import: simplified configuration matching --- .../dsl/KotlinMultiplatformExtension.kt | 55 +++++-------------- .../kotlin/gradle/plugin/KotlinPlugin.kt | 30 +++++++--- .../android/Android25ProjectHandler.kt | 21 +------ .../targets/android/KotlinAndroidTarget.kt | 4 +- .../android/internal/AndroidSubplugin.kt | 2 +- 5 files changed, 43 insertions(+), 69 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinMultiplatformExtension.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinMultiplatformExtension.kt index acc4fca91a6..6e947c242fe 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinMultiplatformExtension.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinMultiplatformExtension.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.gradle.dsl import com.android.build.gradle.BaseExtension +import com.android.build.gradle.api.AndroidSourceSet import com.android.build.gradle.internal.LoggerWrapper import com.android.build.gradle.internal.SdkLocationSourceSet import com.android.build.gradle.internal.SdkLocator @@ -27,7 +28,6 @@ import org.gradle.internal.component.external.model.DefaultModuleComponentIdenti import org.gradle.util.ConfigureUtil import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.mpp.* -import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import java.io.File @@ -82,24 +82,27 @@ open class KotlinMultiplatformExtension : } fun getAndroidSourceSetDependencies(project: Project): Map?> { - val ext = project.extensions.getByName("android") as BaseExtension + data class SourceSetConfigs(val implConfig: Configuration, val compileConfig: Configuration) + val androidSdkJar = getAndroidSdkJar(project) ?: return emptyMap() + val sourceSet2Impl = HashMap() + val allImplConfigs = HashSet() - val sourceSet2Impl = ext.sourceSets.map { - lowerCamelCaseName("android", it.name) to project.configurations.getByName(it.implementationConfigurationName) - }.toMap() - - val allImplConfigs = sourceSet2Impl.values.toSet() - val impl2CompileClasspath = mapImplementationToCompileClasspathConfiguration(project, allImplConfigs) + project.forEachVariant { variant -> + val compileConfig = variant.compileConfiguration + variant.sourceSets.filterIsInstance(AndroidSourceSet::class.java).map { + val implConfig = project.configurations.getByName(it.implementationConfigurationName) + allImplConfigs.add(implConfig) + sourceSet2Impl[lowerCamelCaseName("android", it.name)] = SourceSetConfigs(implConfig, compileConfig) + } + } return sourceSet2Impl.mapValues { entry -> - val compileClasspathConf = impl2CompileClasspath[entry.value] ?: return@mapValues null - - val dependencies = findDependencies(allImplConfigs, entry.value) + val dependencies = findDependencies(allImplConfigs, entry.value.implConfig) val selfResolved = dependencies.filterIsInstance().flatMap { it.resolve() } val resolvedExternal = dependencies.filterIsInstance() - .flatMap { collectDependencies(it.module, compileClasspathConf) } + .flatMap { collectDependencies(it.module, entry.value.compileConfig) } val result = (selfResolved + resolvedExternal + androidSdkJar).toMutableList() @@ -162,34 +165,6 @@ open class KotlinMultiplatformExtension : result.addAll(configs.flatMap { it.dependencies }) doFindDependencies(implConfigs, configs.flatMap { it.extendsFrom }.filter { it !in implConfigs && visited.add(it) }, result) } - - private fun mapImplementationToCompileClasspathConfiguration( - project: Project, - allImplConfigs: Set - ): Map { - val compileClasspathConfigurations = project.configurations.filter { it.name.endsWith("CompileClasspath", true) } - return compileClasspathConfigurations.flatMap { ccConf -> - findImplementationConfigurations(allImplConfigs, ccConf).map { it to ccConf } - }.toMap() - } - - private fun findImplementationConfigurations( - allImplConfigs: Set, - compileClasspathConf: Configuration - ): Set { - return HashSet().also { doFindImplementationConfigurations(allImplConfigs, listOf(compileClasspathConf), it) } - } - - private tailrec fun doFindImplementationConfigurations( - allImplConfigs: Set, - conf: List, - result: MutableSet, - visited: MutableSet = HashSet() - ) { - if (conf.isEmpty()) return - result.addAll(conf.flatMap { it.extendsFrom.filter { newConf -> allImplConfigs.contains(newConf) } }) - doFindImplementationConfigurations(allImplConfigs, conf.flatMap { it.extendsFrom }.filter { visited.add(it) }, result) - } } internal fun KotlinTarget.isProducedFromPreset(kotlinTargetPreset: KotlinTargetPreset<*>): Boolean = diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt index 155e2a615a4..6967638d085 100755 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt @@ -1,7 +1,6 @@ package org.jetbrains.kotlin.gradle.plugin -import com.android.build.gradle.BaseExtension -import com.android.build.gradle.BasePlugin +import com.android.build.gradle.* import com.android.build.gradle.api.AndroidSourceSet import com.android.build.gradle.api.BaseVariant import com.android.builder.model.SourceProvider @@ -707,7 +706,6 @@ class KotlinConfigurationTools internal constructor( abstract class AbstractAndroidProjectHandler(private val kotlinConfigurationTools: KotlinConfigurationTools) { protected val logger = Logging.getLogger(this.javaClass) - abstract fun forEachVariant(project: Project, action: (BaseVariant) -> Unit): Unit abstract fun getResDirectories(variantData: BaseVariant): FileCollection abstract fun getFlavorNames(variant: BaseVariant): List abstract fun getBuildTypeName(variant: BaseVariant): String @@ -781,7 +779,7 @@ abstract class AbstractAndroidProjectHandler(private val kotlinConfigurationTool androidPluginIds.joinToString("\n\t") { "* $it" }) } - forEachVariant(project) { variant -> + project.forEachVariant { variant -> val variantName = getVariantName(variant) // Create the compilation and configure it first, then add to the compilations container. As this code is executed @@ -801,7 +799,7 @@ abstract class AbstractAndroidProjectHandler(private val kotlinConfigurationTool } project.whenEvaluated { - forEachVariant(project) { variant -> + forEachVariant { variant -> val compilation = kotlinAndroidTarget.compilations.getByName(getVariantName(variant)) postprocessVariant(variant, compilation, project, ext, plugin) @@ -868,7 +866,7 @@ abstract class AbstractAndroidProjectHandler(private val kotlinConfigurationTool if (kotlinAndroidTarget.disambiguationClassifier != null) { val sourceSetToVariants = mutableMapOf>().apply { - forEachVariant(project) { variant -> + project.forEachVariant { variant -> for (sourceSet in getSourceProviders(variant)) { val androidSourceSet = sourceSet as? AndroidSourceSet ?: continue getOrPut(androidSourceSet) { mutableListOf() }.add(variant) @@ -1144,4 +1142,22 @@ internal fun compareVersionNumbers(v1: String?, v2: String?): Int { } return 0 } -} \ No newline at end of file +} + +internal fun Project.forEachVariant(action: (BaseVariant) -> Unit) { + val androidExtension = this.extensions.getByName("android") + when (androidExtension) { + is AppExtension -> androidExtension.applicationVariants.all(action) + is LibraryExtension -> { + androidExtension.libraryVariants.all(action) + if (androidExtension is FeatureExtension) { + androidExtension.featureVariants.all(action) + } + } + is TestExtension -> androidExtension.applicationVariants.all(action) + } + if (androidExtension is TestedExtension) { + androidExtension.testVariants.all(action) + androidExtension.unitTestVariants.all(action) + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/android/Android25ProjectHandler.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/android/Android25ProjectHandler.kt index e36c8ccfcef..b014b3d8381 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/android/Android25ProjectHandler.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/android/Android25ProjectHandler.kt @@ -6,7 +6,8 @@ @file:Suppress("PackageDirectoryMismatch") // Old package for compatibility package org.jetbrains.kotlin.gradle.plugin -import com.android.build.gradle.* +import com.android.build.gradle.BaseExtension +import com.android.build.gradle.BasePlugin import com.android.build.gradle.api.* import com.android.build.gradle.tasks.MergeResources import com.android.builder.model.SourceProvider @@ -29,24 +30,6 @@ class Android25ProjectHandler( kotlinConfigurationTools: KotlinConfigurationTools ) : AbstractAndroidProjectHandler(kotlinConfigurationTools) { - override fun forEachVariant(project: Project, action: (BaseVariant) -> Unit) { - val androidExtension = project.extensions.getByName("android") - when (androidExtension) { - is AppExtension -> androidExtension.applicationVariants.all(action) - is LibraryExtension -> { - androidExtension.libraryVariants.all(action) - if (androidExtension is FeatureExtension) { - androidExtension.featureVariants.all(action) - } - } - is TestExtension -> androidExtension.applicationVariants.all(action) - } - if (androidExtension is TestedExtension) { - androidExtension.testVariants.all(action) - androidExtension.unitTestVariants.all(action) - } - } - override fun wireKotlinTasks( project: Project, compilation: KotlinJvmAndroidCompilation, diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/android/KotlinAndroidTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/android/KotlinAndroidTarget.kt index 1aa6f617d50..d7c80ae6f4c 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/android/KotlinAndroidTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/android/KotlinAndroidTarget.kt @@ -64,7 +64,7 @@ open class KotlinAndroidTarget( private fun checkPublishLibraryVariantsExist() { fun AbstractAndroidProjectHandler.getLibraryVariantNames() = mutableSetOf().apply { - forEachVariant(project) { + project.forEachVariant { if (getLibraryOutputTask(it) != null) add(getVariantName(it)) } @@ -94,7 +94,7 @@ open class KotlinAndroidTarget( private fun AbstractAndroidProjectHandler.doCreateComponents(): Set { val publishableVariants = mutableListOf() - .apply { forEachVariant(project) { add(it) } } + .apply { project.forEachVariant { add(it) } } .toList() // Defensive copy against unlikely modification by the lambda that captures the list above in forEachVariant { } .filter { getLibraryOutputTask(it) != null && publishLibraryVariants?.contains(getVariantName(it)) ?: true } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/android/internal/AndroidSubplugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/android/internal/AndroidSubplugin.kt index 955e8ff5dbc..8df1cdb4010 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/android/internal/AndroidSubplugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/android/internal/AndroidSubplugin.kt @@ -208,7 +208,7 @@ class AndroidSubplugin : KotlinGradleSubplugin { val resDirectoriesForAllVariants = mutableListOf() - androidProjectHandler.forEachVariant(project) { variant -> + project.forEachVariant { variant -> if (getTestedVariantData(variant) != null) return@forEachVariant resDirectoriesForAllVariants += androidProjectHandler.getResDirectories(variant) }