Gradle: Import project dependency with non-default configuration by its artifacts
This commit is contained in:
+20
-12
@@ -25,6 +25,7 @@ import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
|||||||
import com.intellij.openapi.roots.DependencyScope
|
import com.intellij.openapi.roots.DependencyScope
|
||||||
import com.intellij.openapi.util.Key
|
import com.intellij.openapi.util.Key
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
|
import org.gradle.api.artifacts.Dependency
|
||||||
import org.gradle.tooling.model.idea.IdeaModule
|
import org.gradle.tooling.model.idea.IdeaModule
|
||||||
import org.jetbrains.kotlin.gradle.CompilerArgumentsBySourceSet
|
import org.jetbrains.kotlin.gradle.CompilerArgumentsBySourceSet
|
||||||
import org.jetbrains.kotlin.gradle.KotlinGradleModel
|
import org.jetbrains.kotlin.gradle.KotlinGradleModel
|
||||||
@@ -37,6 +38,7 @@ import org.jetbrains.plugins.gradle.model.FileCollectionDependency
|
|||||||
import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData
|
import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData
|
||||||
import org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension
|
import org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension
|
||||||
import org.jetbrains.plugins.gradle.service.project.GradleProjectResolver
|
import org.jetbrains.plugins.gradle.service.project.GradleProjectResolver
|
||||||
|
import java.io.File
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
var DataNode<ModuleData>.isResolved
|
var DataNode<ModuleData>.isResolved
|
||||||
@@ -84,6 +86,14 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
|
|||||||
|
|
||||||
val gradleIdeaProject = gradleModule.project
|
val gradleIdeaProject = gradleModule.project
|
||||||
|
|
||||||
|
fun getDependencyByFiles(files: Collection<File>) = files
|
||||||
|
.mapTo(HashSet()) {
|
||||||
|
val path = FileUtil.toSystemIndependentName(it.path)
|
||||||
|
val targetSourceSetId = outputToSourceSet?.get(path)?.first ?: return@mapTo null
|
||||||
|
sourceSetByName?.get(targetSourceSetId)?.first
|
||||||
|
}
|
||||||
|
.singleOrNull()
|
||||||
|
|
||||||
fun DataNode<out ModuleData>.getDependencies(): Collection<DataNode<out ModuleData>> {
|
fun DataNode<out ModuleData>.getDependencies(): Collection<DataNode<out ModuleData>> {
|
||||||
if (useModulePerSourceSet()) {
|
if (useModulePerSourceSet()) {
|
||||||
if (sourceSetByName == null) return emptySet()
|
if (sourceSetByName == null) return emptySet()
|
||||||
@@ -91,20 +101,18 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
|
|||||||
return externalSourceSet.dependencies.mapNotNullTo(LinkedHashSet()) { dependency ->
|
return externalSourceSet.dependencies.mapNotNullTo(LinkedHashSet()) { dependency ->
|
||||||
when (dependency) {
|
when (dependency) {
|
||||||
is ExternalProjectDependency -> {
|
is ExternalProjectDependency -> {
|
||||||
val targetModuleNode = ExternalSystemApiUtil.findFirstRecursively(ideProject) {
|
if (dependency.configurationName == Dependency.DEFAULT_CONFIGURATION) {
|
||||||
(it.data as? ModuleData)?.id == dependency.projectPath
|
val targetModuleNode = ExternalSystemApiUtil.findFirstRecursively(ideProject) {
|
||||||
} as DataNode<ModuleData>? ?: return@mapNotNullTo null
|
(it.data as? ModuleData)?.id == dependency.projectPath
|
||||||
ExternalSystemApiUtil.findAll(targetModuleNode, GradleSourceSetData.KEY)
|
} as DataNode<ModuleData>? ?: return@mapNotNullTo null
|
||||||
.firstOrNull { it.sourceSetName == "main" }
|
ExternalSystemApiUtil.findAll(targetModuleNode, GradleSourceSetData.KEY)
|
||||||
|
.firstOrNull { it.sourceSetName == "main" }
|
||||||
|
} else {
|
||||||
|
getDependencyByFiles(dependency.projectDependencyArtifacts)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
is FileCollectionDependency -> {
|
is FileCollectionDependency -> {
|
||||||
dependency.files
|
getDependencyByFiles(dependency.files)
|
||||||
.mapTo(HashSet()) {
|
|
||||||
val path = FileUtil.toSystemIndependentName(it.path)
|
|
||||||
val targetSourceSetId = outputToSourceSet?.get(path)?.first ?: return@mapTo null
|
|
||||||
sourceSetByName[targetSourceSetId]?.first
|
|
||||||
}
|
|
||||||
.singleOrNull()
|
|
||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|||||||
+114
@@ -17,6 +17,8 @@
|
|||||||
package org.jetbrains.kotlin.gradle
|
package org.jetbrains.kotlin.gradle
|
||||||
|
|
||||||
import com.intellij.openapi.roots.DependencyScope
|
import com.intellij.openapi.roots.DependencyScope
|
||||||
|
import com.intellij.openapi.roots.LibraryOrderEntry
|
||||||
|
import com.intellij.openapi.roots.OrderRootType
|
||||||
import com.intellij.util.PathUtil
|
import com.intellij.util.PathUtil
|
||||||
import junit.framework.TestCase
|
import junit.framework.TestCase
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.gradle.GradleImportingTestCase
|
import org.jetbrains.kotlin.idea.codeInsight.gradle.GradleImportingTestCase
|
||||||
@@ -26,6 +28,12 @@ import org.jetbrains.kotlin.test.KotlinTestUtils
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
class MultiplatformProjectImportingTest : GradleImportingTestCase() {
|
class MultiplatformProjectImportingTest : GradleImportingTestCase() {
|
||||||
|
private fun getDependencyLibraryUrls(moduleName: String) =
|
||||||
|
getRootManager(moduleName)
|
||||||
|
.orderEntries
|
||||||
|
.filterIsInstance<LibraryOrderEntry>()
|
||||||
|
.flatMap { it.getUrls(OrderRootType.CLASSES).map { it.replace(projectPath, "") } }
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testPlatformToCommonDependency() {
|
fun testPlatformToCommonDependency() {
|
||||||
createProjectSubFile("settings.gradle", "include ':common', ':jvm', ':js'")
|
createProjectSubFile("settings.gradle", "include ':common', ':jvm', ':js'")
|
||||||
@@ -492,6 +500,112 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testTransitiveImplementWithNonDefaultConfig() {
|
||||||
|
createProjectSubFile(
|
||||||
|
"settings.gradle",
|
||||||
|
"include ':project1', ':project2', ':project3'"
|
||||||
|
)
|
||||||
|
|
||||||
|
val kotlinVersion = "1.2.31"
|
||||||
|
|
||||||
|
createProjectSubFile(
|
||||||
|
"build.gradle", """
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
project('project1') {
|
||||||
|
apply plugin: 'kotlin-platform-common'
|
||||||
|
}
|
||||||
|
|
||||||
|
project('project2') {
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: 'kotlin-platform-jvm'
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main
|
||||||
|
main2
|
||||||
|
}
|
||||||
|
|
||||||
|
task myJar(type: Jar) {
|
||||||
|
baseName = 'project2-jar'
|
||||||
|
from sourceSets.main.output
|
||||||
|
from sourceSets.main2.output
|
||||||
|
}
|
||||||
|
|
||||||
|
configurations {
|
||||||
|
myConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
artifacts {
|
||||||
|
myConfig myJar
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implement project(':project1')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
project('project3') {
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: 'kotlin-platform-jvm'
|
||||||
|
apply plugin: 'kotlin'
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile(project(path: ':project2', configuration: 'myConfig')) { transitive = false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
val isResolveModulePerSourceSet = getCurrentExternalProjectSettings().isResolveModulePerSourceSet
|
||||||
|
|
||||||
|
try {
|
||||||
|
currentExternalProjectSettings.isResolveModulePerSourceSet = true
|
||||||
|
importProject()
|
||||||
|
|
||||||
|
assertModuleModuleDepScope("project2_main", "project1_main", DependencyScope.COMPILE)
|
||||||
|
assertModuleModuleDepScope("project3_main", "project2_main", DependencyScope.COMPILE)
|
||||||
|
assertNoDepForModule("project3_main", "project1_main")
|
||||||
|
|
||||||
|
TestCase.assertEquals(
|
||||||
|
listOf("jar:///project2/build/libs/project2-jar.jar!/"),
|
||||||
|
getDependencyLibraryUrls("project3_main")
|
||||||
|
)
|
||||||
|
|
||||||
|
currentExternalProjectSettings.isResolveModulePerSourceSet = false
|
||||||
|
importProject()
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that currently such dependencies can't be imported correctly in "No separate module per source set" mode
|
||||||
|
* due to IDEA importer limitations
|
||||||
|
*/
|
||||||
|
assertModuleModuleDepScope("project2", "project1", DependencyScope.COMPILE)
|
||||||
|
assertModuleModuleDepScope("project3", "project2", DependencyScope.TEST, DependencyScope.PROVIDED, DependencyScope.RUNTIME)
|
||||||
|
assertModuleModuleDepScope("project3", "project1", DependencyScope.COMPILE)
|
||||||
|
|
||||||
|
TestCase.assertEquals(
|
||||||
|
emptyList<String>(),
|
||||||
|
getDependencyLibraryUrls("project3")
|
||||||
|
)
|
||||||
|
} finally {
|
||||||
|
currentExternalProjectSettings.isResolveModulePerSourceSet = isResolveModulePerSourceSet
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testTransitiveImplementWithAndroid() {
|
fun testTransitiveImplementWithAndroid() {
|
||||||
createProjectSubFile(
|
createProjectSubFile(
|
||||||
|
|||||||
+1
-1
@@ -138,7 +138,7 @@ public abstract class ExternalSystemImportingTestCase extends ExternalSystemTest
|
|||||||
return getModuleDep(moduleName, depName, ModuleOrderEntry.class);
|
return getModuleDep(moduleName, depName, ModuleOrderEntry.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModuleRootManager getRootManager(String module) {
|
protected ModuleRootManager getRootManager(String module) {
|
||||||
return ModuleRootManager.getInstance(getModule(module));
|
return ModuleRootManager.getInstance(getModule(module));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user