简体   繁体   中英

If I have an SBT multi-project build, how can I make A's test dependencies not leak in to B's tests

So, I have an SBT project with modules A and B.

  • A depends on B.
  • A and B's normal project packages are compatible.
  • A has a package for testing that is incompatible with a package that B uses for tests.
  • A does not depend on B's test packages
  • A's tests fail, because of the test package incompatibility

In my eyes, this failure is invalid, because A's tests do not depend on B's tests.

I'm using

A.dependsOn(B % "compile->compile;test->compile")

meaning

  • A's compile depends on B's compile
  • A's test depends on B's compile.

Am I doing something wrong?

Here's the actual build file . Relevant project is doobieSupport23 depending on core

Here's the build error . You can see that it's pulling in scalaz 7.2 in the build, but it should only be pulling scalaz 7.1.6

The problem is definitely not in projects depending on each other, the configuration "compile->compile;test->compile" , as it seems to me, is perfectly valid for what you need to achieve.

What's causing the problem is that your libraryDependencies are shared due to A being dependent on B. Fortunately, sbt allows to manage dependencies quite precisely.

The easiest suggestion would be to apply a newer version of the conflicting dependency to a scope as narrow as possible - meaning, if scalaz 7.2.0 is only needed in core's tests, so be it!

lazy val core = project(...)
  .settings(libraryDependencies in Test += "org.scalaz" %% "scalaz" % "7.2.0")
lazy val doobieSupport23 = project(...).dependsOn(core)
  .settings(libraryDependencies in Test += "org.scalaz" %% "scalaz" % "7.1.6")

If you can't make it work because the newer version is actually used in other core's dependencies, the following trick may do it:

val scalazOld = "org.scalaz" %% "scalaz" % "7.1.6"
val scalazNew = "org.scalaz" %% "scalaz" % "7.2.0"

lazy val core = project(...)
  .settings(libraryDependencies += "org.scalaz" %% "scalaz" % "7.2.0")

lazy val doobieSupport23 = project(...).dependsOn(core)
  .settings(
    libraryDependencies in Test += "org.scalaz" %% "scalaz" % "7.1.6" force()
  )

Note the force() combinator. I'm not sure this way it won't fail in runtime due to incompatible classes in classpath.

What I had specified in the issue works exactly as expected.

The problem ended up being that my build file had an extraneous dependency that I had just glossed over. That dependency was causing doobie 3.0 being pulled in where I only expected doobie 2.3.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM