SBT使用集合创建子项目

森纳皮

我一直在寻找是否有可能在一段时间内收效甚微。

使用SBT,是否可以通过编程方式创建子项目,而无需将每个项目明确分配给自己的子项目val

我当前的项目结构如下所示:

root/
    common/ <--- This is another sub-project that others dependOn
    project/
        build.scala
    src/main/scala
    apps/ <--- sub-projects live here
        Sub1/
        Sub2/

Sub1并且Sub2都是他们自己的SBT项目。

我第一次尝试将这些项目链接在一起,如下所示:

// root/project/build.scala
import sbt._
import Keys._
object build extends Build {
  lazy val common = project /* Pseudo-code */
  val names = List("Sub1", "Sub2")
  lazy val deps = names map { name =>
    Project(id = name, base = file(s"apps/$name")).dependsOn(common)
  }

  lazy val finalDeps = common :: deps
  lazy val root = project.in(file(".")).aggregate(finalDeps.map(sbt.Project.projectToRef) :_*)
                 .dependsOn(finalDeps.map(ClassPathDependency(_, None)) :_*)
}

但是,由于SBT使用反射来构建其项目和子项目,所以这是行不通的。

仅在明确说明每个子项目的情况下,它才有效:

lazy val Sub1 = project.in(file("apps/Sub1"))

所以问题是:

有没有办法在SBT中以编程方式构建子项目依赖项?

达科·塞迪奇(Darko Cerdic)

Sbt允许为构建本身进行构建定义:

http://www.scala-sbt.org/release/docs/Getting-Started/Full-Def.html

您可以尝试创建一个包含源生成器的project / project / build.scala文件,如下所示:

// project/project/build.scala
sourceGenerators in Compile <+= sourceManaged in Compile map { out =>
    Generator.generate(out / "generated")
}

编辑:您应该自己实现Generator对象。

该源生成器将依次扫描最顶层的apps文件夹,并为包含所有子项目的对象创建源。

// project/subprojects.scala
// This is autogenerated from the source generator
object Subprojects{
  lazy val Sub1 = project.in(file("apps/Sub1"))
  lazy val Sub2 = project.in(file("apps/Sub2"))
  lazy val all = Seq(Sub1,Sub2)
}

现在在您的主要build.scala中编写:

// project/build.scala
lazy val root = project.in(file("."))
  .aggregate(Subprojects.all.map(sbt.Project.projectToRef) :_*)
  .dependsOn(Subprojects.all.map(ClassPathDependency(_, None)) :_*)

我没有通过编译器来运行所有这些程序,因此可能会出现一些错误,但是该原理应该起作用。

编辑:我在实施解决方案的Github上创建了一个仓库。去那里看看它是如何完成的。

https://github.com/darkocerdic/sbt-auto-subprojects

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章