kotlin-android plugin: use VariantDataList instead of list of Variant.
Support junit tests Fix sourceRoot dependencies for productFlavors #KT-7065 Fixed #KT-7506 Fixed
This commit is contained in:
+42
-70
@@ -24,6 +24,9 @@ import com.android.build.gradle.BasePlugin
|
|||||||
import com.android.build.gradle.api.LibraryVariant
|
import com.android.build.gradle.api.LibraryVariant
|
||||||
import com.android.build.gradle.api.ApkVariant
|
import com.android.build.gradle.api.ApkVariant
|
||||||
import com.android.build.gradle.api.TestVariant
|
import com.android.build.gradle.api.TestVariant
|
||||||
|
import com.android.build.gradle.internal.variant.BaseVariantData
|
||||||
|
import com.android.build.gradle.internal.variant.BaseVariantOutputData
|
||||||
|
import com.android.builder.core.VariantType
|
||||||
import org.gradle.api.plugins.JavaPlugin
|
import org.gradle.api.plugins.JavaPlugin
|
||||||
import org.gradle.api.artifacts.dsl.DependencyHandler
|
import org.gradle.api.artifacts.dsl.DependencyHandler
|
||||||
import org.gradle.api.artifacts.ConfigurationContainer
|
import org.gradle.api.artifacts.ConfigurationContainer
|
||||||
@@ -35,6 +38,7 @@ import org.gradle.api.file.SourceDirectorySet
|
|||||||
import kotlin.properties.Delegates
|
import kotlin.properties.Delegates
|
||||||
import org.gradle.api.tasks.Delete
|
import org.gradle.api.tasks.Delete
|
||||||
import groovy.lang.Closure
|
import groovy.lang.Closure
|
||||||
|
import org.gradle.api.file.FileCollection
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
|
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
|
||||||
import java.util.ServiceLoader
|
import java.util.ServiceLoader
|
||||||
import org.gradle.api.logging.*
|
import org.gradle.api.logging.*
|
||||||
@@ -288,112 +292,81 @@ open class KotlinAndroidPlugin [Inject] (val scriptHandler: ScriptHandler, val t
|
|||||||
|
|
||||||
project afterEvaluate { project ->
|
project afterEvaluate { project ->
|
||||||
if (project != null) {
|
if (project != null) {
|
||||||
val testVariants = AndroidGradleWrapper.getTestVariants(ext)
|
val plugin = (project.getPlugins().findPlugin("android")
|
||||||
processVariants(testVariants, project, ext)
|
?: project.getPlugins().findPlugin("android-library")) as BasePlugin
|
||||||
if (ext is AppExtension) {
|
|
||||||
val appVariants = ext.getApplicationVariants()!!
|
|
||||||
processVariants(appVariants, project, ext)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ext is LibraryExtension) {
|
processVariantData(plugin.getVariantManager().getVariantDataList(), project, ext, plugin)
|
||||||
val libVariants = ext.getLibraryVariants()!!
|
|
||||||
processVariants(libVariants, project, ext)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
project.getExtensions().add(DEFAULT_ANNOTATIONS, GradleUtils(scriptHandler, project).resolveKotlinPluginDependency("kotlin-android-sdk-annotations"))
|
project.getExtensions().add(DEFAULT_ANNOTATIONS, GradleUtils(scriptHandler, project).resolveKotlinPluginDependency("kotlin-android-sdk-annotations"))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun processVariants(variants: DefaultDomainObjectSet<out BaseVariant>, project: Project, androidExt: BaseExtension): Unit {
|
private fun processVariantData(
|
||||||
|
variantDataList: List<BaseVariantData<out BaseVariantOutputData>>,
|
||||||
|
project: Project,
|
||||||
|
androidExt: BaseExtension,
|
||||||
|
androidPlugin: BasePlugin
|
||||||
|
) {
|
||||||
val logger = project.getLogger()
|
val logger = project.getLogger()
|
||||||
val kotlinOptions = getExtension<Any?>(androidExt, "kotlinOptions")
|
val kotlinOptions = getExtension<Any?>(androidExt, "kotlinOptions")
|
||||||
val sourceSets = androidExt.getSourceSets()
|
|
||||||
//TODO: change to BuilderConstants.MAIN - it was relocated in 0.11 plugin
|
|
||||||
val mainSourceSet = sourceSets.getByName("main")
|
|
||||||
val testSourceSet = try {
|
|
||||||
sourceSets.getByName("instrumentTest")
|
|
||||||
} catch (e: UnknownDomainObjectException) {
|
|
||||||
sourceSets.getByName("androidTest")
|
|
||||||
}
|
|
||||||
|
|
||||||
val subpluginEnvironment = loadSubplugins(project, logger)
|
val subpluginEnvironment = loadSubplugins(project, logger)
|
||||||
|
|
||||||
for (variant in variants) {
|
for (variantData in variantDataList) {
|
||||||
if (variant is LibraryVariant || variant is ApkVariant) {
|
val variantDataName = variantData.getName()
|
||||||
val buildTypeSourceSetName = AndroidGradleWrapper.getVariantName(variant)
|
logger.debug("Process variant [$variantDataName]")
|
||||||
|
|
||||||
logger.debug("Variant build type is [$buildTypeSourceSetName]")
|
val javaTask = variantData.javaCompileTask
|
||||||
val buildTypeSourceSet = sourceSets.findByName(buildTypeSourceSetName)
|
|
||||||
|
|
||||||
val javaTask = variant.getJavaCompile()!!
|
val kotlinTaskName = "compile${variantDataName.capitalize()}Kotlin"
|
||||||
val variantName = variant.getName()
|
|
||||||
|
|
||||||
val kotlinTaskName = "compile${variantName.capitalize()}Kotlin"
|
|
||||||
val kotlinTask = tasksProvider.createKotlinJVMTask(project, kotlinTaskName)
|
val kotlinTask = tasksProvider.createKotlinJVMTask(project, kotlinTaskName)
|
||||||
if (kotlinOptions != null) {
|
if (kotlinOptions != null) {
|
||||||
kotlinTask.setProperty("kotlinOptions", kotlinOptions)
|
kotlinTask.setProperty("kotlinOptions", kotlinOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
// store kotlin classes in separate directory. They will serve as class-path to java compiler
|
// store kotlin classes in separate directory. They will serve as class-path to java compiler
|
||||||
val kotlinOutputDir = File(project.getBuildDir(), "tmp/kotlin-classes/${variantName}")
|
val kotlinOutputDir = File(project.getBuildDir(), "tmp/kotlin-classes/${variantDataName}")
|
||||||
kotlinTask.setProperty("kotlinDestinationDir", kotlinOutputDir)
|
kotlinTask.setProperty("kotlinDestinationDir", kotlinOutputDir)
|
||||||
kotlinTask.setDestinationDir(javaTask.getDestinationDir())
|
kotlinTask.setDestinationDir(javaTask.getDestinationDir())
|
||||||
kotlinTask.setDescription("Compiles the ${variantName} kotlin.")
|
kotlinTask.setDescription("Compiles the ${variantDataName} kotlin.")
|
||||||
kotlinTask.setClasspath(javaTask.getClasspath())
|
kotlinTask.setClasspath(javaTask.getClasspath())
|
||||||
kotlinTask.setDependsOn(javaTask.getDependsOn())
|
kotlinTask.setDependsOn(javaTask.getDependsOn())
|
||||||
|
|
||||||
fun processSourceSet(javaSourceSet: AndroidSourceSet): SourceDirectorySet {
|
fun SourceDirectorySet.addSourceDirectories(additionalSourceFiles: Collection<File>) {
|
||||||
val javaSrcDirs = AndroidGradleWrapper.getJavaSrcDirs(javaSourceSet)
|
for (dir in additionalSourceFiles) {
|
||||||
val kotlinSourceSet = getExtension<KotlinSourceSet>(javaSourceSet, "kotlin")
|
this.srcDir(dir)
|
||||||
val kotlinSDS = kotlinSourceSet.getKotlin()
|
logger.debug("Source directory ${dir.getAbsolutePath()} was added to kotlin source for $kotlinTaskName")
|
||||||
for (dir in javaSrcDirs) {
|
|
||||||
kotlinSDS.srcDir(dir)
|
|
||||||
}
|
}
|
||||||
kotlinTask.source(kotlinSDS)
|
|
||||||
return kotlinSDS
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (variant is TestVariant) {
|
fun configureDefaultSourceSet() {
|
||||||
processSourceSet(testSourceSet)
|
val defaultSourceSet = variantData.getVariantConfiguration().getDefaultSourceSet()
|
||||||
} else {
|
val kotlinSourceDirectorySet = getExtension<KotlinSourceSet>(defaultSourceSet, "kotlin").getKotlin()
|
||||||
processSourceSet(mainSourceSet)
|
// getJavaSources should return the Java sources used for compilation
|
||||||
|
// We want to collect only generated files, like R-class output dir
|
||||||
|
// Actual java sources will be collected later
|
||||||
|
val additionalSourceFiles = variantData.getJavaSources().filterIsInstance(javaClass<File>())
|
||||||
|
kotlinSourceDirectorySet.addSourceDirectories(additionalSourceFiles)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buildTypeSourceSet != null) {
|
configureDefaultSourceSet()
|
||||||
val variantSourceDirectorySet = processSourceSet(buildTypeSourceSet)
|
|
||||||
for (resourceFolder in AndroidGradleWrapper.getRClassFolder(variant)) {
|
|
||||||
variantSourceDirectorySet.srcDir(resourceFolder)
|
|
||||||
}
|
|
||||||
variantSourceDirectorySet.srcDir(variant.getGenerateBuildConfig()?.getSourceOutputDir())
|
|
||||||
variantSourceDirectorySet.srcDir(variant.getAidlCompile().getSourceOutputDir())
|
|
||||||
variantSourceDirectorySet.srcDir(variant.getRenderscriptCompile().getSourceOutputDir())
|
|
||||||
}
|
|
||||||
|
|
||||||
if (variant is ApkVariant) {
|
// getSortedSourceProviders should return only actual java sources, generated sources should be collected earlier
|
||||||
for (flavourName in AndroidGradleWrapper.getProductFlavorsNames(variant)) {
|
val providers = variantData.getVariantConfiguration().getSortedSourceProviders()
|
||||||
val defaultFlavourSourceSetName = flavourName + buildTypeSourceSetName.capitalize()
|
for (provider in providers) {
|
||||||
val defaultFlavourSourceSet = sourceSets.findByName(defaultFlavourSourceSetName)
|
val javaSrcDirs = AndroidGradleWrapper.getJavaSrcDirs(provider as AndroidSourceSet)
|
||||||
if (defaultFlavourSourceSet != null) {
|
val kotlinSourceSet = getExtension<KotlinSourceSet>(provider, "kotlin")
|
||||||
processSourceSet(defaultFlavourSourceSet)
|
val kotlinSourceDirectorySet = kotlinSourceSet.getKotlin()
|
||||||
}
|
kotlinTask.source(kotlinSourceDirectorySet)
|
||||||
|
|
||||||
val flavourSourceSet = sourceSets.findByName(flavourName)
|
kotlinSourceDirectorySet.addSourceDirectories(javaSrcDirs)
|
||||||
if (flavourSourceSet != null) {
|
|
||||||
processSourceSet(flavourSourceSet)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
subpluginEnvironment.addSubpluginArguments(project, kotlinTask)
|
subpluginEnvironment.addSubpluginArguments(project, kotlinTask)
|
||||||
|
|
||||||
kotlinTask doFirst {
|
kotlinTask doFirst {
|
||||||
var plugin = project.getPlugins().findPlugin("android")
|
val androidRT = project.files(AndroidGradleWrapper.getRuntimeJars(androidPlugin, androidExt))
|
||||||
if (null == plugin) {
|
|
||||||
plugin = project.getPlugins().findPlugin("android-library")
|
|
||||||
}
|
|
||||||
val basePlugin: BasePlugin = plugin as BasePlugin
|
|
||||||
val androidRT = project.files(AndroidGradleWrapper.getRuntimeJars(basePlugin, androidExt))
|
|
||||||
val fullClasspath = (javaTask.getClasspath() + androidRT) - project.files(kotlinTask.property("kotlinDestinationDir"))
|
val fullClasspath = (javaTask.getClasspath() + androidRT) - project.files(kotlinTask.property("kotlinDestinationDir"))
|
||||||
(it as AbstractCompile).setClasspath(fullClasspath)
|
(it as AbstractCompile).setClasspath(fullClasspath)
|
||||||
}
|
}
|
||||||
@@ -405,7 +378,6 @@ open class KotlinAndroidPlugin [Inject] (val scriptHandler: ScriptHandler, val t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fun <T> getExtension(obj: Any, extensionName: String): T {
|
fun <T> getExtension(obj: Any, extensionName: String): T {
|
||||||
if (obj is ExtensionAware) {
|
if (obj is ExtensionAware) {
|
||||||
|
|||||||
Reference in New Issue
Block a user