Add new script dependency resolvers
Changes in new API for dependency resolvers (GenericDependenciesResolver) comparing to an old one (GenericResolver: - Add ability to fast check whether artifact or repository is suitable for current resolver to distinguish between unsuitable resolvers and resolution failures - Return all artifact resolution failures in ResultWithDiagnostics - Use single string for artifact coordinates - Add compound resolver that combines several resolvers - Merge Direct and FlatLib resolver into single FileSystemDependencyResolver - Mark resolve() method as suspend to indicate long operation - Add credentials support for maven resolver (https://youtrack.jetbrains.com/issue/KT-27701)
This commit is contained in:
committed by
Ilya Chernikov
parent
81e2e119e2
commit
c7e9a6c5d9
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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.
|
||||
*/
|
||||
|
||||
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.dependencies.impl.makeResolveFailureResult
|
||||
|
||||
class CompoundDependenciesResolver(private val resolvers: List<ExternalDependenciesResolver>) : ExternalDependenciesResolver {
|
||||
|
||||
constructor(vararg resolvers: ExternalDependenciesResolver) : this(resolvers.toList())
|
||||
|
||||
override fun acceptsArtifact(artifactCoordinates: String): Boolean {
|
||||
return resolvers.any { it.acceptsArtifact(artifactCoordinates) }
|
||||
}
|
||||
|
||||
override fun acceptsRepository(repositoryCoordinates: RepositoryCoordinates): Boolean {
|
||||
return resolvers.any { it.acceptsRepository(repositoryCoordinates) }
|
||||
}
|
||||
|
||||
override fun addRepository(repositoryCoordinates: RepositoryCoordinates) {
|
||||
if (resolvers.count { it.tryAddRepository(repositoryCoordinates) } == 0)
|
||||
throw Exception("Failed to detect repository type: $repositoryCoordinates")
|
||||
}
|
||||
|
||||
override suspend fun resolve(artifactCoordinates: String): ResultWithDiagnostics<List<File>> {
|
||||
|
||||
val reports = mutableListOf<ScriptDiagnostic>()
|
||||
|
||||
for (resolver in resolvers) {
|
||||
if (resolver.acceptsArtifact(artifactCoordinates)) {
|
||||
when (val resolveResult = resolver.resolve(artifactCoordinates)) {
|
||||
is ResultWithDiagnostics.Failure -> reports.addAll(resolveResult.reports)
|
||||
else -> return resolveResult
|
||||
}
|
||||
}
|
||||
}
|
||||
return if (reports.count() == 0) {
|
||||
makeResolveFailureResult("No suitable dependency resolver found for artifact '$artifactCoordinates'")
|
||||
} else {
|
||||
ResultWithDiagnostics.Failure(reports)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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.
|
||||
*/
|
||||
|
||||
package kotlin.script.experimental.dependencies
|
||||
|
||||
import java.io.File
|
||||
import kotlin.script.experimental.api.ResultWithDiagnostics
|
||||
import kotlin.script.experimental.api.valueOrNull
|
||||
|
||||
open class RepositoryCoordinates(val string: String)
|
||||
|
||||
interface ExternalDependenciesResolver {
|
||||
|
||||
fun acceptsRepository(repositoryCoordinates: RepositoryCoordinates): Boolean
|
||||
fun acceptsArtifact(artifactCoordinates: String): Boolean
|
||||
|
||||
suspend fun resolve(artifactCoordinates: String): ResultWithDiagnostics<List<File>>
|
||||
fun addRepository(repositoryCoordinates: RepositoryCoordinates)
|
||||
}
|
||||
|
||||
fun ExternalDependenciesResolver.acceptsRepository(repositoryCoordinates: String): Boolean =
|
||||
acceptsRepository(RepositoryCoordinates(repositoryCoordinates))
|
||||
|
||||
fun ExternalDependenciesResolver.addRepository(repositoryCoordinates: String) = addRepository(RepositoryCoordinates(repositoryCoordinates))
|
||||
|
||||
suspend fun ExternalDependenciesResolver.tryResolve(artifactCoordinates: String): List<File>? =
|
||||
if (acceptsArtifact(artifactCoordinates)) resolve(artifactCoordinates).valueOrNull() else null
|
||||
|
||||
fun ExternalDependenciesResolver.tryAddRepository(repositoryCoordinates: String) =
|
||||
tryAddRepository(RepositoryCoordinates(repositoryCoordinates))
|
||||
|
||||
fun ExternalDependenciesResolver.tryAddRepository(repositoryCoordinates: RepositoryCoordinates) =
|
||||
if (acceptsRepository(repositoryCoordinates)) {
|
||||
addRepository(repositoryCoordinates)
|
||||
true
|
||||
} else false
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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.
|
||||
*/
|
||||
|
||||
package kotlin.script.experimental.dependencies
|
||||
|
||||
import java.io.File
|
||||
import kotlin.script.experimental.api.ResultWithDiagnostics
|
||||
import kotlin.script.experimental.dependencies.impl.makeResolveFailureResult
|
||||
import kotlin.script.experimental.dependencies.impl.toRepositoryUrlOrNull
|
||||
|
||||
class FileSystemDependenciesResolver(vararg paths: File) : ExternalDependenciesResolver {
|
||||
|
||||
private fun String.toRepositoryFileOrNull(): File? =
|
||||
File(this).takeIf { it.exists() && it.isDirectory }
|
||||
|
||||
private fun RepositoryCoordinates.toFilePath() =
|
||||
(this.toRepositoryUrlOrNull()?.takeIf { it.protocol == "file" }?.path ?: string).toRepositoryFileOrNull()
|
||||
|
||||
override fun addRepository(repositoryCoordinates: RepositoryCoordinates) {
|
||||
val repoDir = repositoryCoordinates.toFilePath()
|
||||
?: throw IllegalArgumentException("Invalid repository location: '${repositoryCoordinates}'")
|
||||
localRepos.add(repoDir)
|
||||
}
|
||||
|
||||
override suspend fun resolve(artifactCoordinates: String): ResultWithDiagnostics<List<File>> {
|
||||
if (!acceptsArtifact(artifactCoordinates)) throw IllegalArgumentException("Path is invalid")
|
||||
|
||||
val messages = mutableListOf<String>()
|
||||
|
||||
for (repo in localRepos) {
|
||||
// TODO: add coordinates and wildcard matching
|
||||
val file = if (repo == null) File(artifactCoordinates) else File(repo, artifactCoordinates)
|
||||
when {
|
||||
!file.exists() -> messages.add("File '$file' does not exists")
|
||||
!file.isFile && !file.isDirectory -> messages.add("Path '$file' is neither file nor directory")
|
||||
else -> return ResultWithDiagnostics.Success(listOf(file))
|
||||
}
|
||||
}
|
||||
return makeResolveFailureResult(messages)
|
||||
}
|
||||
|
||||
override fun acceptsArtifact(artifactCoordinates: String) =
|
||||
!artifactCoordinates.isBlank() // TODO: make check stronger, e.g. using NIO's Path
|
||||
|
||||
override fun acceptsRepository(repositoryCoordinates: RepositoryCoordinates): Boolean = repositoryCoordinates.toFilePath() != null
|
||||
|
||||
private val localRepos = arrayListOf<File?>(null)
|
||||
|
||||
init {
|
||||
for (path in paths) {
|
||||
require(path.exists() && path.isDirectory) { "Invalid flat lib directory repository path '$path'" }
|
||||
}
|
||||
localRepos.addAll(paths)
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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.
|
||||
*/
|
||||
|
||||
package kotlin.script.experimental.dependencies.impl
|
||||
|
||||
import java.net.MalformedURLException
|
||||
import java.net.URL
|
||||
import kotlin.script.experimental.dependencies.RepositoryCoordinates
|
||||
import kotlin.script.experimental.api.ResultWithDiagnostics
|
||||
import kotlin.script.experimental.api.ScriptDiagnostic
|
||||
|
||||
fun makeResolveFailureResult(message: String) = makeResolveFailureResult(listOf(message))
|
||||
|
||||
fun makeResolveFailureResult(messages: Iterable<String>) =
|
||||
ResultWithDiagnostics.Failure(messages.map { ScriptDiagnostic(it, ScriptDiagnostic.Severity.WARNING) })
|
||||
|
||||
fun RepositoryCoordinates.toRepositoryUrlOrNull(): URL? =
|
||||
try {
|
||||
URL(string)
|
||||
} catch (_: MalformedURLException) {
|
||||
null
|
||||
}
|
||||
Reference in New Issue
Block a user