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
+126
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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.test
|
||||
|
||||
import java.io.File
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.script.experimental.dependencies.*
|
||||
import kotlin.script.experimental.api.ResultWithDiagnostics
|
||||
import kotlin.script.experimental.dependencies.impl.makeResolveFailureResult
|
||||
|
||||
@ExperimentalContracts
|
||||
class ResolversTest : ResolversTestBase() {
|
||||
|
||||
private fun <T> withTempFile(body: (file: File) -> T): T {
|
||||
createTempFile()
|
||||
val file = createTempFile()
|
||||
file.deleteOnExit()
|
||||
try {
|
||||
return body(file)
|
||||
} finally {
|
||||
file.delete()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getNonExistingFile() = withTempFile { it }.also { assertFalse(it.exists()) }
|
||||
|
||||
fun testFileSystemResolver() {
|
||||
withTempFile { file ->
|
||||
|
||||
val resolver = FileSystemDependenciesResolver()
|
||||
|
||||
resolver.assertNotResolve(1, file.name)
|
||||
resolver.assertResolve(file, file.canonicalPath)
|
||||
|
||||
val dir = file.parent!!
|
||||
resolver.assertAcceptsRepository(dir)
|
||||
resolver.addRepository(dir)
|
||||
|
||||
resolver.assertResolve(file, file.name)
|
||||
}
|
||||
}
|
||||
|
||||
fun testFileSystemResolverFail() {
|
||||
val file = getNonExistingFile()
|
||||
|
||||
val resolver = FileSystemDependenciesResolver()
|
||||
resolver.assertAcceptsArtifact(file.path)
|
||||
resolver.assertNotResolve(1, file.path)
|
||||
|
||||
resolver.addRepository(file.parent)
|
||||
|
||||
resolver.assertNotResolve(2, file.name)
|
||||
resolver.assertNotResolve(2, file.absolutePath)
|
||||
|
||||
resolver.addRepository(file.parentFile.parent)
|
||||
resolver.assertNotResolve(3, file.path)
|
||||
}
|
||||
|
||||
fun testFileSystemAcceptsLinuxPath() {
|
||||
val resolver = FileSystemDependenciesResolver()
|
||||
resolver.assertAcceptsArtifact("/usr/local/bin/temp")
|
||||
}
|
||||
|
||||
fun testFileSystemAcceptsWindowsPath() {
|
||||
val resolver = FileSystemDependenciesResolver()
|
||||
resolver.assertAcceptsArtifact("C:\\temp\\myfile")
|
||||
}
|
||||
|
||||
fun testFileSystemNotAcceptsMavenPath() {
|
||||
val resolver = FileSystemDependenciesResolver()
|
||||
resolver.assertNotAcceptsArtifact(" ")
|
||||
}
|
||||
|
||||
class TestDependenciesResolver(
|
||||
val acceptsArt: (String) -> Boolean,
|
||||
val doResolve: (String) -> File?,
|
||||
val acceptsRepo: (String) -> Boolean,
|
||||
val addRepo: (String) -> Unit
|
||||
) : ExternalDependenciesResolver {
|
||||
|
||||
override fun acceptsArtifact(artifactCoordinates: String): Boolean = acceptsArt(artifactCoordinates)
|
||||
|
||||
override suspend fun resolve(artifactCoordinates: String): ResultWithDiagnostics<List<File>> {
|
||||
if (!acceptsArtifact(artifactCoordinates)) throw Exception("Path is invalid")
|
||||
val file = doResolve(artifactCoordinates) ?: return makeResolveFailureResult("Failed to resolve '$artifactCoordinates'")
|
||||
return ResultWithDiagnostics.Success(listOf(file))
|
||||
}
|
||||
|
||||
override fun addRepository(repositoryCoordinates: RepositoryCoordinates) {
|
||||
addRepo(repositoryCoordinates.string)
|
||||
}
|
||||
|
||||
override fun acceptsRepository(repositoryCoordinates: RepositoryCoordinates): Boolean {
|
||||
return acceptsRepo(repositoryCoordinates.string)
|
||||
}
|
||||
}
|
||||
|
||||
fun testCompoundResolver() {
|
||||
val file1 = getNonExistingFile()
|
||||
val file2 = getNonExistingFile()
|
||||
val resolver1 = TestDependenciesResolver(acceptsArt = { it.startsWith("file") },
|
||||
doResolve = { if (it == "file1") file1 else null },
|
||||
acceptsRepo = { false },
|
||||
addRepo = {})
|
||||
|
||||
var prefix: String? = null
|
||||
val resolver2 = TestDependenciesResolver(acceptsArt = { a -> prefix?.let { a.startsWith(it) } ?: false },
|
||||
doResolve = { if (it.contains(".")) file2 else null },
|
||||
acceptsRepo = { true },
|
||||
addRepo = { prefix = it })
|
||||
|
||||
val resolver = CompoundDependenciesResolver(resolver1, resolver2)
|
||||
|
||||
resolver.assertNotResolve(1, "abc")
|
||||
resolver.assertNotResolve(1, "file2")
|
||||
resolver.assertResolve(file1, "file1")
|
||||
resolver.addRepository("fil")
|
||||
resolver.assertNotResolve(2, "file2")
|
||||
resolver.assertResolve(file2, "file2.txt")
|
||||
resolver.assertResolve(file1, "file1")
|
||||
resolver.assertResolve(file2, "fil1.txt")
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.test
|
||||
|
||||
import junit.framework.TestCase
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert
|
||||
import java.io.File
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.script.experimental.dependencies.ExternalDependenciesResolver
|
||||
import kotlin.script.experimental.dependencies.acceptsRepository
|
||||
import kotlin.script.experimental.api.ResultWithDiagnostics
|
||||
import kotlin.script.experimental.api.valueOrThrow
|
||||
|
||||
@ExperimentalContracts
|
||||
fun <T> assertIsFailure(r: ResultWithDiagnostics<T>) {
|
||||
contract {
|
||||
returns() implies (r is ResultWithDiagnostics.Failure)
|
||||
}
|
||||
|
||||
Assert.assertTrue(r is ResultWithDiagnostics.Failure)
|
||||
}
|
||||
|
||||
@ExperimentalContracts
|
||||
fun <T> assertIsSuccess(r: ResultWithDiagnostics<T>) {
|
||||
contract {
|
||||
returns() implies (r is ResultWithDiagnostics.Success<T>)
|
||||
}
|
||||
|
||||
TestCase.assertTrue(r is ResultWithDiagnostics.Success<T>)
|
||||
}
|
||||
|
||||
@ExperimentalContracts
|
||||
abstract class ResolversTestBase : TestCase() {
|
||||
fun ExternalDependenciesResolver.assertNotResolve(expectedReportsCount: Int, path: String) {
|
||||
val result = runBlocking { resolve(path) }
|
||||
assertIsFailure(result)
|
||||
assertEquals(expectedReportsCount, result.reports.count())
|
||||
}
|
||||
|
||||
fun ExternalDependenciesResolver.assertAcceptsArtifact(path: String) = assertTrue(acceptsArtifact(path))
|
||||
|
||||
fun ExternalDependenciesResolver.assertNotAcceptsArtifact(path: String) = assertFalse(acceptsArtifact(path))
|
||||
|
||||
fun ExternalDependenciesResolver.assertAcceptsRepository(path: String) = assertTrue(acceptsRepository(path))
|
||||
|
||||
fun ExternalDependenciesResolver.assertResolve(expected: File, path: String) {
|
||||
|
||||
assertTrue(acceptsArtifact(path))
|
||||
|
||||
val result = runBlocking { resolve(path) }
|
||||
assertIsSuccess(result)
|
||||
|
||||
val value = result.valueOrThrow()
|
||||
assertEquals(1, value.count())
|
||||
assertEquals(expected.canonicalPath, value.first().canonicalPath)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user