I know this because build.sbt knows this.
sbt-buildinfo generates Scala source from your build definitions.
For sbt 1.x add sbt-buildinfo as a dependency in project/plugins.sbt
:
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "x.y.z")
Add the following in your build.sbt
:
lazy val root = (project in file(".")).
enablePlugins(BuildInfoPlugin).
settings(
buildInfoKeys := Seq[BuildInfoKey](name, version, scalaVersion, sbtVersion),
buildInfoPackage := "hello"
)
When you reload the settings and compile, this generates the following:
package hello
/** This object was generated by sbt-buildinfo. */
case object BuildInfo {
/** The value is "helloworld". */
val name: String = "helloworld"
/** The value is "0.1-SNAPSHOT". */
val version: String = "0.1-SNAPSHOT"
/** The value is "2.10.3". */
val scalaVersion: String = "2.10.3"
/** The value is "0.13.2". */
val sbtVersion: String = "0.13.2"
override val toString: String = "name: %s, version: %s, scalaVersion: %s, sbtVersion: %s".format(name, version, scalaVersion, sbtVersion)
}
As this is generated source it will be found under target
, specifically for a Scala 2.11 project under target/scala-2.11/src_managed/main/sbt-buildinfo
Customize buildInfoKeys
by adding whatever keys you want to have in BuildInfo
. You can use BuildInfoKey.map
to change the generated field name and value, add new fields with tuples, or add new fields with values computed at build-time. Note: BuildInfoKey.map
can handle both SettingKey[T]
and TaskKey[T]
types as arguments:
buildInfoKeys ++= Seq[BuildInfoKey](
resolvers,
Test / libraryDependencies,
BuildInfoKey.map(name) { case (k, v) => "project" + k.capitalize -> v.capitalize },
"custom" -> 1234, // computed at project load time
BuildInfoKey.action("buildTime") {
System.currentTimeMillis
} // re-computed each time at compile
)
This generates:
/** The value is Seq("Sonatype Public: https://oss.sonatype.org/content/groups/public"). */
val resolvers: Seq[String] = Seq("Sonatype Public: https://oss.sonatype.org/content/groups/public")
/** The value is Seq("org.scala-lang:scala-library:2.9.1", ...). */
val test_libraryDependencies: Seq[String] = Seq("org.scala-lang:scala-library:2.9.1", ...)
/** The value is "Helloworld". */
val projectName = "Helloworld"
/** The value is 1234. */
val custom = 1234
/** The value is 1346906092160L. */
val buildTime = 1346906092160L
Tasks can be added only if they do not depend on sourceGenerators
. Otherwise, it will cause an infinite loop.
Here's how to change the generated object name:
buildInfoObject := "Info"
This changes the generated object name to object Info
. Changing the object name is optional, but to avoid name clash with other jars, package name should be unique. Use buildInfoPackage
key for this.
buildInfoPackage := "hello"
A build number can be generated as follows. Note that cross building against multiple Scala would each generate a new number.
buildInfoKeys += buildInfoBuildNumber
Add the following option
buildInfoOptions += BuildInfoOption.ToMap
to generate toMap
method:
val toMap = Map[String, Any](
"name" -> name,
"version" -> version,
"scalaVersion" -> scalaVersion,
"sbtVersion" -> sbtVersion)
Add the following option
buildInfoOptions += BuildInfoOption.ToJson
to generate toJson
method.
Add the following option
buildInfoOptions += BuildInfoOption.Traits("TestTrait1", "TestTrait2")
to mixin traits to the generated object.
Add the following option
buildInfoOptions += BuildInfoOption.BuildTime
to add timestamp values:
/** The value is "2015-07-30 03:30:16.849-0700". */
val builtAtString: String = "2015-07-30 03:30:16.849-0700"
/** The value is 1438227016849L. */
val builtAtMillis: Long = 1438227016849L
Set the package using buildInfoPackage
and use the option BuildInfoOption.PackagePrivate
buildInfoPackage := "hello"
buildInfoOptions += BuildInfoOption.PackagePrivate
to make the generated BuildInfo
object package private:
/** This object was generated by sbt-buildinfo. */
private[hello] case object BuildInfo {
...
}
Add the following option
buildInfoOptions += BuildInfoOption.ConstantValue
to have all vals in the BuildInfo
object declared final
and without an explicit type annotation:
/** This object was generated by sbt-buildinfo. */
case object BuildInfo {
/** The value is "helloworld". */
final val name = "helloworld"
...
}
This is particular useful if the values must be constants – e.g., if you need to assign them to annotation arguments.
Add the following option
buildInfoOptions += BuildInfoOption.ImportScalaPredef
to explicitly import scala.Predef._
in the generated code.
package hello
import scala.Predef._
/** This object was generated by sbt-buildinfo. */
case object BuildInfo {
...
}
This import is necessary only when using compiler option -Yno-imports
. Please note, the generated import is not compatible when compiling with Scala 3 compiler option -source:future
because import wildcards must be *
.
MIT License