Immplement default cache in main-kts

This commit is contained in:
Ilya Chernikov
2020-01-15 18:02:33 +01:00
parent a4752087db
commit 1b65ec75ad
4 changed files with 146 additions and 33 deletions
@@ -13,6 +13,7 @@ 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.security.MessageDigest
import kotlin.script.dependencies.ScriptContents
import kotlin.script.dependencies.ScriptDependenciesResolver
import kotlin.script.experimental.annotations.KotlinScript
@@ -21,11 +22,11 @@ import kotlin.script.experimental.dependencies.CompoundDependenciesResolver
import kotlin.script.experimental.dependencies.FileSystemDependenciesResolver
import kotlin.script.experimental.host.FileBasedScriptSource
import kotlin.script.experimental.host.FileScriptSource
import kotlin.script.experimental.host.ScriptingHostConfiguration
import kotlin.script.experimental.jvm.*
import kotlin.script.experimental.jvm.compat.mapLegacyDiagnosticSeverity
import kotlin.script.experimental.jvm.compat.mapLegacyScriptPosition
import kotlin.script.experimental.jvm.dependenciesFromClassContext
import kotlin.script.experimental.jvm.jvm
import kotlin.script.experimental.jvm.updateClasspath
import kotlin.script.experimental.jvmhost.CompiledScriptJarsCache
import kotlin.script.experimental.jvmhost.jsr223.configureProvidedPropertiesFromJsr223Context
import kotlin.script.experimental.jvmhost.jsr223.importAllBindings
import kotlin.script.experimental.jvmhost.jsr223.jsr223
@@ -38,7 +39,10 @@ import kotlin.script.experimental.jvmhost.jsr223.jsr223
)
abstract class MainKtsScript(val args: Array<String>)
object MainKtsScriptDefinition : ScriptCompilationConfiguration(
const val COMPILED_SCRIPTS_CACHE_DIR_ENV_VAR = "KOTLIN_MAIN_KTS_COMPILED_SCRIPTS_CACHE_DIR"
const val COMPILED_SCRIPTS_CACHE_DIR_PROPERTY = "kotlin.main.kts.compiled.scripts.cache.dir"
class MainKtsScriptDefinition : ScriptCompilationConfiguration(
{
defaultImports(DependsOn::class, Repository::class, Import::class, CompilerOptions::class)
jvm {
@@ -54,15 +58,45 @@ object MainKtsScriptDefinition : ScriptCompilationConfiguration(
jsr223 {
importAllBindings(true)
}
hostConfiguration(ScriptingHostConfiguration {
jvm {
val cacheExtSetting = System.getProperty(COMPILED_SCRIPTS_CACHE_DIR_PROPERTY)
?: System.getenv(COMPILED_SCRIPTS_CACHE_DIR_ENV_VAR)
val cacheBaseDir = when {
cacheExtSetting == null -> System.getProperty("java.io.tmpdir")
?.let(::File)?.takeIf { it.exists() && it.isDirectory }
?.let { File(it, "main.kts.compiled.cache").apply { mkdir() } }
cacheExtSetting.isBlank() -> null
else -> File(cacheExtSetting)
}?.takeIf { it.exists() && it.isDirectory }
if (cacheBaseDir != null)
compilationCache(
CompiledScriptJarsCache { script, scriptCompilationConfiguration ->
File(cacheBaseDir, compiledScriptUniqueName(script, scriptCompilationConfiguration) + ".jar")
}
)
}
})
})
object MainKtsEvaluationConfiguration : ScriptEvaluationConfiguration(
{
scriptsInstancesSharing(true)
refineConfigurationBeforeEvaluate(::configureProvidedPropertiesFromJsr223Context)
refineConfigurationBeforeEvaluate(::configureConstructorArgsFromMainArgs)
}
)
fun configureConstructorArgsFromMainArgs(context: ScriptEvaluationConfigurationRefinementContext): ResultWithDiagnostics<ScriptEvaluationConfiguration> {
val mainArgs = context.evaluationConfiguration[ScriptEvaluationConfiguration.jvm.mainArguments]
val res = if (context.evaluationConfiguration[ScriptEvaluationConfiguration.constructorArgs] == null && mainArgs != null) {
context.evaluationConfiguration.with {
constructorArgs(mainArgs)
}
} else context.evaluationConfiguration
return res.asSuccess()
}
class MainKtsConfigurator : RefineScriptCompilationConfigurationHandler {
private val resolver = CompoundDependenciesResolver(FileSystemDependenciesResolver(), IvyResolver())
@@ -114,3 +148,16 @@ class MainKtsConfigurator : RefineScriptCompilationConfigurationHandler {
}
}
private fun compiledScriptUniqueName(script: SourceCode, scriptCompilationConfiguration: ScriptCompilationConfiguration): String {
val digestWrapper = MessageDigest.getInstance("MD5")
digestWrapper.update(script.text.toByteArray())
scriptCompilationConfiguration.notTransientData.entries
.sortedBy { it.key.name }
.forEach {
digestWrapper.update(it.key.name.toByteArray())
digestWrapper.update(it.value.toString().toByteArray())
}
return digestWrapper.digest().toHexString()
}
private fun ByteArray.toHexString(): String = joinToString("", transform = { "%02x".format(it) })