4

I'm trying to separate various settings from the build definition in my Play! 2.1 application.

I defined some settings in build.sbt as follows:

name := "My Project"
version := 1.0

How can I reuse these values in Build.scala?

object ApplicationBuild extends Build {

  val main = 
    // Doesn't compile since name and version are SettingKeys, not Strings
    play.Project(name, version).settings(
      // ...
    )

}

Thanks a lot!

Ivan Meredith
  • 2,222
  • 14
  • 13
user510159
  • 1,379
  • 14
  • 26

2 Answers2

6

You can use <<= instead of := if you need to access keys (like <+= instead of +=). In this case we want to pull the version and name from the global scope.

val main = play.Project(appName, appVersion, appDependencies).settings(
  version <<= (version in Global)  { v => v} ,
  name <<= (name in Global) { n => n } 
)

Although since this is the default scope we can omit the scope in this case.

val main = play.Project(appName, appVersion, appDependencies).settings(
  version <<= (version)  { v => v} ,
  name <<= (name) { n => n } 
)

An even shorter version of this is simply

val main = play.Project(appName, appVersion, appDependencies).settings(
  version <<= version ,
  name <<= name
)

Note your build.sbt file must go in the root directorying and not the project/ directory.

Ivan Meredith
  • 2,222
  • 14
  • 13
  • Thanks for your answer! However, that means I still have to define appName and appVersion (so that I can call play.Project(...)). Can't I simply use the values I defined in build.sbt? Also, if appName and name are defined to different values, which one will take precedence? – user510159 Dec 11 '12 at 09:37
  • Whichever setting is applied last is the one that has precedence for the project. The problem is in https://github.com/playframework/Play20/blob/master/framework/src/sbt-plugin/src/main/scala/play/Project.scala#L44 - it sets the version, which means you have to set it again, AFTER it is done in that code. In this case appName and appVersion could just be "blah" and it would be overridden. – Ivan Meredith Dec 11 '12 at 09:49
  • OK, thanks! I accepted your answer. This still sounds to me like those parameters are unnecessary and confusing. It would be just fine with play.Project() (i.e. no parameters). – user510159 Dec 11 '12 at 11:50
  • @IvanMeredith Any chance that you can translate your answer to Java? – Eric Wilson Nov 04 '13 at 20:28
  • @EricWilson I don't understand how this could be java. Play2.x uses sbt which built with scala. – Ivan Meredith Nov 05 '13 at 22:21
  • @IvanMeredith Yeah, I misunderstood the question. After I realized my error, I asked my similar but different question: http://stackoverflow.com/questions/19776828 – Eric Wilson Nov 06 '13 at 13:17
1

The Build.scala cannot access the value that you define in build.sbt, but it works the other way around. Whatever you are trying to do here is practically just trying to hack SBT 0.12.

What I would recommend is for you to define the shared settings in a .scala file, ie. Settings.scala. And then you can refer to these shared settings from both Build.scala and build.sbt.

Settings.scala

object Settings {
  appName:= "My Project"
  appVersion:= 1.0
}

Build.scala

object ApplicationBuild extends Build {
  val main = play.Project(appName, appVersion, appDependencies)...
}

build.sbt

name := Settings.appName
version := Settings.appVersion

Of course the story will be different if you use Play 2.2 with SBT 0.13. :)

Let me know if this makes sense and feel cleaner for you.

suriyanto
  • 1,075
  • 12
  • 19