playframeworksbtsbt-release

Passing value of version in ThisBuild setting defined in version.sbt to artifactName?


I use sbt 0.13 and the sbt-release plugin in order to automatically increment version of a Play application, so I have file version.sbt with the following line:

version in ThisBuild := "1.0-SNAPSHOT"

I also prepare mapping artifact name in order to prepare package with specific name per environment:

val main = play.Project(appName, dependencies = appDependencies).
      settings(
        ...
        artifactName := {(sv: ScalaVersion, module: ModuleID, artifact: Artifact) => {
          val suffix = "-" + sys.props.getOrElse("environment","dev") + (if (artifact.classifier.isDefined) "-" + artifact.classifier.get else "")
          artifact.name + "_" + sv.binary + "-" + version + suffix + "." + artifact.extension
        }},
        ...
      )

Evaluation of above code result in version value equal to 1.0 (probably it is some kind of default) because version.sbt define value as 1.0-SNAPSHOT In lot cases I do something like this in order to use version from ThisBuild:

SomeTask <<= (version in ThisBuild) map { ver => ...
  some ver usage
  ...
}

But this specific solution does not work. Can someone provide an example how to use this specific value in artifactName setting?

Another solution that will help me is to get string value from this variable. Thanks to it I will be able to do next thing:

val appVersion := ... // some operation on version in ThisBuild
val main = play.Project(appName, appVersion, dependencies = appDependencies)

I want to pass the value of the version setting from version.sbt file to artifactName in order to provide the name for produced package.


Solution

  • I work with sbt 0.13.3-SNAPSHOT:

    [sbt-0-13-3]> about
    [info] This is sbt 0.13.3-SNAPSHOT
    [info] The current project is {file:/Users/jacek/sandbox/so/sbt-0.13.3/}sbt-0-13-3 1.0-build_sbt
    [info] The current project is built against Scala 2.11.0-RC3
    [info] Available Plugins: sbt.plugins.IvyModule, sbt.plugins.JvmModule, sbt.plugins.GlobalModule, com.typesafe.sbt.SbtGit, com.typesafe.sbt.SbtProguard, growl.GrowlingTests, org.sbtidea.SbtIdeaPlugin, sbtman.Plugin, np.Plugin, com.timushev.sbt.updates.UpdatesPlugin
    [info] sbt, sbt plugins, and build definitions are using Scala 2.10.3
    

    tl;dr Use (version in ThisBuild).value when you need the value of the version setting in ThisBuild configuration.

    Given the following version.sbt file:

    version in ThisBuild := "1.0-version_sbt"
    

    and the following build.sbt (note (version in ThisBuild).value):

    scalaVersion := "2.11.0-RC3"
    
    version := "1.0-build_sbt"
    
    artifactName := {
      (sv: ScalaVersion, module: ModuleID, artifact: Artifact) => {
        val suffix = "-" + sys.props.getOrElse("environment","dev") + (if (artifact.classifier.isDefined) "-" + artifact.classifier.get else "")
        artifact.name + "_" + sv.binary + "-" + (version in ThisBuild).value + suffix + "." + artifact.extension
      }
    }
    

    sbt shell gave me the following output:

    [sbt-0-13-3]> show makePom::artifactPath
    [info] /Users/jacek/sandbox/so/sbt-0.13.3/target/scala-2.11.0-RC3/sbt-0-13-3_2.11.0-RC3-1.0-version_sbt-dev.pom
    

    I used makePom::artifactPath settings as I've noticed it's a reverse dependency of artifactName (I wouldn't otherwise have been able to display the value of the artifactName function):

    [sbt-0-13-3]> inspect artifactName
    [info] Setting: scala.Function3[sbt.ScalaVersion, sbt.ModuleID, sbt.Artifact, java.lang.String] = <function3>
    [info] Description:
    [info]  Function that produces the artifact name from its definition.
    [info] Provided by:
    [info]  {file:/Users/jacek/sandbox/so/sbt-0.13.3/}sbt-0-13-3/*:artifactName
    [info] Defined at:
    [info]  /Users/jacek/sandbox/so/sbt-0.13.3/build.sbt:5
    [info] Dependencies:
    [info]  {.}/*:version
    [info] Reverse dependencies:
    [info]  *:makePom::artifactPath
    [info] Delegates:
    [info]  *:artifactName
    [info]  {.}/*:artifactName
    [info]  */*:artifactName
    [info] Related:
    [info]  */*:artifactName
    

    As to the case where you want to set the version of a Play project to version in ThisBuild you don't have to worry about it as sbt does this for you.

    val appVersion := ... // some operation on version in ThisBuild
    val main = play.Project(appName, appVersion, dependencies = appDependencies)
    

    What play.Project does (see play.Project.scala on GitHub) is to pass applicationVersion to version and since you set the version in version.sbt it's already set by sbt itself. If you however want to do it explicitly, do as follows:

    version := (version in ThisBuild).value
    

    in build.sbt.

    [sbt-0-13-3]> show version
    [info] 1.0-build_sbt
    [sbt-0-13-3]> reload
    [info] Loading global plugins from /Users/jacek/.sbt/0.13/plugins
    [info] Loading project definition from /Users/jacek/sandbox/so/sbt-0.13.3/project
    [info] Set current project to sbt-0-13-3 (in build file:/Users/jacek/sandbox/so/sbt-0.13.3/)
    [sbt-0-13-3]> show version
    [info] 1.0-version_sbt