I want to compile Kotlin scripts within a Kotlin s...
# scripting
p
I want to compile Kotlin scripts within a Kotlin script 😄 just compile, to validate if they compile fine or with a particular error message. So far I'm getting:
Copy code
e: java.lang.ExceptionInInitializerError
...
Caused by: java.lang.ClassCastException: class org.jetbrains.kotlin.idea.KotlinFileType cannot be cast to class org.jetbrains.kotlin.com.intellij.openapi.fileTypes.LanguageFileType (org.jetbrains.kotlin.idea.KotlinFileType and org.jetbrains.kotlin.com.intellij.openapi.fileTypes.LanguageFileType are in unnamed module of loader java.net.URLClassLoader @5d5c04f9
...
my code in the thread
♟ 1
Copy code
#!/usr/bin/env kotlin
@file:DependsOn("org.jetbrains.kotlin:kotlin-compiler:2.1.0")
@file:DependsOn("org.jetbrains.kotlin:kotlin-compiler-embeddable:2.1.0")
@file:DependsOn("org.jetbrains.kotlin:kotlin-main-kts:2.1.0")
@file:DependsOn("org.jetbrains.kotlin:kotlin-scripting-compiler:2.1.0")


import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
import org.jetbrains.kotlin.config.Services
import java.io.ByteArrayOutputStream
import java.io.PrintStream
import java.nio.file.Files.walk
import java.nio.file.Path
import java.nio.file.Paths
import kotlin.io.path.absolutePathString
import kotlin.io.path.createTempDirectory
import kotlin.io.path.isRegularFile

walk(Paths.get("scripts/"))
    .filter { it.isRegularFile() }
    .forEach { it.tryCompiling() }

private fun Path.tryCompiling() {
    val compilationOutput = createTempDirectory()
    val args = K2JVMCompilerArguments().apply {
            destination = compilationOutput.toString()
            freeArgs = listOf(this@tryCompiling.absolutePathString())
            noStdlib = true
            noReflect = true
            allowAnyScriptsInSourceRoots = true
            useFirLT = false
        }
    val compilerMessagesOutputStream = ByteArrayOutputStream()
    val compilerMessageCollector = PrintingMessageCollector(
            PrintStream(compilerMessagesOutputStream),
            MessageRenderer.GRADLE_STYLE,
            false,
        )
    val exitCode = K2JVMCompiler().exec(
            messageCollector = compilerMessageCollector,
            services = Services.EMPTY,
            arguments = args,
        )
    check(exitCode == ExitCode.OK) {
        "Compilation failed! Compiler messages:\n$compilerMessagesOutputStream"
    }
}
@Vampire your PreprocessWorkflowsPlugin.groovy helped me get to the current point a bit, maybe you have some more context and can help?
v
This is the evolution of it actually: https://github.com/spockframework/spock/pull/2092/files 🙂
Actually, the execution I do in a separate process, not in-process.
I guess to begin with you should not depend on the embeddable and non-embeddable compiler
As you try to execute in-process i guess you should use the embeddable
I use the embeddable to parse the kotlin files to determine the imported scripts and the non-embeddable to execute the script out-of-process
With the main-kts dependency not part of the classpath but an argument to
-script
p
thanks, I put this piece of effort on hold for a moment, so I may revisit it one day, and then meaningfully respond