设置sbt环境一次攻击多个库

kes*_*kes 7 scala sbt

在Sbt中是否有相当于Leiningen的"结账"功能?

这是我想要完成的:

我有两个项目,一个应用程序Foo和库" Bar ".我想独立发布这些项目. Foo依赖于Bar,并且每当第三方尝试构建"Foo"(这是典型行为)时,sbt项目将指示sbt 从存储库下载" Bar " 的jar .

现在,说我想同时攻击FooBar.例如,在处理Foo时,我想直接编辑和调试Bar的一些源代码,因此编辑会影响Foo(稍后在方便的时候重建Bar).

在此黑客会话期间,如何指示sbt 从我的机器(而不是我的本地存储库)上的源代码中满足其对Bar的依赖?

(PS我问过Clojure/Leiningen 的类似问题 .Leiningen有"结账"功能来完成这个.我想知道是否有类似的东西......)

小智 9

您可以通过项目引用声明从Foo到Bar的源依赖项:

import sbt._

object FooBuild extends Build {
  lazy val root = Project(
    id = "foo",
    base = file(".")
  ) dependsOn(theBarBuild)

  lazy val theBarBuild = ProjectRef(
    base = file("/path/to/bar"),
    id = "bar")
}
Run Code Online (Sandbox Code Playgroud)

每当编译Foo时,这也应该重新编译Bar(如果它已经改变).请注意,id项目引用的必须与Bar项目的实际id匹配,例如,default-edd2f8如果您使用简单的构建定义(.sbt仅限文件).

这种技术对于插件特别有用(请参阅我关于此主题的博客文章).

编辑:

您可以像这样重新编码结帐行为:

import sbt._

object FooBuild extends Build {
  lazy val root = addCheckouts(Project(id = "foo", base = file(".")))

  def addCheckouts(proj: Project): Project = {
    val checkouts = proj.base.getCanonicalFile / "checkouts"
    if (! checkouts.exists) proj
    else proj.dependsOn(IO.listFiles(DirectoryFilter)(checkouts).map { dir =>
      ProjectRef(base = dir, id = dir.name): ClasspathDep[ProjectReference]
    }:_*)
  }
}
Run Code Online (Sandbox Code Playgroud)

这将检查项目目录中的checkouts目录,如果存在,则将其中的目录(应该是符号链接到其他项目)添加为项目的项目引用.它期望将符号链接命名为链接项目的实际ID(例如default-edd2f8bar).如果目录不存在,那么构建就像以前一样工作.

在checkouts目录(或目录本身)中添加或删除符号链接时,必须重新加载Foo项目以获取更改.

希望这可以帮助.

  • 您也可以使用`RootProject(dir)`来选择根项目而不指定项目ID. (5认同)