scala - SBT incluyendo el número de versión en un programa
scala-2.9 (4)
Quiero un programa que estoy creando para poder reportar su propia versión en tiempo de ejecución (por ejemplo, scala myprog.jar --version
). Tradicionalmente, en un proyecto de Maven, usaba el filtrado de recursos (pom.xml -> file.properties -> valor de lectura en tiempo de ejecución). Sé que sbt-filter-plugin emula esta funcionalidad, pero tengo curiosidad por saber si hay una forma más estándar / preferida / inteligente de hacer esto en SBT.
tl; dr ¿cómo puedo leer el número de versión definido en build.sbt
en tiempo de ejecución?
Actualizar...
https://github.com/ritschwumm/xsbt-reflect (mencionado anteriormente) es Obsoleto, pero existe esta herramienta de lanzamiento SBT que puede administrar automáticamente versiones y más: https://github.com/sbt/sbt-release
Alternativamente, si desea una solución rápida, puede obtener una versión de manifiesto como esta:
val version: String = getClass.getPackage.getImplementationVersion
Este valor será igual a la configuración de version
en su proyecto que estableció en build.sbt
o Build.scala
.
Otra actualización ...
El complemento Buildinfo SBT puede generar una clase con un número de versión basado en build.sbt
:
/** 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)
}
Consulte los documentos sobre cómo habilitarlo aquí: github.com/sbt/sbt-buildinfo .
En general, sin ningún complemento, puedes hacer algo como esto:
sourceGenerators in Compile += Def.task {
val file = (sourceManaged in Compile).value / "foo" / "bar" / "BuildInfo.scala"
IO.write(
file,
s"""package foo.bar
|object BuildInfo {
| val Version = "${version.value}"
|}""".stripMargin
)
Seq(file)
}.taskValue
Y luego hazlo con foo.bar.BuildInfo.Version
constante lo que quieras.
O más general:
def generateBuildInfo(packageName: String,
objectName: String = "BuildInfo"): Setting[_] =
sourceGenerators in Compile += Def.task {
val file =
packageName
.split(''.'')
.foldLeft((sourceManaged in Compile).value)(_ / _) / s"$objectName.scala"
IO.write(
file,
s"""package $packageName
|object $objectName {
| val Version = "${version.value}"
|}""".stripMargin
)
Seq(file)
}.taskValue
Ejemplo:
settings(generateBuildInfo("foo.bar"))
Incluso puede cambiar esto para pasar las propiedades del objeto como un Map[String, String]
y generar el objeto adecuadamente.
Terminé haciendo el sistema de compilación (uso un Makefile
encima de sbt
) preparando un archivo src/main/resources/version.txt
para que Scala lo lea.
En el Makefile
:
$(RESOURCES_VERSION): build.sbt
grep "^version := " $< | cut -f2 -d/" > $@
En Scala:
val version: String = {
val src = Source.fromURL( getClass.getResource("/version.txt") )
src.getLines.next // just take the first line
}
Esto funciona para mí.
Es curioso que una característica tan necesaria (creo que) no esté fácilmente disponible en Scala. Un plugin sbt
muy simple solo por esto sería bienvenido.
Utilice el https://github.com/ritschwumm/xsbt-reflect . Generará un archivo fuente que contiene, entre otras cosas, el número de versión del proyecto.