我working on a sbt plugin使用Slick code generator
为数据库生成Scala模型我当然希望用户覆盖代码生成器,因此我的插件需要支持:
无论如何,我可以动态加载一个Scala类,在build.sbt插件中给出一个路径吗?例如,在用户的父build.sbt中,她会提供类似codegen.override=com.company.project.CustomCodegenerator
looks like this
与上述有关;自定义codegen可能会使用其他一些库,因此简单的动态类加载可能不够。无论如何,一个sbt插件可以使用该插件继承项目的依赖项?
以下是对此的完整讨论:https://github.com/papauschek/play-slick-evolutions-plugin/issues/1
答案 0 :(得分:3)
在一天结束时,您需要运行一些代码来生成Scala源文件。
如您所知,sbt有一个用于生成名为sourceGenerators
的源文件的钩子,在Generating files中有记录。
作为插件作者,您应该使用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。 Forking允许您在插件之外运行代码。鉴于sbt会根据它们之间的依赖关系自动排序任务并且并行运行多个任务,动态执行代码充满了意想不到的危险。