Home > OS >  Set Dependencies / Plugins versions depending on scalaVersion
Set Dependencies / Plugins versions depending on scalaVersion

Time:11-05

I am trying to set different versions for the dependencies and plugins on my build.sbt script, depending the value of the scalaVersion on a crossCompiled project.

Here is a reduced and simplified representation of what I have so far:

scalaVersion := "2.11.12"
crossScalaVersions := Seq("2.11.12", "2.12.14")


val currentDependencies = Def.setting {
  scalaVersion.value match {
    case "2.11.12" => new {
      val circe         = "0.12.0-M3"
      val kindProjector = "0.10.3"
    }

    case "2.12.14" => new {
      val circe         = "0.14.1"
      val kindProjector = "0.13.2"
    }
  }
}

libraryDependencies   = Seq (
  "io.circe" %% "circe-core" % currentDependencies.value.circe
)

addCompilerPlugin(
  "org.typelevel" %% "kind-projector" % currentDependencies.value.kindProjector
)


The libraryDependencies part is correct, even though it would have been cleaner to not be forced to add the .value part.

Ideally I would have simply declared a Map(scalaV1 -> { dep1 -> v1}, scalaV2 -> { dep1 -> v2} )

But the problem I have is with regards to addCompilerPlugin, as it's not happening within a task or setting, I get the following error:

error: `value` can only be used within a task or setting macro, such as :=,  =,   =, Def.task, or Def.setting.

Is there a cleaner way to achieve what I'm trying to do? And how can I get the right dependency version depending on the scalaVersion for non tasks?

CodePudding user response:

Regarding the libraries, an approach that I've often seen in projects is to do it like this:

libraryDependencies   = {
      CrossVersion.partialVersion(scalaVersion.value) match {
        case Some((2, 12)) =>
          List("groupA" %% "libA" % "x.y.z", "groupB" %% "libB" % "x.y.z")
        case Some((2, 11)) =>
          List("groupA" %% "libA" % "x.y.z", ...)
        case _ =>
          Nil
      }
    }

Which should be transformable to something like this to match your expectation (not tested):

val myVersions: Map[Int, Map[String, String]] = Map(
  11 -> Map("libA" -> "x.y.z", "libB" -> "x.y.z"),
  12 -> Map("libA" -> "x.y.z", "libB" -> "x.y.z")
)

libraryDependencies   = {
      CrossVersion.partialVersion(scalaVersion.value) match {
        case Some((2, n)) =>
          List("groupA" %% "libA" % myVersions(n)("libA"), "groupB" %% "libB" % myVersions(n)("libB"))
        case _ =>
          Nil
      }
    }

Obviously this is just a draft on which the reader can iterate.


Regarding compiler plugin, a similar approach can be used by using the following syntax as replacement for addCompilerPlugin(dependency):

libraryDependencies  = compilerPlugin(dependency)

(Source: https://github.com/sbt/sbt/blob/2dad7ea76385261aa542b5e7410d50d19e1a496a/main/src/main/scala/sbt/Defaults.scala#L4317)

  • Related