Оценить kotlin файл сценария с зависимостями - PullRequest
1 голос
/ 10 марта 2020

Вопрос : как выполнить набор файлов kotlin во время выполнения и вернуть из них результат одного kts файла?

Я пишу систему, которая умеет выполнять kts файл с инструкциями. На текущий момент поддерживается следующая схема выполнения:

main.kts - этот файл будет выполнен. Он должен вернуть List<Step>

Однако пользователь может поместить любой другой файл в ту же папку. Например, папка может иметь следующие файлы:

  • main.kts
  • Constants.kt // она имеет некоторые константы
  • Helpers.kt // некоторые дополнительные методы

ScriptEngine имеет методы для оценки кода, однако он имеет только один входной файл.

Вопрос: как я могу попросить ScriptEngine скомпилировать классы в classpath, однако выполнить только один из них?

Это решение не является правильным, поскольку порядок файлов важен (например, сборка завершается неудачно, если первый файл зависит от последнего):

// 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 Ответ

0 голосов
/ 10 марта 2020

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

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

...