Skip to content

Commit 6586d05

Browse files
committed
Add script definition with dynamic dependencies downloading example
origin: https://github.com/JetBrains/kotlin/tree/master/libraries/examples/scripting/jvm-maven-deps
1 parent 99ed79a commit 6586d05

File tree

9 files changed

+204
-0
lines changed

9 files changed

+204
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
plugins {
3+
kotlin("jvm")
4+
}
5+
6+
val kotlinVersion: String by rootProject.extra
7+
8+
dependencies {
9+
implementation(project(":jvm:basic:jvm-maven-deps:script"))
10+
implementation("org.jetbrains.kotlin:kotlin-scripting-jvm-host:$kotlinVersion")
11+
testImplementation("junit:junit:4.12")
12+
}
13+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
3+
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
4+
*/
5+
6+
package org.jetbrains.kotlin.script.examples.jvm.resolve.maven.host
7+
8+
import org.jetbrains.kotlin.script.examples.jvm.resolve.maven.ScriptWithMavenDeps
9+
import java.io.File
10+
import kotlin.script.experimental.api.EvaluationResult
11+
import kotlin.script.experimental.api.ResultWithDiagnostics
12+
import kotlin.script.experimental.host.toScriptSource
13+
import kotlin.script.experimental.jvmhost.BasicJvmScriptingHost
14+
import kotlin.script.experimental.jvmhost.createJvmCompilationConfigurationFromTemplate
15+
16+
fun evalFile(scriptFile: File): ResultWithDiagnostics<EvaluationResult> {
17+
18+
val compilationConfiguration = createJvmCompilationConfigurationFromTemplate<ScriptWithMavenDeps>()
19+
20+
return BasicJvmScriptingHost().eval(scriptFile.toScriptSource(), compilationConfiguration, null)
21+
}
22+
23+
fun main(vararg args: String) {
24+
if (args.size != 1) {
25+
println("usage: <app> <script file>")
26+
} else {
27+
val scriptFile = File(args[0])
28+
println("Executing script $scriptFile")
29+
30+
val res = evalFile(scriptFile)
31+
32+
res.reports.forEach {
33+
println(" : ${it.message}" + if (it.exception == null) "" else ": ${it.exception}")
34+
}
35+
}
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
3+
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
4+
*/
5+
6+
package org.jetbrains.kotlin.script.examples.jvm.resolve.maven.test
7+
8+
import org.jetbrains.kotlin.script.examples.jvm.resolve.maven.host.evalFile
9+
import org.junit.Assert
10+
import org.junit.Test
11+
import java.io.File
12+
import kotlin.script.experimental.api.ResultWithDiagnostics
13+
14+
class ResolveTest {
15+
16+
@Test
17+
fun testResolveJunit() {
18+
val res = evalFile(File("testData/hello-maven-resolve-junit.scriptwithdeps.kts"))
19+
20+
Assert.assertTrue(
21+
"test failed:\n ${res.reports.joinToString("\n ") { it.message + if (it.exception == null) "" else ": ${it.exception}" }}",
22+
res is ResultWithDiagnostics.Success
23+
)
24+
}
25+
26+
@Test
27+
fun testUnresolvedJunit() {
28+
val res = evalFile(File("testData/hello-unresolved-junit.scriptwithdeps.kts"))
29+
30+
Assert.assertTrue(
31+
"test failed - expecting a failure with the message \"Unresolved reference: junit\" but received " +
32+
(if (res is ResultWithDiagnostics.Failure) "failure" else "success") +
33+
":\n ${res.reports.joinToString("\n ") { it.message + if (it.exception == null) "" else ": ${it.exception}" }}",
34+
res is ResultWithDiagnostics.Failure && res.reports.any { it.message.contains("Unresolved reference: junit") })
35+
}
36+
37+
@Test
38+
fun testResolveError() {
39+
val res = evalFile(File("testData/hello-maven-resolve-error.scriptwithdeps.kts"))
40+
41+
Assert.assertTrue(
42+
"test failed - expecting a failure with the message \"Unknown set of arguments to maven resolver: abracadabra\" but received " +
43+
(if (res is ResultWithDiagnostics.Failure) "failure" else "success") +
44+
":\n ${res.reports.joinToString("\n ") { it.message + if (it.exception == null) "" else ": ${it.exception}" }}",
45+
res is ResultWithDiagnostics.Failure && res.reports.any { it.message.contains("Unknown set of arguments to maven resolver: abracadabra") })
46+
}
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
@file:DependsOn("abracadabra")
3+
4+
println("Hello, World!")
5+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
@file:DependsOn("junit:junit:4.11")
3+
4+
org.junit.Assert.assertTrue(true)
5+
6+
println("Hello, World!")
7+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
org.junit.Assert.assertTrue(true)
3+
4+
println("Hello, World!")
5+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
plugins {
3+
kotlin("jvm")
4+
}
5+
6+
val kotlinVersion: String by rootProject.extra
7+
8+
dependencies {
9+
implementation("org.jetbrains.kotlin:kotlin-scripting-jvm:$kotlinVersion")
10+
implementation("org.jetbrains.kotlin:kotlin-script-util:$kotlinVersion")
11+
runtimeOnly("com.jcabi:jcabi-aether:0.10.1")
12+
runtimeOnly("org.sonatype.aether:aether-api:1.13.1")
13+
runtimeOnly("org.apache.maven:maven-core:3.0.3")
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
3+
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
4+
*/
5+
6+
package org.jetbrains.kotlin.script.examples.jvm.resolve.maven
7+
8+
import org.jetbrains.kotlin.script.util.DependsOn
9+
import org.jetbrains.kotlin.script.util.FilesAndMavenResolver
10+
import org.jetbrains.kotlin.script.util.Repository
11+
import java.io.File
12+
import kotlin.script.dependencies.ScriptContents
13+
import kotlin.script.dependencies.ScriptDependenciesResolver
14+
import kotlin.script.experimental.annotations.KotlinScript
15+
import kotlin.script.experimental.api.*
16+
import kotlin.script.experimental.jvm.JvmDependency
17+
import kotlin.script.experimental.jvm.compat.mapLegacyDiagnosticSeverity
18+
import kotlin.script.experimental.jvm.compat.mapLegacyScriptPosition
19+
import kotlin.script.experimental.jvm.dependenciesFromCurrentContext
20+
import kotlin.script.experimental.jvm.jvm
21+
import kotlin.script.experimental.jvm.withUpdatedClasspath
22+
23+
@KotlinScript(
24+
fileExtension = "scriptwithdeps.kts",
25+
compilationConfiguration = ScriptWithMavenDepsConfiguration::class
26+
)
27+
abstract class ScriptWithMavenDeps
28+
29+
object ScriptWithMavenDepsConfiguration : ScriptCompilationConfiguration(
30+
{
31+
defaultImports(DependsOn::class, Repository::class)
32+
jvm {
33+
dependenciesFromCurrentContext(
34+
"script", // script library jar name
35+
"kotlin-script-util" // DependsOn annotation is taken from script-util
36+
)
37+
}
38+
refineConfiguration {
39+
onAnnotations(DependsOn::class, Repository::class, handler = ::configureMavenDepsOnAnnotations)
40+
}
41+
}
42+
)
43+
44+
private val resolver = FilesAndMavenResolver()
45+
46+
fun configureMavenDepsOnAnnotations(context: ScriptConfigurationRefinementContext): ResultWithDiagnostics<ScriptCompilationConfiguration> {
47+
val annotations = context.collectedData?.get(ScriptCollectedData.foundAnnotations)?.takeIf { it.isNotEmpty() }
48+
?: return context.compilationConfiguration.asSuccess()
49+
val scriptContents = object : ScriptContents {
50+
override val annotations: Iterable<Annotation> = annotations
51+
override val file: File? = null
52+
override val text: CharSequence? = null
53+
}
54+
val diagnostics = arrayListOf<ScriptDiagnostic>()
55+
fun report(severity: ScriptDependenciesResolver.ReportSeverity, message: String, position: ScriptContents.Position?) {
56+
diagnostics.add(
57+
ScriptDiagnostic(
58+
message,
59+
mapLegacyDiagnosticSeverity(severity),
60+
context.script.locationId,
61+
mapLegacyScriptPosition(position)
62+
)
63+
)
64+
}
65+
return try {
66+
val newDepsFromResolver = resolver.resolve(scriptContents, emptyMap(), ::report, null).get()
67+
?: return context.compilationConfiguration.asSuccess(diagnostics)
68+
val resolvedClasspath = newDepsFromResolver.classpath.toList().takeIf { it.isNotEmpty() }
69+
?: return context.compilationConfiguration.asSuccess(diagnostics)
70+
context.compilationConfiguration.withUpdatedClasspath(resolvedClasspath).asSuccess(diagnostics)
71+
} catch (e: Throwable) {
72+
ResultWithDiagnostics.Failure(*diagnostics.toTypedArray(), e.asDiagnostics(path = context.script.locationId))
73+
}
74+
}
75+

settings.gradle.kts

+2
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ pluginManagement {
99
include("jvm:basic:jvm-simple-script:script")
1010
include("jvm:basic:jvm-simple-script:host")
1111

12+
include("jvm:basic:jvm-maven-deps:script")
13+
include("jvm:basic:jvm-maven-deps:host")

0 commit comments

Comments
 (0)