pat*_*rit 8 scala sbt slick slick-2.0 slick-codegen
我正在开发一个sbt插件,它使用Slick代码生成器为数据库生成Scala模型
我当然希望用户覆盖代码生成器,所以我的插件需要支持这个:
无论如何,我可以动态加载一个Scala类,给出build.sbt插件中的路径吗?例如,在用户的父build.sbt,她会提供像codegen.override=com.company.project.CustomCodegenerator它看起来是这样的
与上述有关; 自定义codegen可能会使用其他一些库,因此简单的动态类加载可能不够.无论如何,一个sbt插件可以使用该插件继承项目的依赖项?
以下是对此的全面讨论:https://github.com/papauschek/play-slick-evolutions-plugin/issues/1
最终,您需要运行一些代码来生成 Scala 源文件。
如您所知,sbt 有一个用于生成名为 的源文件的钩子sourceGenerators,该钩子记录在生成文件中。作为插件作者,您应该提供一个使用 Slick 代码生成器作为默认实现生成的Seq[File]任务(sourceManaged in Compile).value / "garfield"。我们就这样称呼吧generateModel。您的插件可能具有以下设置:
sourceGenerators in Compile += generateModel.taskValue,
generateModel := defaultGenerateModel.value,
defaultGenerateModel := { ... }
Run Code Online (Sandbox Code Playgroud)
如果您的构建用户想要重新连接generateModel,他或她可以这样做:
generateModel := {
val file = (sourceManaged in Compile).value / "garfield" / "Foo.scala"
IO.write(file, """case class Foo() {}""")
Seq(file)
}
Run Code Online (Sandbox Code Playgroud)
如果代码生成包含在 sbt 插件中(如上所述),则不需要执行任何动态操作。由于play-slick-evolutions-codegen-plugin依赖于 slick-codegen,所以这应该不是问题。
由于问题直接涉及动态加载用户的代码,因此我也会提供一些指针。
sbt.RunAPI 。这相当于run使用一些自定义参数调用任务。如果您正在生成Compile配置代码,那么使用运行器进行任何依赖于它的配置并不是一个好主意。sbt.ForkAPI 。分叉允许您在插件外部运行代码。鉴于 sbt 会根据任务之间的依赖关系自动排序任务并并行运行多个任务,动态执行代码充满了意想不到的危险。