scala sbt scala-2.9

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.