Consolidate resolving in the new lib, deprecate it in script-util

also deprecate Import and CompileOptions annotations, because they
do not seem generic enough. Create specific copie in the main-kts
instead.
This commit is contained in:
Ilya Chernikov
2020-05-14 21:05:32 +02:00
parent 7d426226f9
commit c112d37ac1
13 changed files with 115 additions and 86 deletions
@@ -5,11 +5,8 @@ plugins {
dependencies { dependencies {
compile(project(":kotlin-scripting-jvm")) compile(project(":kotlin-scripting-jvm"))
compile(project(":kotlin-scripting-dependencies"))
compile(project(":kotlin-scripting-dependencies-maven")) compile(project(":kotlin-scripting-dependencies-maven"))
compile(project(":kotlin-script-util"))
runtime("com.jcabi:jcabi-aether:0.10.1")
runtime("org.sonatype.aether:aether-api:1.13.1")
runtime("org.apache.maven:maven-core:3.0.3")
} }
sourceSets { sourceSets {
@@ -6,14 +6,10 @@
package org.jetbrains.kotlin.script.examples.jvm.resolve.maven package org.jetbrains.kotlin.script.examples.jvm.resolve.maven
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.jetbrains.kotlin.script.util.DependsOn
import org.jetbrains.kotlin.script.util.Repository
import kotlin.script.experimental.annotations.KotlinScript import kotlin.script.experimental.annotations.KotlinScript
import kotlin.script.experimental.api.* import kotlin.script.experimental.api.*
import kotlin.script.experimental.dependencies.CompoundDependenciesResolver import kotlin.script.experimental.dependencies.*
import kotlin.script.experimental.dependencies.FileSystemDependenciesResolver
import kotlin.script.experimental.dependencies.maven.MavenDependenciesResolver import kotlin.script.experimental.dependencies.maven.MavenDependenciesResolver
import kotlin.script.experimental.dependencies.tryAddRepository
import kotlin.script.experimental.jvm.JvmDependency import kotlin.script.experimental.jvm.JvmDependency
import kotlin.script.experimental.jvm.dependenciesFromCurrentContext import kotlin.script.experimental.jvm.dependenciesFromCurrentContext
import kotlin.script.experimental.jvm.jvm import kotlin.script.experimental.jvm.jvm
@@ -30,7 +26,7 @@ object ScriptWithMavenDepsConfiguration : ScriptCompilationConfiguration(
jvm { jvm {
dependenciesFromCurrentContext( dependenciesFromCurrentContext(
"scripting-jvm-maven-deps", // script library jar name "scripting-jvm-maven-deps", // script library jar name
"kotlin-script-util" // DependsOn annotation is taken from script-util "kotlin-scripting-dependencies" // DependsOn annotation is taken from script-util
) )
} }
refineConfiguration { refineConfiguration {
@@ -44,24 +40,8 @@ private val resolver = CompoundDependenciesResolver(FileSystemDependenciesResolv
fun configureMavenDepsOnAnnotations(context: ScriptConfigurationRefinementContext): ResultWithDiagnostics<ScriptCompilationConfiguration> { fun configureMavenDepsOnAnnotations(context: ScriptConfigurationRefinementContext): ResultWithDiagnostics<ScriptCompilationConfiguration> {
val annotations = context.collectedData?.get(ScriptCollectedData.foundAnnotations)?.takeIf { it.isNotEmpty() } val annotations = context.collectedData?.get(ScriptCollectedData.foundAnnotations)?.takeIf { it.isNotEmpty() }
?: return context.compilationConfiguration.asSuccess() ?: return context.compilationConfiguration.asSuccess()
annotations.forEach { annotation -> return runBlocking {
when (annotation) { resolver.resolveFromAnnotations(annotations)
is Repository -> {
val repositoryCoordinates = with(annotation) { value.takeIf { it.isNotBlank() } ?: url }
if (!resolver.tryAddRepository(repositoryCoordinates))
return makeFailureResult("Unrecognized repository coordinates: $repositoryCoordinates")
}
is DependsOn -> {}
else -> return makeFailureResult("Unknown annotation ${annotation.javaClass}")
}
}
return annotations.filterIsInstance(DependsOn::class.java).flatMapSuccess { dep ->
val artifactCoordinates =
if (dep.value.isNotBlank()) dep.value
else listOf(dep.groupId, dep.artifactId, dep.version).filter { it.isNotBlank() }.joinToString(":")
runBlocking {
resolver.resolve(artifactCoordinates)
}
}.onSuccess { }.onSuccess {
context.compilationConfiguration.with { context.compilationConfiguration.with {
dependencies.append(JvmDependency(it)) dependencies.append(JvmDependency(it))
@@ -0,0 +1,54 @@
/*
* Copyright 2010-2020 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.flatMapSuccess
import kotlin.script.experimental.api.makeFailureResult
/**
* A common annotation that could be used in a script to denote a dependency
* The annotation could be processed by configuration refinement code and it's arguments passed to an ExternalDependenciesResolver
* for resolving dependencies
*/
@Target(AnnotationTarget.FILE)
@Repeatable
@Retention(AnnotationRetention.SOURCE)
annotation class DependsOn(vararg val artifactsCoordinates: String)
/**
* A common annotation that could be used in a script to denote a repository for an ExternalDependenciesResolver
* The annotation could be processed by configuration refinement code and it's arguments passed to an ExternalDependenciesResolver
* for configuring repositories
*/
@Target(AnnotationTarget.FILE)
@Repeatable
@Retention(AnnotationRetention.SOURCE)
annotation class Repository(vararg val repositoriesCoordinates: String)
/**
* An extension function that configures repositories and resolves artifacts denoted by the [Repository] and [DependsOn] annotations
*/
suspend fun ExternalDependenciesResolver.resolveFromAnnotations(annotations: Iterable<Annotation>): ResultWithDiagnostics<List<File>> {
annotations.forEach { annotation ->
when (annotation) {
is Repository -> {
for (coordinates in annotation.repositoriesCoordinates) {
if (!tryAddRepository(coordinates))
return makeFailureResult("Unrecognized repository coordinates: $coordinates")
}
}
is DependsOn -> {}
else -> return makeFailureResult("Unknown annotation ${annotation.javaClass}")
}
}
return annotations.filterIsInstance(DependsOn::class.java)
.flatMap { it.artifactsCoordinates.asIterable() }
.flatMapSuccess { artifactCoordinates ->
resolve(artifactCoordinates)
}
}
@@ -29,7 +29,6 @@ dependencies {
compileOnly(project(":compiler:cli-common")) compileOnly(project(":compiler:cli-common"))
compileOnly(project(":kotlin-scripting-jvm-host")) compileOnly(project(":kotlin-scripting-jvm-host"))
compileOnly(project(":kotlin-scripting-dependencies")) compileOnly(project(":kotlin-scripting-dependencies"))
compileOnly(project(":kotlin-script-util"))
runtime(project(":kotlin-compiler-embeddable")) runtime(project(":kotlin-compiler-embeddable"))
runtime(project(":kotlin-scripting-compiler-embeddable")) runtime(project(":kotlin-scripting-compiler-embeddable"))
runtime(project(":kotlin-scripting-jvm-host-embeddable")) runtime(project(":kotlin-scripting-jvm-host-embeddable"))
@@ -38,7 +37,6 @@ dependencies {
embedded(project(":kotlin-scripting-jvm")) { isTransitive = false } embedded(project(":kotlin-scripting-jvm")) { isTransitive = false }
embedded(project(":kotlin-scripting-jvm-host")) { isTransitive = false } embedded(project(":kotlin-scripting-jvm-host")) { isTransitive = false }
embedded(project(":kotlin-scripting-dependencies")) { isTransitive = false } embedded(project(":kotlin-scripting-dependencies")) { isTransitive = false }
embedded(project(":kotlin-script-util")) { isTransitive = false }
embedded("org.apache.ivy:ivy:2.5.0") embedded("org.apache.ivy:ivy:2.5.0")
embedded(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core")) { isTransitive = false } embedded(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core")) { isTransitive = false }
embedded(commonDep("org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm")) { embedded(commonDep("org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm")) {
@@ -0,0 +1,35 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.mainKts
/**
* Import other script(s)
*/
@Target(AnnotationTarget.FILE)
@Repeatable
@Retention(AnnotationRetention.SOURCE)
annotation class Import(vararg val paths: String)
/**
* Compiler options that will be applied on script compilation
*
* @see [kotlin.script.experimental.api.compilerOptions]
*/
@Target(AnnotationTarget.FILE)
@Repeatable
@Retention(AnnotationRetention.SOURCE)
annotation class CompilerOptions(vararg val options: String)
@@ -1,36 +0,0 @@
/*
* 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 org.jetbrains.kotlin.mainKts.impl
import org.jetbrains.kotlin.script.util.DependsOn
import org.jetbrains.kotlin.script.util.Repository
import java.io.File
import kotlin.script.experimental.api.ResultWithDiagnostics
import kotlin.script.experimental.api.flatMapSuccess
import kotlin.script.experimental.api.makeFailureResult
import kotlin.script.experimental.dependencies.ExternalDependenciesResolver
import kotlin.script.experimental.dependencies.tryAddRepository
suspend fun resolveFromAnnotations(resolver: ExternalDependenciesResolver, annotations: Iterable<Annotation>): ResultWithDiagnostics<List<File>> {
annotations.forEach { annotation ->
when (annotation) {
is Repository -> {
val repositoryCoordinates = with(annotation) { value.takeIf { it.isNotBlank() } ?: url }
if (!resolver.tryAddRepository(repositoryCoordinates))
return makeFailureResult("Unrecognized repository coordinates: $repositoryCoordinates")
}
is DependsOn -> {}
else -> return makeFailureResult("Unknown annotation ${annotation.javaClass}")
}
}
return annotations.filterIsInstance(DependsOn::class.java).flatMapSuccess { dep ->
val artifactCoordinates =
if (dep.value.isNotBlank()) dep.value
else listOf(dep.groupId, dep.artifactId, dep.version).filter { it.isNotBlank() }.joinToString(":")
resolver.resolve(artifactCoordinates)
}
}
@@ -7,19 +7,13 @@ package org.jetbrains.kotlin.mainKts
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.jetbrains.kotlin.mainKts.impl.IvyResolver import org.jetbrains.kotlin.mainKts.impl.IvyResolver
import org.jetbrains.kotlin.mainKts.impl.resolveFromAnnotations
import org.jetbrains.kotlin.script.util.CompilerOptions
import org.jetbrains.kotlin.script.util.DependsOn
import org.jetbrains.kotlin.script.util.Import
import org.jetbrains.kotlin.script.util.Repository
import java.io.File import java.io.File
import java.security.MessageDigest import java.security.MessageDigest
import kotlin.script.dependencies.ScriptContents import kotlin.script.dependencies.ScriptContents
import kotlin.script.dependencies.ScriptDependenciesResolver import kotlin.script.dependencies.ScriptDependenciesResolver
import kotlin.script.experimental.annotations.KotlinScript import kotlin.script.experimental.annotations.KotlinScript
import kotlin.script.experimental.api.* import kotlin.script.experimental.api.*
import kotlin.script.experimental.dependencies.CompoundDependenciesResolver import kotlin.script.experimental.dependencies.*
import kotlin.script.experimental.dependencies.FileSystemDependenciesResolver
import kotlin.script.experimental.host.FileBasedScriptSource import kotlin.script.experimental.host.FileBasedScriptSource
import kotlin.script.experimental.host.FileScriptSource import kotlin.script.experimental.host.FileScriptSource
import kotlin.script.experimental.host.ScriptingHostConfiguration import kotlin.script.experimental.host.ScriptingHostConfiguration
@@ -138,7 +132,7 @@ class MainKtsConfigurator : RefineScriptCompilationConfigurationHandler {
val resolveResult = try { val resolveResult = try {
runBlocking { runBlocking {
resolveFromAnnotations(resolver, annotations.filter { it is DependsOn || it is Repository }) resolver.resolveFromAnnotations( annotations.filter { it is DependsOn || it is Repository })
} }
} catch (e: Throwable) { } catch (e: Throwable) {
ResultWithDiagnostics.Failure(*diagnostics.toTypedArray(), e.asDiagnostics(path = context.script.locationId)) ResultWithDiagnostics.Failure(*diagnostics.toTypedArray(), e.asDiagnostics(path = context.script.locationId))
@@ -16,33 +16,25 @@
package org.jetbrains.kotlin.script.util package org.jetbrains.kotlin.script.util
// in case of flat or direct resolvers the value should be a direct path or file name of a jar respectively @Deprecated("Use annotations an processing code from the kotlin-scripting-dependencies library")
// in case of maven resolver the maven coordinates string is accepted (resolved with com.jcabi.aether library)
@Target(AnnotationTarget.FILE) @Target(AnnotationTarget.FILE)
@Repeatable @Repeatable
@Retention(AnnotationRetention.SOURCE) @Retention(AnnotationRetention.SOURCE)
annotation class DependsOn(val value: String = "", val groupId: String = "", val artifactId: String = "", val version: String = "") annotation class DependsOn(val value: String = "", val groupId: String = "", val artifactId: String = "", val version: String = "")
// only flat directory repositories are supported now, so value should be a path to a directory with jars @Deprecated("Use annotations an processing code from the kotlin-scripting-dependencies library")
// TODO: support other types of repos
@Target(AnnotationTarget.FILE) @Target(AnnotationTarget.FILE)
@Repeatable @Repeatable
@Retention(AnnotationRetention.SOURCE) @Retention(AnnotationRetention.SOURCE)
annotation class Repository(val value: String = "", val id: String = "", val url: String = "") annotation class Repository(val value: String = "", val id: String = "", val url: String = "")
/** @Deprecated("Use your own annotations, this will be removed soon")
* Import other script(s)
*/
@Target(AnnotationTarget.FILE) @Target(AnnotationTarget.FILE)
@Repeatable @Repeatable
@Retention(AnnotationRetention.SOURCE) @Retention(AnnotationRetention.SOURCE)
annotation class Import(vararg val paths: String) annotation class Import(vararg val paths: String)
/** @Deprecated("Use your own annotations, this will be removed soon")
* Compiler options that will be applied on script compilation
*
* @see [kotlin.script.experimental.api.compilerOptions]
*/
@Target(AnnotationTarget.FILE) @Target(AnnotationTarget.FILE)
@Repeatable @Repeatable
@Retention(AnnotationRetention.SOURCE) @Retention(AnnotationRetention.SOURCE)
@@ -30,6 +30,7 @@ import kotlin.script.dependencies.ScriptDependenciesResolver
import kotlin.script.dependencies.asFuture import kotlin.script.dependencies.asFuture
import kotlin.script.templates.AcceptedAnnotations import kotlin.script.templates.AcceptedAnnotations
@Deprecated("Use new resolving classes from kotlin-scripting-dependencies and kotlin-scripting-dependencies-maven")
open class KotlinAnnotatedScriptDependenciesResolver(val baseClassPath: List<File>, resolvers: Iterable<Resolver>) open class KotlinAnnotatedScriptDependenciesResolver(val baseClassPath: List<File>, resolvers: Iterable<Resolver>)
: ScriptDependenciesResolver : ScriptDependenciesResolver
{ {
@@ -75,9 +76,11 @@ open class KotlinAnnotatedScriptDependenciesResolver(val baseClassPath: List<Fil
} }
} }
@Deprecated("Use FileSystemDependenciesResolver from kotlin-scripting-dependencies instead")
class LocalFilesResolver : class LocalFilesResolver :
KotlinAnnotatedScriptDependenciesResolver(emptyList(), arrayListOf(DirectResolver())) KotlinAnnotatedScriptDependenciesResolver(emptyList(), arrayListOf(DirectResolver()))
@Deprecated("Use CompoundDependenciesResolver and MavenDependenciesResolver from kotlin-scripting-dependencies and kotlin-scripting-dependencies-maven")
class FilesAndMavenResolver : class FilesAndMavenResolver :
KotlinAnnotatedScriptDependenciesResolver(emptyList(), arrayListOf(DirectResolver(), MavenResolver())) KotlinAnnotatedScriptDependenciesResolver(emptyList(), arrayListOf(DirectResolver(), MavenResolver()))
@@ -22,6 +22,7 @@ import java.io.File
import java.net.MalformedURLException import java.net.MalformedURLException
import java.net.URL import java.net.URL
@Deprecated("Use new resolving classes from kotlin-scripting-dependencies")
class DirectResolver : GenericRepositoryWithBridge { class DirectResolver : GenericRepositoryWithBridge {
override fun tryResolve(artifactCoordinates: GenericArtifactCoordinates): Iterable<File>? = override fun tryResolve(artifactCoordinates: GenericArtifactCoordinates): Iterable<File>? =
artifactCoordinates.string.takeUnless(String::isBlank) artifactCoordinates.string.takeUnless(String::isBlank)
@@ -30,6 +31,7 @@ class DirectResolver : GenericRepositoryWithBridge {
override fun tryAddRepository(repositoryCoordinates: GenericRepositoryCoordinates): Boolean = false override fun tryAddRepository(repositoryCoordinates: GenericRepositoryCoordinates): Boolean = false
} }
@Deprecated("Use new resolving classes from kotlin-scripting-dependencies")
class FlatLibDirectoryResolver(vararg paths: File) : GenericRepositoryWithBridge { class FlatLibDirectoryResolver(vararg paths: File) : GenericRepositoryWithBridge {
private val localRepos = arrayListOf<File>() private val localRepos = arrayListOf<File>()
@@ -13,10 +13,12 @@ import org.jetbrains.kotlin.script.util.resolvers.toRepositoryUrlOrNull
import java.io.File import java.io.File
import java.net.URL import java.net.URL
@Deprecated("Use new resolving classes from kotlin-scripting-dependencies")
interface GenericArtifactCoordinates { interface GenericArtifactCoordinates {
val string: String val string: String
} }
@Deprecated("Use new resolving classes from kotlin-scripting-dependencies")
interface GenericRepositoryCoordinates { interface GenericRepositoryCoordinates {
val string: String val string: String
val name: String? get() = null val name: String? get() = null
@@ -24,6 +26,7 @@ interface GenericRepositoryCoordinates {
val file: File? get() = (url?.takeIf { it.protocol == "file" }?.path ?: string).toRepositoryFileOrNull() val file: File? get() = (url?.takeIf { it.protocol == "file" }?.path ?: string).toRepositoryFileOrNull()
} }
@Deprecated("Use new resolving classes from kotlin-scripting-dependencies")
interface GenericResolver { interface GenericResolver {
fun tryResolve(artifactCoordinates: GenericArtifactCoordinates): Iterable<File>? fun tryResolve(artifactCoordinates: GenericArtifactCoordinates): Iterable<File>?
fun tryAddRepository(repositoryCoordinates: GenericRepositoryCoordinates): Boolean fun tryAddRepository(repositoryCoordinates: GenericRepositoryCoordinates): Boolean
@@ -34,10 +37,13 @@ interface GenericResolver {
tryAddRepository(BasicRepositoryCoordinates(repositoryCoordinates, id)) tryAddRepository(BasicRepositoryCoordinates(repositoryCoordinates, id))
} }
@Deprecated("Use new resolving classes from kotlin-scripting-dependencies")
open class BasicArtifactCoordinates(override val string: String) : GenericArtifactCoordinates open class BasicArtifactCoordinates(override val string: String) : GenericArtifactCoordinates
@Deprecated("Use new resolving classes from kotlin-scripting-dependencies")
open class BasicRepositoryCoordinates(override val string: String, override val name: String? = null) : GenericRepositoryCoordinates open class BasicRepositoryCoordinates(override val string: String, override val name: String? = null) : GenericRepositoryCoordinates
@Deprecated("Use new resolving classes from kotlin-scripting-dependencies")
interface GenericRepositoryWithBridge : GenericResolver, Resolver { interface GenericRepositoryWithBridge : GenericResolver, Resolver {
override fun tryResolve(dependsOn: DependsOn): Iterable<File>? = override fun tryResolve(dependsOn: DependsOn): Iterable<File>? =
tryResolve( tryResolve(
@@ -55,6 +61,7 @@ interface GenericRepositoryWithBridge : GenericResolver, Resolver {
} }
} }
@Deprecated("Use new resolving classes from kotlin-scripting-dependencies")
open class MavenArtifactCoordinates( open class MavenArtifactCoordinates(
val value: String?, val value: String?,
val groupId: String?, val groupId: String?,
@@ -31,8 +31,10 @@ import org.sonatype.aether.util.artifact.JavaScopes
import java.io.File import java.io.File
import java.util.* import java.util.*
@Deprecated("Use new resolving classes from kotlin-scripting-dependencies and kotlin-scripting-dependencies-maven")
val mavenCentral = RemoteRepository("maven-central", "default", "https://repo.maven.apache.org/maven2/") val mavenCentral = RemoteRepository("maven-central", "default", "https://repo.maven.apache.org/maven2/")
@Deprecated("Use kotlin.script.experimental.dependencies.maven.MavenDependenciesResolver from kotlin-scripting-dependencies-maven")
class MavenResolver(val reportError: ((String) -> Unit)? = null): GenericRepositoryWithBridge { class MavenResolver(val reportError: ((String) -> Unit)? = null): GenericRepositoryWithBridge {
// TODO: make robust // TODO: make robust
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.script.util.DependsOn
import org.jetbrains.kotlin.script.util.Repository import org.jetbrains.kotlin.script.util.Repository
import java.io.File import java.io.File
@Deprecated("Use new resolving classes from kotlin-scripting-dependencies")
interface Resolver { interface Resolver {
fun tryResolve(dependsOn: DependsOn): Iterable<File>? fun tryResolve(dependsOn: DependsOn): Iterable<File>?
fun tryAddRepo(annotation: Repository): Boolean fun tryAddRepo(annotation: Repository): Boolean