SBT, включая номер версии в программе - PullRequest
21 голосов
/ 22 января 2012

Я хочу, чтобы программа, которую я создаю, могла сообщать о своей собственной версии во время выполнения (например, scala myprog.jar --version). Традиционно в проекте maven я бы использовал фильтрацию ресурсов (pom.xml -> file.properties -> read value во время выполнения). Я знаю, что есть sbt-filter-plugin для эмуляции этой функциональности, но мне интересно, есть ли более стандартный / предпочтительный / умный способ сделать это в SBT.

tl; dr, как я могу прочитать номер версии, определенный в build.sbt во время выполнения?

Ответы [ 4 ]

24 голосов
/ 30 сентября 2013

Обновление ...

https://github.com/ritschwumm/xsbt-reflect (упомянуто выше) устарел, но есть этот замечательный инструмент выпуска SBT, который может автоматически управлять версиями и другими функциями: https://github.com/sbt/sbt-release.

В качестве альтернативы, если вы хотите быстрое исправление, вы можете получить версию из манифеста следующим образом:

val version: String = getClass.getPackage.getImplementationVersion

Это значение будет равно version настройке в вашем проекте, которую вы установили в build.sbt или Build.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/.

7 голосов
/ 22 января 2012

Используйте плагин xsbt-рефлекс .Он сгенерирует исходный файл, который содержит, помимо прочего, номер версии проекта.

3 голосов
/ 19 декабря 2017

В общем, без каких-либо плагинов, вы можете сделать что-то вроде этого:

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"))

Вы можете даже изменить это, чтобы передать свойства объекта как Map[String, String] и сгенерировать объект соответствующим образом.

1 голос
/ 29 июля 2015

В итоге я заставил систему сборки (я использую Makefile поверх sbt) подготовить файл src/main/resources/version.txt для чтения в Scala.

В Makefile:

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

В Scala:

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

Это работает для меня.

Любопытно, что такая необходимая функция (я бы подумал) не легко доступна в Scala.Очень простой плагин sbt только для этого будет приветствоваться.

...