Confused how to set up a multi-project sbt project

playframework, sbt, scala

Solution

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.

Problem

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?

Original source