归根结底,您需要运行一些代码来生成 Scala 源文件。
生成文件
如您所知,sbt 有一个用于生成源文件的钩子,称为sourceGenerators
,它记录在生成文件中。作为插件作者,您应该提供一个使用 Slick 代码生成器作为默认实现生成Seq[File]
的任务。(sourceManaged in Compile).value / "garfield"
让我们称之为generateModel
. 您的插件可能具有以下设置:
sourceGenerators in Compile += generateModel.taskValue,
generateModel := defaultGenerateModel.value,
defaultGenerateModel := { ... }
如果您的构建用户想要重新布线generateModel
,他或她可以这样做:
generateModel := {
val file = (sourceManaged in Compile).value / "garfield" / "Foo.scala"
IO.write(file, """case class Foo() {}""")
Seq(file)
}
如果代码生成包含在 sbt 插件中,就像上面一样,你不需要做任何动态的事情。由于play-slick-evolutions-codegen-plugin
依赖于 slick-codegen,这应该不是问题。
动态加载用户代码
由于问题直接在于动态加载用户的代码,因此我也提出了一些指示。
- 一种方法是使用现有配置中的
sbt.Run
API 。这相当于run
使用一些自定义参数调用任务。如果您正在为Compile
配置生成代码,那么将运行器用于任何依赖于它的配置都不是一个好主意。
- 另一种类似的方法是使用
sbt.Fork
API。分叉允许您在插件之外运行代码。
鉴于 sbt 会根据它们之间的依赖关系自动排序任务并并行运行多个任务,动态执行的代码充满了意想不到的危险。