Scripting, KT-61727: Make it possible to resolve multiple artifacts at once
For MavenDependenciesResolver it improves performance drastically depending on how strong transitive dependencies of the roots interfere ^KT-61727 Fixed
This commit is contained in:
committed by
Space Team
parent
0d628c9e59
commit
841cc8eb43
+9
-7
@@ -13,6 +13,7 @@ import org.eclipse.aether.util.artifact.JavaScopes
|
||||
import org.eclipse.aether.util.repository.AuthenticationBuilder
|
||||
import java.io.File
|
||||
import kotlin.script.experimental.api.*
|
||||
import kotlin.script.experimental.dependencies.ArtifactWithLocation
|
||||
import kotlin.script.experimental.dependencies.ExternalDependenciesResolver
|
||||
import kotlin.script.experimental.dependencies.RepositoryCoordinates
|
||||
import kotlin.script.experimental.dependencies.impl.*
|
||||
@@ -50,12 +51,13 @@ class MavenDependenciesResolver : ExternalDependenciesResolver {
|
||||
else null
|
||||
|
||||
override suspend fun resolve(
|
||||
artifactCoordinates: String,
|
||||
options: ExternalDependenciesResolver.Options,
|
||||
sourceCodeLocation: SourceCode.LocationWithId?
|
||||
artifactsWithLocations: List<ArtifactWithLocation>,
|
||||
options: ExternalDependenciesResolver.Options
|
||||
): ResultWithDiagnostics<List<File>> {
|
||||
|
||||
val artifactId = artifactCoordinates.toMavenArtifact()!!
|
||||
val firstArtifactWithLocation = artifactsWithLocations.firstOrNull() ?: return ResultWithDiagnostics.Success(emptyList())
|
||||
val artifactIds = artifactsWithLocations.map {
|
||||
it.artifact.toMavenArtifact()!!
|
||||
}
|
||||
|
||||
return try {
|
||||
val dependencyScopes = options.dependencyScopes ?: listOf(JavaScopes.COMPILE, JavaScopes.RUNTIME)
|
||||
@@ -71,10 +73,10 @@ class MavenDependenciesResolver : ExternalDependenciesResolver {
|
||||
AetherResolveSession(
|
||||
null, remoteRepositories()
|
||||
).resolve(
|
||||
artifactId, dependencyScopes.joinToString(","), kind, null, classifier, extension
|
||||
artifactIds, dependencyScopes.joinToString(","), kind, null, classifier, extension
|
||||
)
|
||||
} catch (e: RepositoryException) {
|
||||
makeResolveFailureResult(e, sourceCodeLocation)
|
||||
makeResolveFailureResult(e, firstArtifactWithLocation.sourceCodeLocation)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-16
@@ -144,16 +144,16 @@ internal class AetherResolveSession(
|
||||
}
|
||||
|
||||
fun resolve(
|
||||
root: Artifact,
|
||||
roots: List<Artifact>,
|
||||
scope: String,
|
||||
kind: ResolutionKind,
|
||||
filter: DependencyFilter?,
|
||||
classifier: String? = null,
|
||||
extension: String? = null,
|
||||
): ResultWithDiagnostics<List<File>> {
|
||||
if (kind == ResolutionKind.NON_TRANSITIVE) return resolveArtifact(root).asSuccess()
|
||||
if (kind == ResolutionKind.NON_TRANSITIVE) return resolveArtifacts(roots).asSuccess()
|
||||
|
||||
val requests = resolveTree(root, scope, filter, classifier, extension)
|
||||
val requests = resolveTree(roots, scope, filter, classifier, extension)
|
||||
|
||||
@Suppress("KotlinConstantConditions")
|
||||
return when (kind) {
|
||||
@@ -197,14 +197,14 @@ internal class AetherResolveSession(
|
||||
}
|
||||
|
||||
private fun resolveTree(
|
||||
root: Artifact,
|
||||
roots: List<Artifact>,
|
||||
scope: String,
|
||||
filter: DependencyFilter?,
|
||||
classifier: String?,
|
||||
extension: String?,
|
||||
): Collection<ArtifactRequest> {
|
||||
return fetch(
|
||||
request(Dependency(root, scope)),
|
||||
request(roots.map { root -> Dependency(root, scope) }),
|
||||
{ req ->
|
||||
val requestsBuilder = ArtifactRequestBuilder(classifier, extension)
|
||||
val collectionResult = repositorySystem.collectDependencies(repositorySystemSession, req)
|
||||
@@ -247,23 +247,21 @@ internal class AetherResolveSession(
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveArtifact(artifact: Artifact): List<File> {
|
||||
val request = ArtifactRequest()
|
||||
request.artifact = artifact
|
||||
for (repo in remotes) {
|
||||
request.addRepository(repo)
|
||||
private fun resolveArtifacts(artifacts: List<Artifact>): List<File> {
|
||||
val requests = artifacts.map { artifact ->
|
||||
ArtifactRequest(artifact, remotes, "")
|
||||
}
|
||||
|
||||
return fetch(
|
||||
request,
|
||||
{ req -> listOf(repositorySystem.resolveArtifact(repositorySystemSession, req)) },
|
||||
{ req, ex -> ArtifactResolutionException(listOf(ArtifactResult(req)), ex.message, IllegalArgumentException(ex)) }
|
||||
).toFiles()
|
||||
requests,
|
||||
{ reqs -> listOf(repositorySystem.resolveArtifacts(repositorySystemSession, reqs)) },
|
||||
{ reqs, ex -> ArtifactResolutionException(reqs.map { req -> ArtifactResult(req) }, ex.message, IllegalArgumentException(ex)) }
|
||||
).flatMap { it.toFiles() }
|
||||
}
|
||||
|
||||
private fun request(root: Dependency): CollectRequest {
|
||||
private fun request(roots: List<Dependency>): CollectRequest {
|
||||
val request = CollectRequest()
|
||||
request.root = root
|
||||
request.dependencies = roots
|
||||
for (repo in remotes) {
|
||||
request.addRepository(repo)
|
||||
}
|
||||
|
||||
+37
@@ -9,6 +9,7 @@ import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert
|
||||
import org.junit.Ignore
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
@@ -22,6 +23,7 @@ import kotlin.script.experimental.dependencies.impl.makeExternalDependenciesReso
|
||||
import kotlin.script.experimental.dependencies.impl.set
|
||||
import kotlin.script.experimental.dependencies.maven.MavenDependenciesResolver
|
||||
import kotlin.script.experimental.dependencies.maven.impl.createMavenSettings
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
@ExperimentalContracts
|
||||
class MavenResolverTest : ResolversTestBase() {
|
||||
@@ -183,6 +185,41 @@ class MavenResolverTest : ResolversTestBase() {
|
||||
)
|
||||
}
|
||||
|
||||
fun testMultipleDependencies() {
|
||||
val resolver = MavenDependenciesResolver()
|
||||
val sourceOptions = buildOptions(
|
||||
DependenciesResolverOptionsName.PARTIAL_RESOLUTION to "true",
|
||||
DependenciesResolverOptionsName.CLASSIFIER to "sources",
|
||||
DependenciesResolverOptionsName.EXTENSION to "jar",
|
||||
)
|
||||
val multipleDependencies = listOf(
|
||||
"commons-io:commons-io:2.11.0",
|
||||
"org.jetbrains.kotlin:kotlin-reflect:1.8.20",
|
||||
"org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.20",
|
||||
).map { ArtifactWithLocation(it, null) }
|
||||
|
||||
val result = TreeSet<String>()
|
||||
fun addToResult(resultFiles: ResultWithDiagnostics<List<File>>) {
|
||||
if (resultFiles is ResultWithDiagnostics.Success) {
|
||||
for (file in resultFiles.value) {
|
||||
result.add(file.absolutePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val timeMs = measureTimeMillis {
|
||||
runBlocking {
|
||||
addToResult(resolver.resolve(multipleDependencies))
|
||||
addToResult(resolver.resolve(multipleDependencies, sourceOptions))
|
||||
}
|
||||
}
|
||||
println("Test time: $timeMs ms")
|
||||
println("Deps size: ${result.size}")
|
||||
println(result.joinToString("\n"))
|
||||
|
||||
assertEquals(14, result.size)
|
||||
}
|
||||
|
||||
@Ignore("ignored because spark is a very heavy dependency")
|
||||
fun ignore_testPartialResolution() {
|
||||
val resolver = MavenDependenciesResolver()
|
||||
|
||||
Reference in New Issue
Block a user