如何在SBT中切换项目和库依赖项?

时间:2013-01-31 10:07:35

标签: scala sbt

在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将这两个依赖关系视为完全不同。是否有更直接的方式在项目和库依赖项之间切换,而不是重写我的构建定义?

2 个答案:

答案 0 :(得分:3)

我的sbt脚本有一些场景(测试,发布,制作)。我从脚本(来自bash,你可能有其他环境)开始使用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定义由一个环境变量控制。环境变量会影响所有项目/子项目。

答案 1 :(得分:3)

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

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

  1. 像往常一样声明依赖

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

    $ sbt
    > projects add ../RichUtil
    
  3. Setting up sbt environment to hack on multiple libraries at once中描述的基于约定的方法是一种特殊情况,并且也可以通过这种方式启用。