sbt 跨项目,测试示例的共享依赖项

sbt cross project, shared dependencies for test example

我有一个小project.

我遇到以下问题:

scalaTest三个依赖工程(client,server,shared)需要全部添加,否则scalatest库是不是来自所有项目的可访问

换句话说,如果我写

 val jvmDependencies = Def.setting(Seq(
   "org.scalaz" %% "scalaz-core" % "7.2.8"
 )++scalaTest)

然后一切正常。

但是如果我不将 ++scalaTest 写入每个三个依赖项,那么它会像这样失败:

> test
[info] Compiling 1 Scala source to /Users/joco/tmp3/server/target/scala-2.11/test-classes...
[error] /Users/joco/tmp3/server/src/test/scala/Test.scala:1: object specs2 is not a member of package org
[error] import org.specs2.mutable.Specification
[error]            ^
[error] /Users/joco/tmp3/server/src/test/scala/Test.scala:3: not found: type Specification
[error] class Test extends Specification {
[error]                    ^
[error] /Users/joco/tmp3/server/src/test/scala/Test.scala:5: value should is not a member of String
[error]   "Test" should {
[error]          ^
[error] /Users/joco/tmp3/server/src/test/scala/Test.scala:6: value in is not a member of String
[error]     "one is one" in {
[error]                  ^
[error] /Users/joco/tmp3/server/src/test/scala/Test.scala:8: value === is not a member of Int
[error]       1===one
[error]        ^
[error] 5 errors found
[error] (server/test:compileIncremental) Compilation failed
[error] Total time: 4 s, completed Mar 18, 2017 1:56:54 PM

然而,对于生产(而非测试)代码,一切正常:如果我想使用一个所有三个项目中的库,仅将其添加到 shared 项目就足够了,然后我可以在所有三个项目中使用该库。

然而,对于测试代码,正如我上面提到的,目前 我必须向所有三个项目添加相同的库依赖项(scalaTest - 下面)

问题:有没有办法避免这种情况?

Settings.scala:

import org.scalajs.sbtplugin.ScalaJSPlugin.autoImport._
import sbt.Keys._
import sbt._

object Settings {
  val scalacOptions = Seq(
    "-Xlint",
    "-unchecked",
    "-deprecation",
    "-feature",
    "-Yrangepos"
  )

  object versions {
    val scala = "2.11.8"
  }

   val scalaTest=Seq(
      "org.scalatest" %% "scalatest" % "3.0.1" % "test",
     "org.specs2" %% "specs2" % "3.7" % "test")

   val sharedDependencies = Def.setting(Seq(
    "com.lihaoyi" %%% "autowire" % "0.2.6"
  )++scalaTest)

 val jvmDependencies = Def.setting(Seq(
   "org.scalaz" %% "scalaz-core" % "7.2.8"
 ))

  /** Dependencies only used by the JS project (note the use of %%% instead of %%) */
  val scalajsDependencies = Def.setting(Seq(
    "org.scala-js" %%% "scalajs-dom" % "0.9.1"
  )++scalaTest)
}

build.sbt:

import sbt.Keys._
import sbt.Project.projectToRef
import webscalajs.SourceMappings

lazy val shared = (crossProject.crossType(CrossType.Pure) in file("shared")) .settings(
    scalaVersion := Settings.versions.scala,
    libraryDependencies ++= Settings.sharedDependencies.value,
    addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full)
) .jsConfigure(_ enablePlugins ScalaJSWeb)

lazy val sharedJVM = shared.jvm.settings(name := "sharedJVM")

lazy val sharedJS = shared.js.settings(name := "sharedJS")

lazy val elideOptions = settingKey[Seq[String]]("Set limit for elidable functions")

lazy val client: Project = (project in file("client"))
  .settings(
    scalaVersion := Settings.versions.scala,
    scalacOptions ++= Settings.scalacOptions,
    libraryDependencies ++= Settings.scalajsDependencies.value,
    testFrameworks += new TestFramework("utest.runner.Framework")
  )
  .enablePlugins(ScalaJSPlugin)
  .disablePlugins(RevolverPlugin)
  .dependsOn(sharedJS)

lazy val clients = Seq(client)

lazy val server = (project in file("server")) .settings(
    scalaVersion := Settings.versions.scala,
    scalacOptions ++= Settings.scalacOptions,
    libraryDependencies ++= Settings.jvmDependencies.value
  )
  .enablePlugins(SbtLess,SbtWeb)
  .aggregate(clients.map(projectToRef): _*)
  .dependsOn(sharedJVM)

onLoad in Global := (Command.process("project server", _: State)) compose (onLoad in Global).value
fork in run := true
cancelable in Global := true

For test code, however, as I mentioned above, currently I have to add the same library dependency (scalaTest - below) to all three projects.

这是意料之中的。 test 依赖关系不会沿依赖链继承。这是有道理的,因为您不想仅仅因为您依赖于恰好使用 JUnit 测试的库而依赖 JUnit。

虽然是的,但当您在同一个构建中有多个项目时,这需要一些重复,所有项目都使用相同的测试框架。这就是为什么我们经常发现一些 commonSettings 被添加到一个 sbt 构建的所有项目中。这也是我们通常放置 organizationscalaVersion 和许多其他通常适用于一个构建中的所有项目的设置的地方。