Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi-version build with SBT

Tags:

sbt

I want to implement the following build in SBT:

  • Having multiple scala version
  • Having multiple target version (because of a library dependency)

Let's take for example an external Lib, that exist in version 1.0, 2.0, 3.0, and Scala 2.92, 2.10.2, I would like to compile, assembly and publish:

  • MyProject_externalLib1.0_scala_2.9.2
  • MyProject_externalLib1.0_scala_2.10.2
  • MyProject_externalLib2.0_scala_2.9.2
  • MyProject_externalLib2.0_scala_2.10.2
  • MyProject_externalLib3.0_scala_2.9.2
  • MyProject_externalLib3.0_scala_2.10.2

By default, however, I would want to work in a single version. Only when I launch a release processes, all the versions should be compiled and tested and assembled.

Is there a simple way to implement this multiple-version build in Sbt?

like image 581
Edmondo1984 Avatar asked Aug 22 '13 07:08

Edmondo1984


1 Answers

cross building

Having multiple Scala version in sbt is fairly common, and it's called cross building or cross publishing. See sbt's Cross-building page for details. All you have to do is:

scalaVersion := "2.10.2"

crossScalaVersions := Seq("2.10.2", "2.9.2")  

By sbt's naming convention, your published artifact will have binary version post fix, which is _2.10 for Scala 2.10.x, and _2.9.2 for Scala 2.9.2. This is to take advantage of the binary compatibility among the 2.10 series. You can use crossVersion to control that aspect.

cross building against an external library

Cross building against an external library is a bit more tricky. The closet situation I can think of is a plugin for Dispatch. In there, I created a custom setting called dispatchVersion:

lazy val dispatchVersion = SettingKey[String]("x-dispatch-version")

This is set in the buildSettings as

dispatchVersion := "0.10.1"

and my version prefixed with dispatch0.10.0_:

version <<= dispatchVersion { dv => "dispatch" + dv + "_0.1.0" }

Here's how to add dependencies using the key:

libraryDependencies <++= (dispatchVersion) { (dv) => Seq(
  "net.databinder.dispatch" %% "dispatch-core" % dv,
  "net.databinder.dispatch" %% "dispatch-json4s-native" % dv
)}

For Java libraries it should be % instead of %%:

libraryDependencies <++= (externalLibVersion) { (el) => Seq(
  "org.apache" % "foo" % el,
  "org.apache" % "foo-extention" % el
)}

Aside from making a custom plugin like sbt-cross-building, there's no easy way to iterate over a sequence of external versions. You can write a shell script like:

sbt "set externalLibVersion := \"1.0\"" +assembly "set externalLibVersion := \"2.0\"" +assembly "set externalLibVersion := \"3.0\"" +assembly
like image 69
Eugene Yokota Avatar answered Oct 09 '22 02:10

Eugene Yokota