Fix compiled scripts saving tests:

The tests were broken some time ago by applying script isolation, so
it was necessary to add base libraries into the classpath.
Also refactored some classpath building utilities.
This commit is contained in:
Ilya Chernikov
2019-07-09 15:35:38 +02:00
parent 9c004c3a52
commit c9a4328feb
4 changed files with 43 additions and 14 deletions
@@ -6,8 +6,7 @@
package kotlin.script.experimental.host package kotlin.script.experimental.host
import java.io.File import java.io.File
import java.io.IOError import java.io.Serializable
import java.io.IOException
import java.net.URL import java.net.URL
import kotlin.script.experimental.api.* import kotlin.script.experimental.api.*
@@ -48,7 +47,7 @@ abstract class FileBasedScriptSource() : ExternalSourceCode {
/** /**
* The implementation of the SourceCode for a script located in a file * The implementation of the SourceCode for a script located in a file
*/ */
open class FileScriptSource(override val file: File, private val preloadedText: String? = null) : FileBasedScriptSource() { open class FileScriptSource(override val file: File, private val preloadedText: String? = null) : FileBasedScriptSource(), Serializable {
override val externalLocation: URL get() = file.toURI().toURL() override val externalLocation: URL get() = file.toURI().toURL()
override val text: String by lazy { preloadedText ?: file.readText() } override val text: String by lazy { preloadedText ?: file.readText() }
override val name: String? get() = file.name override val name: String? get() = file.name
@@ -58,12 +57,17 @@ open class FileScriptSource(override val file: File, private val preloadedText:
this === other || (other as? FileScriptSource)?.let { file.absolutePath == it.file.absolutePath && textSafe == it.textSafe } == true this === other || (other as? FileScriptSource)?.let { file.absolutePath == it.file.absolutePath && textSafe == it.textSafe } == true
override fun hashCode(): Int = file.absolutePath.hashCode() + textSafe.hashCode() * 23 override fun hashCode(): Int = file.absolutePath.hashCode() + textSafe.hashCode() * 23
companion object {
@JvmStatic
private val serialVersionUID = 0L
}
} }
/** /**
* The implementation of the SourceCode for a script location pointed by the URL * The implementation of the SourceCode for a script location pointed by the URL
*/ */
open class UrlScriptSource(override val externalLocation: URL) : ExternalSourceCode { open class UrlScriptSource(override val externalLocation: URL) : ExternalSourceCode, Serializable {
override val text: String by lazy { externalLocation.readText() } override val text: String by lazy { externalLocation.readText() }
override val name: String? get() = externalLocation.file override val name: String? get() = externalLocation.file
override val locationId: String? get() = externalLocation.toString() override val locationId: String? get() = externalLocation.toString()
@@ -72,6 +76,11 @@ open class UrlScriptSource(override val externalLocation: URL) : ExternalSourceC
this === other || (other as? UrlScriptSource)?.let { externalLocation == it.externalLocation && textSafe == it.textSafe } == true this === other || (other as? UrlScriptSource)?.let { externalLocation == it.externalLocation && textSafe == it.textSafe } == true
override fun hashCode(): Int = externalLocation.hashCode() + textSafe.hashCode() * 17 override fun hashCode(): Int = externalLocation.hashCode() + textSafe.hashCode() * 17
companion object {
@JvmStatic
private val serialVersionUID = 0L
}
} }
/** /**
@@ -82,7 +91,7 @@ fun File.toScriptSource(): SourceCode = FileScriptSource(this)
/** /**
* The implementation of the ScriptSource for a script in a String * The implementation of the ScriptSource for a script in a String
*/ */
open class StringScriptSource(val source: String, override val name: String? = null) : SourceCode { open class StringScriptSource(val source: String, override val name: String? = null) : SourceCode, Serializable {
override val text: String get() = source override val text: String get() = source
@@ -92,6 +101,11 @@ open class StringScriptSource(val source: String, override val name: String? = n
this === other || (other as? StringScriptSource)?.let { text == it.text && name == it.name && locationId == it.locationId } == true this === other || (other as? StringScriptSource)?.let { text == it.text && name == it.name && locationId == it.locationId } == true
override fun hashCode(): Int = text.hashCode() + name.hashCode() * 17 + locationId.hashCode() * 23 override fun hashCode(): Int = text.hashCode() + name.hashCode() * 17 + locationId.hashCode() * 23
companion object {
@JvmStatic
private val serialVersionUID = 0L
}
} }
/** /**
@@ -29,6 +29,9 @@ import kotlin.script.experimental.host.toScriptSource
import kotlin.script.experimental.jvm.BasicJvmScriptEvaluator import kotlin.script.experimental.jvm.BasicJvmScriptEvaluator
import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration
import kotlin.script.experimental.jvm.impl.KJvmCompiledScript import kotlin.script.experimental.jvm.impl.KJvmCompiledScript
import kotlin.script.experimental.jvm.updateClasspath
import kotlin.script.experimental.jvm.util.KotlinJars
import kotlin.script.experimental.jvm.util.classpathFromClass
import kotlin.script.experimental.jvmhost.* import kotlin.script.experimental.jvmhost.*
import kotlin.script.templates.standard.SimpleScriptTemplate import kotlin.script.templates.standard.SimpleScriptTemplate
@@ -121,7 +124,10 @@ class ScriptingHostTest : TestCase() {
fun testSaveToRunnableJar() { fun testSaveToRunnableJar() {
val greeting = "Hello from script jar!" val greeting = "Hello from script jar!"
val outJar = Files.createTempFile("saveToRunnableJar", ".jar").toFile() val outJar = Files.createTempFile("saveToRunnableJar", ".jar").toFile()
val compilationConfiguration = createJvmCompilationConfigurationFromTemplate<SimpleScriptTemplate>() val compilationConfiguration = createJvmCompilationConfigurationFromTemplate<SimpleScriptTemplate>() {
updateClasspath(classpathFromClass<SimpleScriptTemplate>())
updateClasspath(KotlinJars.kotlinScriptStandardJarsWithReflect)
}
val compiler = JvmScriptCompiler(defaultJvmScriptingHostConfiguration) val compiler = JvmScriptCompiler(defaultJvmScriptingHostConfiguration)
val scriptName = "SavedRunnableScript" val scriptName = "SavedRunnableScript"
val compiledScript = runBlocking { val compiledScript = runBlocking {
@@ -62,12 +62,12 @@ fun ScriptCompilationConfiguration.withUpdatedClasspath(classpath: Collection<Fi
} }
} }
fun ScriptCompilationConfiguration.Builder.updateClasspath(classpath: Collection<File>) = updateClasspathImpl(classpath) fun ScriptCompilationConfiguration.Builder.updateClasspath(classpath: Collection<File>?) = updateClasspathImpl(classpath)
fun JvmScriptCompilationConfigurationBuilder.updateClasspath(classpath: Collection<File>) = updateClasspathImpl(classpath) fun JvmScriptCompilationConfigurationBuilder.updateClasspath(classpath: Collection<File>?) = updateClasspathImpl(classpath)
private fun PropertiesCollection.Builder.updateClasspathImpl(classpath: Collection<File>) { private fun PropertiesCollection.Builder.updateClasspathImpl(classpath: Collection<File>?) {
val newClasspath = classpath.filterNewClasspath(this[ScriptCompilationConfiguration.dependencies]) val newClasspath = classpath?.filterNewClasspath(this[ScriptCompilationConfiguration.dependencies])
?: return ?: return
ScriptCompilationConfiguration.dependencies.append(JvmDependency(newClasspath)) ScriptCompilationConfiguration.dependencies.append(JvmDependency(newClasspath))
@@ -179,12 +179,14 @@ fun classpathFromClasspathProperty(): List<File>? =
fun classpathFromClass(classLoader: ClassLoader, klass: KClass<out Any>): List<File>? = fun classpathFromClass(classLoader: ClassLoader, klass: KClass<out Any>): List<File>? =
classpathFromFQN(classLoader, klass.qualifiedName!!) classpathFromFQN(classLoader, klass.qualifiedName!!)
fun classpathFromClass(klass: KClass<out Any>): List<File>? =
classpathFromClass(klass.java.classLoader, klass)
inline fun <reified T: Any> classpathFromClass(): List<File>? = classpathFromClass(T::class)
fun classpathFromFQN(classLoader: ClassLoader, fqn: String): List<File>? { fun classpathFromFQN(classLoader: ClassLoader, fqn: String): List<File>? {
val clp = "${fqn.replace('.', '/')}.class" val clp = "${fqn.replace('.', '/')}.class"
val url = classLoader.getResource(clp) return classLoader.rawClassPathFromKeyResourcePath(clp).filter { it.isValidClasspathFile() }.toList().takeIf { it.isNotEmpty() }
return url?.toURI()?.path?.removeSuffix(clp)?.let {
listOf(File(it))
}
} }
fun File.matchMaybeVersionedFile(baseName: String) = fun File.matchMaybeVersionedFile(baseName: String) =
@@ -408,4 +410,11 @@ object KotlinJars {
stdlibOrNull, stdlibOrNull,
scriptRuntimeOrNull scriptRuntimeOrNull
).filterNotNull() ).filterNotNull()
val kotlinScriptStandardJarsWithReflect
get() = listOf(
stdlibOrNull,
scriptRuntimeOrNull,
reflectOrNull
).filterNotNull()
} }