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
+48
-19
@@ -6,10 +6,7 @@
|
||||
package kotlin.script.experimental.dependencies
|
||||
|
||||
import java.io.File
|
||||
import kotlin.script.experimental.api.ResultWithDiagnostics
|
||||
import kotlin.script.experimental.api.ScriptDiagnostic
|
||||
import kotlin.script.experimental.api.SourceCode
|
||||
import kotlin.script.experimental.api.asSuccess
|
||||
import kotlin.script.experimental.api.*
|
||||
import kotlin.script.experimental.dependencies.impl.makeResolveFailureResult
|
||||
|
||||
class CompoundDependenciesResolver(private val resolvers: List<ExternalDependenciesResolver>) : ExternalDependenciesResolver {
|
||||
@@ -57,25 +54,57 @@ class CompoundDependenciesResolver(private val resolvers: List<ExternalDependenc
|
||||
}
|
||||
|
||||
override suspend fun resolve(
|
||||
artifactCoordinates: String,
|
||||
options: ExternalDependenciesResolver.Options,
|
||||
sourceCodeLocation: SourceCode.LocationWithId?
|
||||
artifactsWithLocations: List<ArtifactWithLocation>,
|
||||
options: ExternalDependenciesResolver.Options
|
||||
): ResultWithDiagnostics<List<File>> {
|
||||
val reports = mutableListOf<ScriptDiagnostic>()
|
||||
val resultsCollector = IterableResultsCollector<File>()
|
||||
|
||||
for (resolver in resolvers) {
|
||||
if (resolver.acceptsArtifact(artifactCoordinates)) {
|
||||
when (val resolveResult = resolver.resolve(artifactCoordinates, options, sourceCodeLocation)) {
|
||||
is ResultWithDiagnostics.Failure -> reports.addAll(resolveResult.reports)
|
||||
else -> return resolveResult
|
||||
val artifactToResolverIndex = mutableMapOf<ArtifactWithLocation, Int>().apply {
|
||||
for (artifactWithLocation in artifactsWithLocations) {
|
||||
put(artifactWithLocation, -1)
|
||||
}
|
||||
}
|
||||
|
||||
while (artifactToResolverIndex.isNotEmpty()) {
|
||||
val resolverGroups = mutableMapOf<Int, MutableList<ArtifactWithLocation>>()
|
||||
|
||||
for ((artifactWithLocation, resolverIndex) in artifactToResolverIndex) {
|
||||
val (artifact, sourceCodeLocation) = artifactWithLocation
|
||||
|
||||
var currentIndex = resolverIndex + 1
|
||||
while (currentIndex < resolvers.size) {
|
||||
if (resolvers[currentIndex].acceptsArtifact(artifact)) break
|
||||
++currentIndex
|
||||
}
|
||||
if (currentIndex == resolvers.size) {
|
||||
if (resolverIndex == -1) {
|
||||
// We add this diagnostic only if there were no resolution attempts made
|
||||
resultsCollector.addDiagnostic(
|
||||
"No suitable dependency resolver found for artifact '$artifact'"
|
||||
.asErrorDiagnostics(locationWithId = sourceCodeLocation)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
resolverGroups
|
||||
.getOrPut(currentIndex) { mutableListOf() }
|
||||
.add(artifactWithLocation)
|
||||
}
|
||||
}
|
||||
|
||||
artifactToResolverIndex.clear()
|
||||
for ((resolverIndex, artifacts) in resolverGroups) {
|
||||
val resolver = resolvers[resolverIndex]
|
||||
val resolveResult = resolver.resolve(artifacts, options)
|
||||
resultsCollector.add(resolveResult)
|
||||
if (resolveResult.reports.isNotEmpty()) {
|
||||
for (artifact in artifacts) {
|
||||
artifactToResolverIndex[artifact] = resolverIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return if (reports.count() == 0) {
|
||||
makeResolveFailureResult("No suitable dependency resolver found for artifact '$artifactCoordinates'", sourceCodeLocation)
|
||||
} else {
|
||||
ResultWithDiagnostics.Failure(reports)
|
||||
}
|
||||
|
||||
return resultsCollector.getResult()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+10
-2
@@ -11,6 +11,8 @@ import kotlin.script.experimental.dependencies.ExternalDependenciesResolver.Opti
|
||||
|
||||
open class RepositoryCoordinates(val string: String)
|
||||
|
||||
data class ArtifactWithLocation(val artifact: String, val sourceCodeLocation: SourceCode.LocationWithId?)
|
||||
|
||||
interface ExternalDependenciesResolver {
|
||||
interface Options {
|
||||
object Empty : Options {
|
||||
@@ -25,11 +27,18 @@ interface ExternalDependenciesResolver {
|
||||
fun acceptsRepository(repositoryCoordinates: RepositoryCoordinates): Boolean
|
||||
fun acceptsArtifact(artifactCoordinates: String): Boolean
|
||||
|
||||
// Override one of the following methods
|
||||
suspend fun resolve(
|
||||
artifactCoordinates: String,
|
||||
options: Options = Options.Empty,
|
||||
sourceCodeLocation: SourceCode.LocationWithId? = null
|
||||
): ResultWithDiagnostics<List<File>>
|
||||
): ResultWithDiagnostics<List<File>> = resolve(listOf(ArtifactWithLocation(artifactCoordinates, sourceCodeLocation)), options)
|
||||
|
||||
suspend fun resolve(
|
||||
artifactsWithLocations: List<ArtifactWithLocation>,
|
||||
options: Options = Options.Empty,
|
||||
): ResultWithDiagnostics<List<File>> =
|
||||
artifactsWithLocations.map { (artifact, location) -> resolve(artifact, options, location) }.asSuccessIfAny()
|
||||
|
||||
fun addRepository(
|
||||
repositoryCoordinates: RepositoryCoordinates,
|
||||
@@ -46,4 +55,3 @@ fun ExternalDependenciesResolver.addRepository(
|
||||
options: Options = Options.Empty,
|
||||
sourceCodeLocation: SourceCode.LocationWithId? = null
|
||||
) = addRepository(RepositoryCoordinates(repositoryCoordinates), options, sourceCodeLocation)
|
||||
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ abstract class ResolversTestBase : TestCase() {
|
||||
fun ExternalDependenciesResolver.assertNotResolve(expectedReportsCount: Int, path: String) {
|
||||
val result = runBlocking { resolve(path) }
|
||||
assertIsFailure(result)
|
||||
assertEquals(expectedReportsCount, result.reports.count())
|
||||
assertEquals("Actual reports:\n${result.reports.joinToString("\n")}", expectedReportsCount, result.reports.count())
|
||||
}
|
||||
|
||||
fun ExternalDependenciesResolver.assertAcceptsArtifact(path: String) = assertTrue(acceptsArtifact(path))
|
||||
|
||||
Reference in New Issue
Block a user