Оцените файл сценария 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 файл от них?

1 ответ

Решение

Что вы должны сделать, это добавить @file:Import("Constants.kt", "Helpers.kt")в основной скрипт (см. https://github.com/Kotlin/KEEP/blob/master/proposals/scripting-support.md). Хотя я не уверен, относится ли это к каталогу, в котором находится скрипт, или к рабочему каталогу.

Если вы не хотите, чтобы пользователи делали это, вы можете передать их в importedScripts.

Другие вопросы по тегам