28

I'm using sbt .13 here.

I have this so far:

import sbt._
import Keys._
import play.Project._

object ApplicationBuild extends Build {

  val appVersion = "1.0"

  resolvers += "local maven" at "/Users/blankman/.m2/repository/"

  val commonDependencies = Seq()
  val modelDependencies = Seq(
    "com.typesafe.slick" %% "slick" % "2.0.1",
    "org.slf4j" % "slf4j-nop" % "1.6.4"
  )

  val serviceDependencies = Seq(
    "com.typesafe.slick" %% "slick" % "2.0.1",
    "org.slf4j" % "slf4j-nop" % "1.6.4"
  )

  val webDependencies = Seq(
    //"org.apache.tomcat" % "tomcat-jdbc" % "8.0.3",
    "mysql" % "mysql-connector-java" % "5.1.30",
    "com.typesafe.slick" %% "slick" % "2.0.1"
  )


  lazy val common = Project(
    id = "app-common",
    base = file("app-common"),
    dependencies = commonDependencies
  )

  lazy val models = Project(
    id = "app-models",
    base = file("app-models"),
    settings(modelDependencies: _*)
    )
  ).dependsOn(common)

  lazy val services = Project(
    id = "app-services",
    base = file("app-services"),
    settings = Seq(
      libraryDependencies ++= serviceDependencies
    )
  ).dependsOn(models, common)


  lazy val web = play.Project("app-web", appVersion, webDependencies,
                        path = file("app-web"))
                      .settings(playScalaSettings: _*)
                      .dependsOn(services)

}

This doesn't work. For example, if I go into:

project app-models

and try and compile, it says compile isn't valid or something.

I'm really confused how to set up a project. What is the correct way?

Looking at this slide #10 here http://jsuereth.com/scala/2013/06/11/effective-sbt.html it says I can do:

lazy val web = (
  Project("app-models", file("app-models"))
  settings(
     libraryDependencies += modelDependencies
  )
)

But when I do this I get an error also.

I basically have a few projects inside of sbt:

common
models
services
web (which is play)
  • models depends on commons
  • services depends on commons + models
  • web depends on services

Can someone help me get this to work?

Boann
  • 48,794
  • 16
  • 117
  • 146
Blankman
  • 259,732
  • 324
  • 769
  • 1,199

1 Answers1

47

There are a few issues I found in your build definition, but since you bought up Josh's Effective sbt talk, I think we should go whole hog on the style.

Effective sbt

Here are the files.

project/build.properties

sbt.version=0.13.2

project/play.sbt

val playVersion = "2.2.2"

resolvers += Resolver.typesafeRepo("releases")

addSbtPlugin("com.typesafe.play" % "sbt-plugin" % playVersion) 

project/commons.scala

import sbt._
import Keys._

object Commons {
  val appVersion = "1.0"

  val settings: Seq[Def.Setting[_]] = Seq(
    version := appVersion,
    resolvers += Opts.resolver.mavenLocalFile
  )
}

project/dependencies.scala

import sbt._
import Keys._

object Dependencies {
  val slickVersion = "2.0.1"
  val slick = "com.typesafe.slick" %% "slick" % slickVersion
  val slf4jVersion = "1.6.4"
  val slf4jNop = "org.slf4j" % "slf4j-nop" % slf4jVersion
  val mysqlConnectorVersion = "5.1.30"
  val mysqlConnector = "mysql" % "mysql-connector-java" % mysqlConnectorVersion

  val commonDependencies: Seq[ModuleID] = Seq(
    slick,
    slf4jNop
  )
  val modelDependencies: Seq[ModuleID] = Seq()
  val serviceDependencies: Seq[ModuleID] = Seq()
  val webDependencies: Seq[ModuleID] = Seq(
    mysqlConnector
  )
}

build.sbt

import play.Project._
import Dependencies._

lazy val appCommon = (project in file("app-common")).
  settings(Commons.settings: _*).
  settings(
    libraryDependencies ++= commonDependencies
  )

lazy val appModels = (project in file("app-models")).
  settings(Commons.settings: _*).
  settings(
    libraryDependencies ++= modelDependencies
  ).
  dependsOn(appCommon)

lazy val appServices = (project in file("app-services")).
  settings(Commons.settings: _*).
  settings(
    libraryDependencies ++= serviceDependencies
  ).
  dependsOn(appModels, appCommon)

lazy val appWeb = (project in file("app-web")).
  settings(Commons.settings: _*).
  settings(playScalaSettings: _*).
  dependsOn(appServices)

notes

settings parameter vs settings method

For models and services, you're passing in settings sequence into Project(...) constructor, so the default settings are likely not loaded. You can pass in the default settings manually, or use settings(...) method on Project, which I would recommend.

lazy val appModels = (project in file("app-models")).
  settings(
    libraryDependencies ++= modelDependencies
  ).
  dependsOn(appCommon)

Josh uses postfix notation using parenthesis, but I prefer using dot notation for this, so that's a slight deviation from the talk.

libraryDependencies ++=

As the above example, you have to pass modelDependencies to libraryDependencies. You had it calling directly into settings.

resolvers

The resolvers setting is not passed into anything, which likely is not correct.

Eugene Yokota
  • 94,654
  • 45
  • 215
  • 319
  • in my play project, the template created plugins.sbt, should I delete that now? Also, you seem to have the logic in build.sbt whereas I have it in build.scala, any difference? – Blankman Apr 21 '14 at 03:49
  • also, should I remove build.sbt from commons, models and service projects also? Eugene, thanks a ton for this! I was pretty depressed that I couldn't get this too work and was feeling like this just wasn't going to work out for me (play/scala) although I love the framework :) – Blankman Apr 21 '14 at 03:59
  • also, how can I make the web project the default project? – Blankman Apr 21 '14 at 04:11
  • 3
    You can delete `project/plugins.sbt`. Effective sbt talks about breaking the file up. `build.sbt` or `project/Build.scala` is a matter of preference, but Effective sbt uses `build.sbt`. You don't need `build.sbt` in individual sub project if you've done what I did. Please open new questions for the followups. (I've probably violated StackOverflow guidelines for answering other questions) – Eugene Yokota Apr 21 '14 at 04:36
  • *"I've probably violated StackOverflow guidelines for answering other questions"* oh, yes, you have...so many times :-) – Jacek Laskowski Apr 21 '14 at 08:13
  • @EugeneYokota what about setting the scalaVersion, is that a good idea? – Blankman May 17 '14 at 02:32
  • Where and how should I set the scala and java version? – Blankman Jun 27 '14 at 15:53
  • @EugeneYokota Awesome answer - quick question, is this still valid with play 2.3, or on the "web" app would you want to do .enablePlugins(PlayScala)? – Patrick White Jul 14 '15 at 22:42
  • @EugeneYokota, fantastic post, thanks for tkaing the time to offer a great answer - how much the Effective SBT approach be used for multiple modules? – null Mar 01 '16 at 14:05