7

sbt 中是否有与 Leiningen 的“结帐”功能等效的功能?

这是我想要完成的事情:

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

现在,假设我想同时破解FooBar。例如,在处理Foo时,我想直接编辑和调试Bar的一些源代码,以便编辑影响Foo(然后在方便时重建Bar )。

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

(PS 我对 Clojure/Leiningen提出了类似的问题。Leiningen 具有完成此任务的“结帐”功能。我想知道 sbt 中是否有类似的东西......)

4

1 回答 1

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")
}

每当您编译 Foo 时,这也应该重新编译 Bar(如果它已更改)。请注意,id项目引用的 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]
    }:_*)
  }
}

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

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

希望这可以帮助。

于 2013-01-16T06:35:20.220 回答