From 3732422e6aae31175b882309971610191d036507 Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Mon, 5 Feb 2018 16:00:59 +0100 Subject: [PATCH] Add example scripting hosts with tests: the simple scripting host and the one with maven resolving --- .../scripting/jvm-maven-deps/build.gradle.kts | 1 + .../script/examples/jvm/resolve/maven/host.kt | 111 ++++++++++++++++++ .../examples/jvm/resolve/maven/scriptDef.kt | 19 +++ .../jvm/resolve/maven/test/resolveTest.kt | 47 ++++++++ .../testData/hello-maven-resolve-error.kts | 5 + .../testData/hello-maven-resolve-junit.kts | 7 ++ .../testData/hello-unresolved-junit.kts | 5 + .../jvm-simple-script/build.gradle.kts | 1 + .../kotlin/script/examples/jvm/simple/host.kt | 64 ++++++++++ .../script/examples/jvm/simple/scriptDef.kt | 16 +++ .../examples/jvm/simple/test/simpleTest.kt | 36 ++++++ .../jvm-simple-script/testData/error.kts | 3 + .../jvm-simple-script/testData/hello.kts | 3 + .../kotlin/script/util/impl/pathUtil.kt | 2 +- 14 files changed, 319 insertions(+), 1 deletion(-) create mode 100644 libraries/examples/scripting/jvm-maven-deps/build.gradle.kts create mode 100644 libraries/examples/scripting/jvm-maven-deps/src/org/jetbrains/kotlin/script/examples/jvm/resolve/maven/host.kt create mode 100644 libraries/examples/scripting/jvm-maven-deps/src/org/jetbrains/kotlin/script/examples/jvm/resolve/maven/scriptDef.kt create mode 100644 libraries/examples/scripting/jvm-maven-deps/test/org/jetbrains/kotlin/script/examples/jvm/resolve/maven/test/resolveTest.kt create mode 100644 libraries/examples/scripting/jvm-maven-deps/testData/hello-maven-resolve-error.kts create mode 100644 libraries/examples/scripting/jvm-maven-deps/testData/hello-maven-resolve-junit.kts create mode 100644 libraries/examples/scripting/jvm-maven-deps/testData/hello-unresolved-junit.kts create mode 100644 libraries/examples/scripting/jvm-simple-script/build.gradle.kts create mode 100644 libraries/examples/scripting/jvm-simple-script/src/org/jetbrains/kotlin/script/examples/jvm/simple/host.kt create mode 100644 libraries/examples/scripting/jvm-simple-script/src/org/jetbrains/kotlin/script/examples/jvm/simple/scriptDef.kt create mode 100644 libraries/examples/scripting/jvm-simple-script/test/org/jetbrains/kotlin/script/examples/jvm/simple/test/simpleTest.kt create mode 100644 libraries/examples/scripting/jvm-simple-script/testData/error.kts create mode 100644 libraries/examples/scripting/jvm-simple-script/testData/hello.kts diff --git a/libraries/examples/scripting/jvm-maven-deps/build.gradle.kts b/libraries/examples/scripting/jvm-maven-deps/build.gradle.kts new file mode 100644 index 00000000000..a87d58dfd71 --- /dev/null +++ b/libraries/examples/scripting/jvm-maven-deps/build.gradle.kts @@ -0,0 +1 @@ +import org.jetbrains.kotlin.gradle.dsl.Coroutines apply { plugin("kotlin") } dependencies { compile(project(":kotlin-script-runtime")) compile(project(":kotlin-scripting-jvm-host")) compile(project(":kotlin-script-util")) compile(projectDist(":kotlin-stdlib")) compile(projectDist(":kotlin-reflect")) compileOnly(project(":compiler:util")) runtime(projectDist(":kotlin-compiler")) testCompile(commonDep("junit")) testRuntime("com.jcabi:jcabi-aether:0.10.1") testRuntime("org.sonatype.aether:aether-api:1.13.1") testRuntime("org.apache.maven:maven-core:3.0.3") } sourceSets { "main" { projectDefault() } "test" { projectDefault() } } kotlin { experimental.coroutines = Coroutines.ENABLE } \ No newline at end of file diff --git a/libraries/examples/scripting/jvm-maven-deps/src/org/jetbrains/kotlin/script/examples/jvm/resolve/maven/host.kt b/libraries/examples/scripting/jvm-maven-deps/src/org/jetbrains/kotlin/script/examples/jvm/resolve/maven/host.kt new file mode 100644 index 00000000000..304649d1d8c --- /dev/null +++ b/libraries/examples/scripting/jvm-maven-deps/src/org/jetbrains/kotlin/script/examples/jvm/resolve/maven/host.kt @@ -0,0 +1,111 @@ +/* + * Copyright 2000-2018 JetBrains s.r.o. 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.script.examples.jvm.resolve.maven + +import org.jetbrains.kotlin.script.util.* +import org.jetbrains.kotlin.script.util.impl.getResourcePathForClass +import java.io.File +import kotlin.reflect.KClass +import kotlin.script.dependencies.ScriptContents +import kotlin.script.dependencies.ScriptDependenciesResolver +import kotlin.script.experimental.api.* +import kotlin.script.experimental.definitions.ScriptDefinitionFromAnnotatedBaseClass +import kotlin.script.experimental.host.toScriptSource +import kotlin.script.experimental.jvm.* +import kotlin.script.experimental.jvmhost.impl.KJVMCompilerImpl + +val stdlibFile: File by lazy { + KotlinJars.stdlib + ?: throw Exception("Unable to find kotlin stdlib, please specify it explicitly via \"kotlin.java.stdlib.jar\" property") +} + +val selfFile: File by lazy { + getResourcePathForClass(MyScriptWithMavenDeps::class.java).takeIf(File::exists) + ?: throw Exception("Unable to get path to the script base") +} + +val scriptUtilsJarFile: File by lazy { + getResourcePathForClass(DependsOn::class.java).takeIf(File::exists) + ?: throw Exception("Unable to get path to the kotlin-script-util.jar") +} + +class MyConfigurator(val baseClass: KClass? = null) : ScriptConfigurator { + + private val resolver = FilesAndMavenResolver() + + override suspend fun baseConfiguration(scriptSource: ScriptSource?) : ResultWithDiagnostics = + myJvmConfig(scriptSource.toConfigEntry()).asSuccess() + + override suspend fun refineConfiguration( + configuration: ScriptCompileConfiguration, + processedScriptData: ProcessedScriptData + ): ResultWithDiagnostics { + val annotations = processedScriptData.getOrNull(ProcessedScriptDataParams.annotations)?.toList()?.takeIf { it.isNotEmpty() } + ?: return configuration.asSuccess() + val scriptContents = object : ScriptContents { + override val annotations: Iterable = annotations + override val file: File? = null + override val text: CharSequence? = null + } + val diagnostics = arrayListOf() + fun report(severity: ScriptDependenciesResolver.ReportSeverity, message: String, position: ScriptContents.Position?) { + diagnostics.add(ScriptDiagnostic(message, mapLegacyDiagnosticSeverity(severity), mapLegacyScriptPosition(position))) + } + return try { + val newDepsFromResolver = resolver.resolve(scriptContents, emptyMap(), ::report, null).get() + ?: return configuration.asSuccess(diagnostics) + val resolvedClasspath = newDepsFromResolver.classpath.toList().takeIf { it.isNotEmpty() } + ?: return configuration.asSuccess(diagnostics) + val newDependency = JvmDependency(resolvedClasspath) + val updatedDeps = + configuration.getOrNull(ScriptCompileConfigurationParams.dependencies)?.plus(newDependency) ?: listOf(newDependency) + configuration.cloneWith(ScriptCompileConfigurationParams.dependencies to updatedDeps).asSuccess(diagnostics) + } catch (e: Throwable) { + ResultWithDiagnostics.Failure(*diagnostics.toTypedArray(), e.asDiagnostics()) + } + } +} + +fun myJvmConfig(vararg params: Pair, Any?>): ScriptCompileConfiguration = + jvmConfigWithJavaHome( + ScriptCompileConfigurationParams.scriptSignature to ScriptSignature(MyScriptWithMavenDeps::class, ProvidedDeclarations()), + ScriptCompileConfigurationParams.importedPackages to listOf(DependsOn::class.qualifiedName!!, Repository::class.qualifiedName!!), + ScriptCompileConfigurationParams.dependencies to listOf( + JvmDependency(listOf(stdlibFile)), + JvmDependency(listOf(selfFile)), + JvmDependency(listOf(scriptUtilsJarFile)) + ), + ScriptCompileConfigurationParams.updateConfigurationOnAnnotations to listOf(DependsOn::class, Repository::class), + *params + ) + +fun evalFile(scriptFile: File): ResultWithDiagnostics { + val scriptCompiler = JvmScriptCompiler(KJVMCompilerImpl(), DummyCompiledJvmScriptCache()) + val scriptDefinition = ScriptDefinitionFromAnnotatedBaseClass(MyScriptWithMavenDeps::class) + + val host = JvmBasicScriptingHost( + scriptDefinition.configurator, + scriptCompiler, + scriptDefinition.runner + ) + + return host.eval(myJvmConfig(scriptFile.toScriptSource().toConfigEntry()), ScriptEvaluationEnvironment()) +} + +fun main(vararg args: String) { + if (args.size != 1) { + println("usage: