5

在 SBT 中声明托管库依赖项很容易,例如

 libraryDependencies ++= Seq(
 "org.specs2" %% "specs2" % "1.12.2" % "test" ,
 "junit" % "junit" % "4.7" % "test"
)

虽然在 SBT 中声明项目依赖项并不容易,但我也可以这样做:

object RichMath extends Build {
  lazy val myApp = Project("RichMath", file(".")) dependsOn(richUtil)   
  lazy val richUtil = RootProject(file("../RichUtil"))
}

但在实践中,我通常希望在项目模式和库模式之间切换,在这种模式下更改在上游项目中立即可见,而在库模式中,随着代码的成熟,我必须发布更改才能在依赖项目中看到它们。

在代码库生命的早期,或者每当我想在模块之间进行频繁的更改时,我不希望为了查看上游更改而重新发布的麻烦。但是在稳定/成熟的代码中,我想准确地指定我所依赖的版本。

似乎 SBT 将这两个依赖项视为完全不同的。有没有比重写我的构建定义更直接的方式来在项目依赖和库依赖之间切换?

4

2 回答 2

3

我的 sbt 脚本有一些场景(测试、发布、生产)。例如,我从脚本(从 bash,你可能有其他环境)开始 sbt DO=TESTS sbt。这是我对环境变量的动态依赖:

if (sys.env.contains("LOCAL_BUILD")) {
  Seq[Project.Setting[_]](
    unmanagedResourceDirectories in Compile <+= baseDirectory { _ / "src" / "main" / "scala" },
    libraryDependencies ++= {
      Seq(
        "org.digimead" %% "digi-lib-slf4j" % "0.2.1-SNAPSHOT" % "test",
        "org.digimead" %% "digi-lib-test" % "0.2.1-SNAPSHOT" % "test",
        "org.scalatest" %% "scalatest" % "1.9" % "test"
      )
    }
  )
} else {
  Seq[Project.Setting[_]](
   libraryDependencies ++= {
      Seq(
        "org.slf4j" % "slf4j-log4j12" % "1.7.1"
      )
    }
  )
}

如您所见,我可能有不同的项目设置,单个 .sbt 定义由一个环境变量控制。环境变量影响所有项目/子项目。

于 2013-02-01T02:21:59.533 回答
3

确实,这两种依赖关系的处理方式截然不同,如果不是这样就好了。主要障碍是 sbt 需要在加载设置之前了解所有外部项目(出于各种原因)。

目前,最简单的解决方案可能是另一个答案中描述的环境变量或系统属性。展望未来,以下在 sbt 中非常接近可能,但仍需要更多工作:

  1. 像往常一样声明依赖

    libraryDependencies += "org.example" % "rich-util" % "0.1"
    
  2. 从命令行添加源依赖,过程中自动覆盖正常依赖

    $ sbt
    > projects add ../RichUtil
    

设置 sbt 环境以同时破解多个库中描述的基于约定的方法是一种特殊情况,也可以通过这种工作方式启用。

于 2013-02-02T17:52:38.010 回答