Tapping into your build system to automatically generate source code that includes build information (version, date, dependencies) is not only smart, it should be the standard. For Maven-based Java projects, I've long had a technique I use in every project by defining it in a standard parent pom.xml file used in every project. For Play framework's SBT-based build system, there fortunately is a plugin (sbt-buildinfo) which can accomplish the same result with just a few simple tweaks.
Add the sbt-buildinfo plugin to your project/play.plugins
file:
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.2.5")
Add this import statement to the top of your project/Build.scala
file:
import sbtbuildinfo.Plugin._
At this point I start to diverge from the standard instructions for sbt-buildinfo. Their instructions are mainly targeted at SBT users while mine are targeted at Play framework users. In a standard project/Build.scala
file, this is usually what the assignment of val main
looks like after creating a new play project:
val main = play.Project(appName, appVersion, appDependencies).settings( // settings go here )
I prefer to make two key changes to trigger auto generation of a build info class that contains the application version, build date, scala version, and build time in milliseconds. First, we'll merge sbt-buildinfo's settings. Second, we'll override them with our settings. The new assignment of val main
now looks like:
val main = play.Project(appName, appVersion, appDependencies).settings( buildInfoSettings: _* ).settings( sourceGenerators in Compile <+= buildInfo, buildInfoPackage := "com.mfizz.sample", buildInfoKeys ++= Seq[BuildInfoKey] ( "builtAt" -> { val dtf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss") dtf.setTimeZone(java.util.TimeZone.getTimeZone("UTC")) dtf.format(new java.util.Date()) }, "builtAtMillis" -> { System.currentTimeMillis() } ) )
Go ahead and run play compile
to test if your setup works. Once compilation successfully completes, based on the example above, a BuildInfo.scala
file should exist here:
target/scala-2.10/src_managed/main/sbt-buildinfo/BuildInfo.scala
If you modify appVersion
in project/Build.scala
and run play compile
another time, you'll notice that BuildInfo.scala
will reflect that change. You can now use that class in the rest of your project. For example, you can now access the version in Java like so:
String ver = com.mfizz.sample.BuildInfo.version;
All of the class properties are accessed like static properties from Java. Our custom tweaks also expose a builtAt
property that is the build compilation date in UTC "2013-04-21 01:07:33"
and builtAtMillis
which is the saved long from System.currentTimeMillis()
at compile time.
The BuildInfo.scala
will look like this:
package com.mfizz.sample case object BuildInfo { val name = "play-sample" val version = "1.0-SNAPSHOT" val scalaVersion = "2.10.0" val sbtVersion = "0.12.2" val builtAt = "2013-04-13 01:07:33" val builtAtMillis = 1373677653249L }
Your published jars or tarballs will now contain a compiled class that will forever contain the version and build date. These can be useful to access for numerous reasons -- they have come in handy in countless situations over the years.
Updates? Need assistance?
Follow @fizzed_inc on Twitter for future updates and latest news.
If you have specific issues, questions, or problems, please contact us with your inquiry or consulting request.