Import 'implement' dependency of platform project transitively

#KT-16926 fixed
This commit is contained in:
Alexey Tsvetkov
2017-03-24 18:51:54 +03:00
parent e9c47d6498
commit 54ee779ba1
3 changed files with 120 additions and 15 deletions
@@ -25,23 +25,25 @@ import java.io.Serializable
import java.lang.Exception
import java.lang.reflect.InvocationTargetException
import java.lang.reflect.Method
import java.util.*
import kotlin.collections.HashSet
typealias CompilerArgumentsBySourceSet = Map<String, List<String>>
interface KotlinGradleModel : Serializable {
val implements: String?
val currentCompilerArgumentsBySourceSet: CompilerArgumentsBySourceSet
val defaultCompilerArgumentsBySourceSet: CompilerArgumentsBySourceSet
val coroutines: String?
val platformPluginId: String?
val transitiveCommonDependencies: Set<String>
}
class KotlinGradleModelImpl(
override val implements: String?,
override val currentCompilerArgumentsBySourceSet: CompilerArgumentsBySourceSet,
override val defaultCompilerArgumentsBySourceSet: CompilerArgumentsBySourceSet,
override val coroutines: String?,
override val platformPluginId: String?
override val platformPluginId: String?,
override val transitiveCommonDependencies: Set<String>
) : KotlinGradleModel
class KotlinGradleModelBuilder : ModelBuilderService {
@@ -53,6 +55,7 @@ class KotlinGradleModelBuilder : ModelBuilderService {
"kotlin" to "kotlin-platform-jvm",
"kotlin2js" to "kotlin-platform-js"
)
private val kotlinPlatformCommonPluginId = "kotlin-platform-common"
}
override fun getErrorMessageBuilder(project: Project, e: Exception): ErrorMessageBuilder {
@@ -61,13 +64,41 @@ class KotlinGradleModelBuilder : ModelBuilderService {
override fun canBuild(modelName: String?): Boolean = modelName == KotlinGradleModel::class.java.name
private fun getImplements(project: Project): String? {
val implementsConfiguration = project.configurations.findByName("implement")
if (implementsConfiguration != null) {
val implementsProjectDependency = implementsConfiguration.dependencies.filterIsInstance<ProjectDependency>().firstOrNull()
if (implementsProjectDependency != null) return implementsProjectDependency.dependencyProject.path
private fun getImplements(project: Project): Project? {
val implementsConfiguration = project.configurations.findByName("implement") ?: return null
val implementsProjectDependency = implementsConfiguration.dependencies.filterIsInstance<ProjectDependency>().firstOrNull()
return implementsProjectDependency?.dependencyProject
}
private fun transitiveCommonDependencies(startingProject: Project): Set<String> {
val toProcess = LinkedList<Project>()
toProcess.add(startingProject)
val processed = HashSet<String>()
val result = HashSet<String>()
result.add(startingProject.path)
while (toProcess.isNotEmpty()) {
val project = toProcess.pollFirst()
processed.add(project.path)
if (!project.plugins.hasPlugin(kotlinPlatformCommonPluginId)) continue
result.add(project.path)
val compileConfiguration = project.configurations.findByName("compile") ?: continue
val dependencies = compileConfiguration
.dependencies
.filterIsInstance<ProjectDependency>()
.map { it.dependencyProject }
for (dep in dependencies) {
if (dep.path !in processed) {
toProcess.add(dep)
}
}
}
return null
return result
}
private fun Class<*>.findGetterMethod(name: String): Method? {
@@ -132,13 +163,14 @@ class KotlinGradleModelBuilder : ModelBuilderService {
val platform = platformPluginIds.singleOrNull { project.plugins.findPlugin(it) != null }
?: pluginToPlatform.entries.singleOrNull { project.plugins.findPlugin(it.key) != null }?.value
val transitiveCommon = getImplements(project)?.let { transitiveCommonDependencies(it) } ?: emptySet()
return KotlinGradleModelImpl(
getImplements(project),
currentCompilerArgumentsBySourceSet,
defaultCompilerArgumentsBySourceSet,
getCoroutines(project),
platform
platform,
transitiveCommon
)
}
}
@@ -57,7 +57,7 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
ideProject: DataNode<ProjectData>) {
val gradleModel = resolverCtx.getExtraProject(gradleModule, KotlinGradleModel::class.java) ?: return
gradleModel.implements?.let { implementsModuleId ->
gradleModel.transitiveCommonDependencies.forEach { implementsModuleId ->
val targetModule = findModule(ideProject, implementsModuleId) ?: return
if (resolverCtx.isResolveModulePerSourceSet) {
populateSourceSetDependencies(gradleModule, ideModule, targetModule)
@@ -25,13 +25,11 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
fun testPlatformToCommonDependency() {
createProjectSubFile("settings.gradle", "include ':common', ':jvm', ':js'")
val kotlinVersion = "1.1-M04"
val kotlinRepo = "maven { url 'http://dl.bintray.com/kotlin/kotlin-eap-1.1' }"
val kotlinVersion = "1.1.0"
createProjectSubFile("build.gradle", """
buildscript {
repositories {
$kotlinRepo
mavenCentral()
}
@@ -67,4 +65,79 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
assertModuleModuleDepScope("js_main", "common_main", DependencyScope.COMPILE)
assertModuleModuleDepScope("js_test", "common_test", DependencyScope.COMPILE)
}
@Test
fun testMultiProject() {
createProjectSubFile("settings.gradle", "include ':common-lib', ':jvm-lib', ':js-lib', ':common-app', ':jvm-app', ':js-app'")
val kotlinVersion = "1.1.0"
createProjectSubFile("build.gradle", """
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
}
}
project('common-lib') {
apply plugin: 'kotlin-platform-common'
}
project('jvm-lib') {
apply plugin: 'kotlin-platform-jvm'
dependencies {
implement project(':common-lib')
}
}
project('js-lib') {
apply plugin: 'kotlin-platform-js'
dependencies {
implement project(':common-lib')
}
}
project('common-app') {
apply plugin: 'kotlin-platform-common'
dependencies {
compile project(':common-lib')
}
}
project('jvm-app') {
apply plugin: 'kotlin-platform-jvm'
dependencies {
implement project(':common-app')
compile project(':jvm-lib')
}
}
project('js-app') {
apply plugin: 'kotlin-platform-js'
dependencies {
implement project(':common-app')
compile project(':js-lib')
}
}
""")
importProject()
assertModuleModuleDepScope("jvm-app_main", "common-app_main", DependencyScope.COMPILE)
assertModuleModuleDepScope("jvm-app_main", "common-lib_main", DependencyScope.COMPILE)
assertModuleModuleDepScope("jvm-app_main", "jvm-lib_main", DependencyScope.COMPILE)
assertModuleModuleDepScope("js-app_main", "common-app_main", DependencyScope.COMPILE)
assertModuleModuleDepScope("js-app_main", "common-lib_main", DependencyScope.COMPILE)
assertModuleModuleDepScope("js-app_main", "js-lib_main", DependencyScope.COMPILE)
}
}