使用依赖项评估kotlin脚本文件



问题:如何在运行时执行一组kotlin文件,并从中返回一个kts文件的结果?

我编写了一个系统,它能够用指令执行kts文件。目前,它支持以下执行模式:

main.kts-将执行此文件。应返回List<Step>

但是,用户可以将任何其他文件放在同一文件夹中。例如,文件夹可以有以下文件:

  • main.kts
  • Constants.kt//它有一些常量
  • Helpers.kt//一些附加方法

ScriptEngine有计算代码的方法,但它只有一个输入文件。

问题:如何让ScriptEngine将类编译到类路径中,但只执行其中一个?

这个解决方案是不正确的,因为文件顺序很重要(例如,如果第一个文件依赖于最后一个文件,编译就会失败(:

// there is security issue here
val classLoader = Thread.currentThread().contextClassLoader
val engineManager = ScriptEngineManager(classLoader)
setIdeaIoUseFallback()
val ktsEngine: ScriptEngine = engineManager.getEngineByExtension("kts")
/**
* There is issue here: if file1 requires file2 compilation then execution below fails.
*
* Right way: find the solution to compile whole folder and evaluate the single file.
*/
filesFromFolderExceptMain.forEach {
ktsEngine.eval(it)
}
return ktsEngine.eval(mainScriptFile) as List<Step>

另一种解决方案(可能导致不可预测的编译波动(:

val context = filesFromFolderExceptMain.joinToString(System.lineSeparator()
ktsEngine.eval(context)
return ktsEngine.eval(mainScriptFile) as List<Step>

所以,问题:如何在运行时执行一组kotlin文件,并从中返回一个kts文件的结果?

您应该做的是将@file:Import("Constants.kt", "Helpers.kt")添加到主脚本中(请参阅https://github.com/Kotlin/KEEP/blob/master/proposals/scripting-support.md#kotlin-主kts(。虽然我不确定它是相对于脚本所在的目录还是相对于工作目录。

如果您不希望用户必须这样做,您可以在importedScripts中传递它们。

最新更新