org.jetbrains.kotlinx.jupyter.dependencies.JupyterScriptDependenciesResolverImpl.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kotlin-jupyter-kernel Show documentation
Show all versions of kotlin-jupyter-kernel Show documentation
Kotlin Jupyter kernel published as artifact
package org.jetbrains.kotlinx.jupyter.dependencies
import jupyter.kotlin.DependsOn
import jupyter.kotlin.Repository
import kotlinx.coroutines.runBlocking
import org.jetbrains.kotlin.mainKts.impl.IvyResolver
import org.jetbrains.kotlinx.jupyter.config.getLogger
import java.io.File
import kotlin.script.dependencies.ScriptContents
import kotlin.script.experimental.api.ResultWithDiagnostics
import kotlin.script.experimental.api.ScriptDiagnostic
import kotlin.script.experimental.api.asSuccess
import kotlin.script.experimental.api.makeFailureResult
import kotlin.script.experimental.api.valueOrNull
import kotlin.script.experimental.dependencies.CompoundDependenciesResolver
import kotlin.script.experimental.dependencies.ExternalDependenciesResolver
import kotlin.script.experimental.dependencies.FileSystemDependenciesResolver
import kotlin.script.experimental.dependencies.RepositoryCoordinates
import kotlin.script.experimental.dependencies.impl.DependenciesResolverOptionsName
import kotlin.script.experimental.dependencies.impl.makeExternalDependenciesResolverOptions
open class JupyterScriptDependenciesResolverImpl(resolverConfig: ResolverConfig?) : JupyterScriptDependenciesResolver {
private val log = getLogger("resolver")
private val resolver: ExternalDependenciesResolver
private val resolverOptions = makeExternalDependenciesResolverOptions(
mapOf(
DependenciesResolverOptionsName.SCOPE.key to "compile,runtime"
)
)
private val repositories = arrayListOf()
private val addedClasspath = arrayListOf()
init {
resolver = CompoundDependenciesResolver(
FileSystemDependenciesResolver(),
RemoteResolverWrapper(IvyResolver())
)
resolverConfig?.repositories?.forEach { addRepository(it) }
}
private fun addRepository(repository: RepositoryCoordinates): Boolean {
val repoIndex = repositories.indexOfFirst { it.string == repository.string }
if (repoIndex != -1) repositories.removeAt(repoIndex)
repositories.add(repository)
return resolver.addRepository(repository).valueOrNull() == true
}
fun popAddedClasspath(): List {
val result = addedClasspath.toList()
addedClasspath.clear()
return result
}
override fun resolveFromAnnotations(script: ScriptContents): ResultWithDiagnostics> {
val scriptDiagnostics = mutableListOf()
val classpath = mutableListOf()
var existingRepositories: List? = null
script.annotations.forEach { annotation ->
when (annotation) {
is Repository -> {
log.info("Adding repository: ${annotation.value}")
if (existingRepositories == null) {
existingRepositories = ArrayList(repositories)
}
if (!addRepository(RepositoryCoordinates(annotation.value))) {
throw IllegalArgumentException("Illegal argument for Repository annotation: $annotation")
}
existingRepositories?.forEach { addRepository(it) }
}
is DependsOn -> {
log.info("Resolving ${annotation.value}")
try {
when (val result = runBlocking { resolver.resolve(annotation.value, resolverOptions) }) {
is ResultWithDiagnostics.Failure -> {
val diagnostics = ScriptDiagnostic(ScriptDiagnostic.unspecifiedError, "Failed to resolve ${annotation.value}:\n" + result.reports.joinToString("\n") { it.message })
log.warn(diagnostics.message, diagnostics.exception)
scriptDiagnostics.add(diagnostics)
}
is ResultWithDiagnostics.Success -> {
log.info("Resolved: " + result.value.joinToString())
addedClasspath.addAll(result.value)
classpath.addAll(result.value)
}
}
} catch (e: Exception) {
val diagnostic = ScriptDiagnostic(ScriptDiagnostic.unspecifiedError, "Unhandled exception during resolve", exception = e)
log.error(diagnostic.message, e)
scriptDiagnostics.add(diagnostic)
}
// Hack: after first resolution add "standard" Central repo to the end of the list, giving it the lowest priority
addRepository(CENTRAL_REPO_COORDINATES)
}
else -> throw Exception("Unknown annotation ${annotation.javaClass}")
}
}
return if (scriptDiagnostics.isEmpty()) classpath.asSuccess()
else makeFailureResult(scriptDiagnostics)
}
companion object {
val CENTRAL_REPO_COORDINATES = RepositoryCoordinates("https://repo1.maven.org/maven2/")
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy