25

我希望我正在构建的程序能够在运行时报告它自己的版本(例如scala myprog.jar --version)。传统上,在 maven 项目中,我会使用资源过滤(pom.xml -> file.properties -> 在运行时读取值)。我知道有sbt-filter-plugin可以模拟此功能,但我很好奇在 SBT 中是否有更标准/首选/聪明的方式来执行此操作。

tl;博士如何读取build.sbt运行时定义的版本号?

4

4 回答 4

28

更新...

https://github.com/ritschwumm/xsbt-reflect(上面提到的)已经过时了,但是有一个很酷的 SBT 发布工具可以自动管理版本等等:https ://github.com/sbt/sbt-release 。

或者,如果您想要快速修复,您可以从清单中获取版本,如下所示:

val version: String = getClass.getPackage.getImplementationVersion

此值将等于您在或version中设置的项目中的设置。build.sbtBuild.scala

另一个更新...

Buildinfo SBT 插件可以生成一个带有版本号的类,基于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)
}

在此处查看有关如何启用它的文档:https ://github.com/sbt/sbt-buildinfo/ 。

于 2013-09-30T16:42:13.993 回答
8

使用xsbt-reflect插件。它将生成一个源文件,其中包含项目版本号等内容。

于 2012-01-22T01:42:14.453 回答
5

一般来说,没有任何插件,你可以做这样的事情:

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

然后随心所欲地做foo.bar.BuildInfo.Version任何你喜欢的事情。

或更笼统地说:

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

例子:

settings(generateBuildInfo("foo.bar"))

您甚至可以更改它以将对象属性作为 a 传递Map[String, String]并适当地生成对象。

于 2017-12-19T09:33:05.780 回答
1

我最终让构建系统(我Makefile在上面使用了sbt)准备了一个src/main/resources/version.txt文件供 Scala 读取。

Makefile

$(RESOURCES_VERSION): build.sbt
    grep "^version := " $< | cut -f2 -d\" > $@

在斯卡拉:

val version: String = {
  val src = Source.fromURL( getClass.getResource("/version.txt") )
  src.getLines.next   // just take the first line 
}

这对我有用。

奇怪的是,这样一个需要的特性(我认为)在 Scala 中并不容易获得。一个非常简单的sbt插件将受到欢迎。

于 2015-07-29T07:32:05.540 回答