[Gradle] IdeBinaryDependencyResolver: Support opaque file dependencies

^KT-60612 In Progress
This commit is contained in:
Sebastian Sellmair
2023-07-24 14:32:58 +02:00
committed by Space Team
parent 6c4ce81237
commit f883079988
5 changed files with 119 additions and 10 deletions
@@ -576,10 +576,13 @@ public final class org/jetbrains/kotlin/gradle/idea/tcs/extras/PrimitiveExtrasKt
public static final fun isNativeDistributionKey ()Lorg/jetbrains/kotlin/tooling/core/Extras$Key;
public static final fun isNativeStdlib (Lorg/jetbrains/kotlin/gradle/idea/tcs/IdeaKotlinBinaryDependency;)Z
public static final fun isNativeStdlibKey ()Lorg/jetbrains/kotlin/tooling/core/Extras$Key;
public static final fun isOpaqueFileDependency (Lorg/jetbrains/kotlin/gradle/idea/tcs/IdeaKotlinBinaryDependency;)Z
public static final fun isOpaqueFileDependencyKey ()Lorg/jetbrains/kotlin/tooling/core/Extras$Key;
public static final fun setCommonized (Lorg/jetbrains/kotlin/gradle/idea/tcs/IdeaKotlinBinaryDependency;Z)V
public static final fun setIdeaProjectLevel (Lorg/jetbrains/kotlin/gradle/idea/tcs/IdeaKotlinBinaryDependency;Z)V
public static final fun setNativeDistribution (Lorg/jetbrains/kotlin/gradle/idea/tcs/IdeaKotlinBinaryDependency;Z)V
public static final fun setNativeStdlib (Lorg/jetbrains/kotlin/gradle/idea/tcs/IdeaKotlinBinaryDependency;Z)V
public static final fun setOpaqueFileDependency (Lorg/jetbrains/kotlin/gradle/idea/tcs/IdeaKotlinBinaryDependency;Z)V
}
public final class org/jetbrains/kotlin/gradle/idea/tcs/extras/ProjectArtifactClasspathExtrasKt {
@@ -41,3 +41,24 @@ val isCommonizedKey = extrasKeyOf<Boolean>("isCommonized")
* Marks dependencies produced by the commonizer
*/
var IdeaKotlinBinaryDependency.isCommonized by isCommonizedKey.readWriteProperty.notNull(false)
/**
* @see isOpaqueFileDependencyKey
*/
val isOpaqueFileDependencyKey = extrasKeyOf<Boolean>("isOpaqueFileDependencyKey")
/**
* Marks a dependency as 'opaque' (meaning that we cannot really know about the actual binary coordiantes)
*
* Example: File dependencies are 'opaque'
* ```kotlin
* kotlin {
* sourceSets.jvmMain.dependencies {
* implementation(files("libs/foo.jar")) // <- OPAQUE
* implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.2") // <- NOT OPAQUE
* }
* }
* ```
*/
var IdeaKotlinBinaryDependency.isOpaqueFileDependency by isOpaqueFileDependencyKey.readWriteProperty.notNull(false)
@@ -15,8 +15,9 @@ import org.gradle.internal.resolve.ModuleVersionResolveException
import org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi
import org.jetbrains.kotlin.gradle.idea.tcs.*
import org.jetbrains.kotlin.gradle.idea.tcs.extras.artifactsClasspath
import org.jetbrains.kotlin.gradle.idea.tcs.extras.isIdeaProjectLevel
import org.jetbrains.kotlin.gradle.idea.tcs.extras.isOpaqueFileDependency
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinOutputDependencyIdentifier
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.ide.*
@@ -32,6 +33,7 @@ import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.sources.InternalKotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.sources.internal
import org.jetbrains.kotlin.gradle.utils.markResolvable
import org.jetbrains.kotlin.gradle.utils.relativeOrAbsolute
import org.jetbrains.kotlin.tooling.core.mutableExtrasOf
/**
@@ -171,18 +173,31 @@ class IdeBinaryDependencyResolver @JvmOverloads constructor(
is OpaqueComponentArtifactIdentifier -> {
/* Such dependencies *would* require implementing a resolver */
null
IdeaKotlinResolvedBinaryDependency(
binaryType = binaryType, coordinates = IdeaKotlinBinaryCoordinates(
group = "<file>",
module = componentId.file.relativeOrAbsolute(sourceSet.project.rootDir),
version = null,
sourceSetName = null
),
classpath = IdeaKotlinClasspath(componentId.file)
).also { dependency ->
dependency.isOpaqueFileDependency = true
}
}
/*
Such dependencies (e.g. associate compilations, cinterops, ...)
Will have dedicated resolvers implemented
*/
is KotlinOutputDependencyIdentifier -> null
else -> {
logger.warn("Unhandled componentId: ${componentId.javaClass}")
null
}
}?.also { dependency ->
dependency.gradleArtifact = artifact
if (dependency is IdeaKotlinResolvedBinaryDependency) {
dependency.isIdeaProjectLevel = false
}
}
}.toSet()
@@ -235,11 +250,7 @@ class IdeBinaryDependencyResolver @JvmOverloads constructor(
private fun ArtifactResolutionStrategy.createArtifactViewFromConfiguration(
sourceSet: KotlinSourceSet, configuration: Configuration,
): ArtifactView = configuration.incoming
.apply {
val dependencyFilter = dependencyFilter
if (dependencyFilter != null) dependencies.removeIf { dependency -> !dependencyFilter.invoke(dependency) }
}
): ArtifactView = (if (dependencyFilter != null) configuration.copyRecursive(dependencyFilter) else configuration).incoming
.artifactView { view ->
view.isLenient = true
view.attributes.setupArtifactViewAttributes(sourceSet)
@@ -24,4 +24,5 @@ val kotlinExtrasSerialization = IdeaKotlinExtrasSerializationExtension {
register(sourcesClasspathKey, IdeaKotlinClasspathSerializer)
register(documentationClasspathKey, IdeaKotlinClasspathSerializer)
register(projectArtifactsClasspathKey, IdeaKotlinClasspathSerializer)
register(isOpaqueFileDependencyKey, IdeaKotlinBooleanExtrasSerializer)
}
@@ -0,0 +1,73 @@
/*
* 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.
*/
@file:Suppress("FunctionName")
package org.jetbrains.kotlin.gradle.dependencyResolutionTests.tcs
import org.jetbrains.kotlin.gradle.dependencyResolutionTests.mavenCentralCacheRedirector
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformSourceSetConventionsImpl.dependencies
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformSourceSetConventionsImpl.jvmMain
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinResolvedBinaryDependency
import org.jetbrains.kotlin.gradle.idea.tcs.extras.isOpaqueFileDependency
import org.jetbrains.kotlin.gradle.idea.testFixtures.tcs.*
import org.jetbrains.kotlin.gradle.plugin.ide.kotlinIdeMultiplatformImport
import org.jetbrains.kotlin.gradle.util.applyMultiplatformPlugin
import org.jetbrains.kotlin.gradle.util.buildProject
import org.jetbrains.kotlin.gradle.util.enableDefaultStdlibDependency
import org.jetbrains.kotlin.gradle.util.enableDependencyVerification
import kotlin.test.Test
import kotlin.test.assertTrue
import kotlin.test.fail
class IdeOpaqueFileDependencyResolutionTest {
@Test
fun `test - simple jar file`() {
val project = buildProject {
enableDefaultStdlibDependency(false)
enableDependencyVerification(false)
applyMultiplatformPlugin()
repositories.mavenCentralCacheRedirector()
val kotlin = project.multiplatformExtension
kotlin.jvm()
/*
Setup opaque file dependency to 'foo.jar'
*/
kotlin.sourceSets.jvmMain.dependencies {
implementation(project.files("libs/foo.jar"))
}
}
project.evaluate()
/* Check dependencies on jvmMain */
val fooJarMatcher = binaryCoordinates(Regex(""".*:libs[/\\]foo\.jar"""))
val fooJarDependency = project.kotlinIdeMultiplatformImport.resolveDependencies("jvmMain").assertMatches(
dependsOnDependency(":/commonMain"),
fooJarMatcher
).getOrFail(fooJarMatcher)
if (fooJarDependency !is IdeaKotlinResolvedBinaryDependency) {
fail("Expected 'foo.jar' to be resolved. Found $fooJarDependency")
}
assertTrue(
fooJarDependency.isOpaqueFileDependency,
"Expected 'foo.jar' to be marked as 'opaque file dependency'"
)
/* Check dependencies on jvmTest */
project.kotlinIdeMultiplatformImport.resolveDependencies("jvmTest").assertMatches(
friendSourceDependency(":/commonMain"),
friendSourceDependency(":/jvmMain"),
dependsOnDependency(":/commonTest"),
fooJarMatcher
)
}
}