SBT including the version number in a program

前端 未结 4 1146
春和景丽
春和景丽 2020-12-13 19:36

I want a program I\'m building to be able to report its own version at runtime (e.g. scala myprog.jar --version). Traditionally in a maven project, I\'d use res

相关标签:
4条回答
  • 2020-12-13 20:12

    Use the xsbt-reflect plugin. It will generate a source file that contains, among other things, the project version number.

    0 讨论(0)
  • 2020-12-13 20:20

    In general, without any plugins, you can do something like this:

    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
    

    And then do with foo.bar.BuildInfo.Version constant whatever you like.

    Or more 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
    

    Example:

    settings(generateBuildInfo("foo.bar"))
    

    You can even change this to pass object properties as a Map[String, String] and generate the object appropriately.

    0 讨论(0)
  • 2020-12-13 20:24

    Update...

    https://github.com/ritschwumm/xsbt-reflect (mentioned above) is Obsolete, but there is this cool SBT release tool that can automatically manage versions and more: https://github.com/sbt/sbt-release.

    Alternatively, if you want a quick fix you can get version from manifest like this:

    val version: String = getClass.getPackage.getImplementationVersion
    

    This value will be equal to version setting in your project which you set either in build.sbt or Build.scala.

    Another Update ...

    Buildinfo SBT plugin can generate a class with version number based on 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)
    }
    

    See the docs on how to enable it here: https://github.com/sbt/sbt-buildinfo/.

    0 讨论(0)
  • 2020-12-13 20:26

    I ended up making the build system (I use a Makefile on top of sbt) prepare a src/main/resources/version.txt file for Scala to read.

    In the Makefile:

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

    In Scala:

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

    This works for me.

    It's curious that such a needed feature (I would think) is not easily available in Scala. A very simple sbt plugin just for this would be welcome.

    0 讨论(0)
提交回复
热议问题