SBT doesn't call Test.Setup on a Play2 project - scala

Here is my SBT build:
val main = play.Project(appName, appVersion, appDependencies).settings(defaultScalaSettings:_*)
.settings(
scalaVersion := "2.10.0",
resolvers += .....
)
.configs(IntegrationTest)
.settings( Defaults.itSettings : _*)
.settings(
testOptions in Test += Tests.Setup( () => println("Setup Test yoohooo") ),
testOptions in Test += Tests.Cleanup( () => println("Cleanup Test yoohoo") ),
scalaSource in Test <<= baseDirectory / "test/unit",
parallelExecution in Test := true,
testOptions in IntegrationTest += Tests.Setup( () => println("Setup Integration Test yoohoo") ),
testOptions in IntegrationTest += Tests.Cleanup( () => println("Cleanup Integration Test yoohoo") ),
scalaSource in IntegrationTest <<= baseDirectory / "test/integration",
parallelExecution in IntegrationTest := false
)
I can launch both tasks test and it:test, but it only prints the text for the IntegrationTest, and not for the regular Test.
I see that Play2 has some default settings related:
testOptions in Test += Tests.Setup { loader =>
loader.loadClass("play.api.Logger").getMethod("init", classOf[java.io.File]).invoke(null, new java.io.File("."))
},
testOptions in Test += Tests.Cleanup { loader =>
loader.loadClass("play.api.Logger").getMethod("shutdown").invoke(null)
},
Isn't my build supposed to override these settings?
By the way, can I call an external library or a test source class in this Setup?

Maybe this is constraint of sbt.
sbt official documents says
Setup and Cleanup actions are not supported when a group is forked.
https://github.com/sbt/sbt/blob/v0.12.2/src/sphinx/Detailed-Topics/Testing.rst#forking-tests
http://www.scala-sbt.org/0.12.2/docs/Detailed-Topics/Testing.html
fork in Test := true
is default from Play2.1.0
https://github.com/playframework/Play20/pull/654/files#L5L110

Related

How to apply common test configuration to all projects?

I'm migrating an old project to Scala 3. The build.sbt is as follows:
import Dependencies._
inThisBuild(
Seq(
scalaVersion := "2.12.7",
scalacOptions ++= Seq(
"-unchecked",
// more
)
)
++ inConfig(Test)(Seq(
testOptions += Tests.Argument(TestFrameworks.ScalaTest, "-o", "-e"),
// more
))
)
lazy val root = (project in file("."))
.aggregate(
`test-util`
)
lazy val `test-util` = project
Now, I want to separate stuff inside inThisBuild for legibility.
import Dependencies._
ThisBuild / scalaVersion := "3.0.1"
ThisBuild / scalacOptions ++= Seq(
"-unchecked",
// more
)
lazy val testSettings = inConfig(Test)(
Seq(
testOptions += Tests.Argument(TestFrameworks.ScalaTest, "-o", "-e"),
// more
))
lazy val root = (project in file("."))
.aggregate(
`test-util`
)
.settings(testSettings)
lazy val `test-util` = project
As you can see, I'm having to apply the testSettings for each project. Ideally, I'd like to do something like ThisBuild / Test := testSettings but that is not valid syntax.
Is there a way to apply the testSettings to all projects without having to explicitly set .settings(testSettings)?
Edit:
I understand I can write each line of testSettings with ThisBuild / Test prefix, but I’d rather not repeat the same prefix. I’m looking for something like what I’ve done with scalacOptions.
Is there a way to apply the testSettings to all projects without having to explicitly set .settings(testSettings)
Consider creating an auto plugin which can inject settings automatically in all the sub-projects, for example in project/CommonTestSettings.scala
import sbt._
import Keys._
object CommonTestSettings extends sbt.AutoPlugin {
override def requires = plugins.JvmPlugin
override def trigger = allRequirements
override lazy val projectSettings =
inConfig(Test)(
Seq(
testOptions += Tests.Argument(TestFrameworks.ScalaTest, "-o", "-e")
// more
)
)
}
You can test with show testOptions which should reveal the common settings in all the sub-projects, for example in my project where root aggregates foo and bar I get something like
sbt:sbt-multi-project> show testOptions
[info] foo / Test / testOptions
[info] List(Argument(Some(TestFramework(org.scalatest.tools.Framework, org.scalatest.tools.ScalaTestFramework)),List(-o, -e)))
[info] bar / Test / testOptions
[info] List(Argument(Some(TestFramework(org.scalatest.tools.Framework, org.scalatest.tools.ScalaTestFramework)),List(-o, -e)))
[info] Test / testOptions
[info] List(Argument(Some(TestFramework(org.scalatest.tools.Framework, org.scalatest.tools.ScalaTestFramework)),List(-o, -e)))
As you can done with scalaVersion and scalacOptions, you can do with Test. For example:
lazy val testSettings = inConfig(Test)(
Seq(
testOptions += Tests.Argument(TestFrameworks.ScalaTest, "-o", "-e"),
// more
))
Can be rewritten as:
ThisBuild / Test / testOptions += Test.Argument(TestFrameworks.ScalaTest, "-o", "-e")
Is it this that you want? Or do you want to pass a sequence directly?

sbt conditional if else style configuration

I want to be able to switch between parallel and serial execution of scala tests using command line.
Working example with "test.par" system property:
val parallelTestOpt = Option(System.getProperty("test.par"))
testOptions in IntegrationTest += Tests.Argument(
//Configure distributor's pool size
parallelTestOpt.map(count =>s"-P$count").getOrElse("-P1")
)
lazy val root = (project in file("."))
.configs(IntegrationTest)
.settings(Defaults.itSettings,
//If suites are executed in parallel
IntegrationTest / parallelExecution := parallelTestOpt.exists(_ != "1"),
IntegrationTest / testForkedParallel := parallelTestOpt.exists(_ != "1")
)
The "problematic" part is the parallelTestOpt.map(count =>s"-P$count").getOrElse("-P1"). I don't want to provide default value "-P1" when the "test.par" property was not specified. What is the best practice to achieve that ?
Maybe the whole concept is wrong and I should do it in a different way ?
As an alternative approach consider separating the parallelism concern into a single-argument custom command
commands += Command.single("testpar") { (state, numOfThreads) =>
s"""set IntegrationTest / testOptions += Tests.Argument("-P$numOfThreads")"""::
"set IntegrationTest / parallelExecution := true" ::
"set IntegrationTest / testForkedParallel := true" ::
"IntegrationTest / test" :: state
}
and execute with, say, testpar 6 to run with pool of 6 threads.
Addressing the comment, for compile-time safety try
commands += Command.single("testpar") { (state, numOfThreads) =>
val extracted = Project.extract(state)
val stateWithParallel= extracted.appendWithSession(
Seq(
IntegrationTest / testOptions += Tests.Argument(s"-P$numOfThreads"),
IntegrationTest / parallelExecution := true,
IntegrationTest / testForkedParallel := true,
),
state
)
extracted.runTask(IntegrationTest / test, stateWithParallel)
state
}

sbt run Play as a sumodule

I was wondering if I can run Play in development as a submodule?
Here is the project structure:
Root
submodule1
submodule2(Play)
submodule3
......
There is only one build.sbt file under the root level, which specified the structure of the project.
Previously, I had the Play module as a separate project, which has its own build.sbt, and I could simply run it in development mode with sbt run.
However, after I combined the Play module with the other modules into one project, sbt "project projectName" run can still start the Play module in development mode, but when I tried to hit any endpoint, I got injection error, such as No implementation for models.services.UserService was bound.
Here is a portion of the build.sbt. emberconflagration is the Play project.
lazy val root = project
.in(file("."))
.aggregate(embercore)
.aggregate(emberdataset)
.aggregate(emberconflagration)
.aggregate(emberservice)
.aggregate(embersession)
.aggregate(emberetl)
.aggregate(embermodel)
.aggregate(emberclient)
.aggregate(emberserver)
.aggregate(emberservermongo)
.aggregate(emberstreaming)
.settings(commonSettings: _*)
.settings(name := "ember-conflagration-root")
lazy val embercore = (project in file("./embercore"))
.settings(commonSettings: _*)
.settings(testSettings: _*)
.settings(
name := "embercore",
libraryDependencies ++= Seq(
Libraries.scalatest,
Libraries.play_json
),
resolvers ++= Seq(
"Apache Repository" at "https://repository.apache.org/content/repositories/releases/",
"Cloudera Repository" at "https://repository.cloudera.com/artifactory/cloudera-repos/",
Resolver.sonatypeRepo("public")
),
javaOptions in assembly += "-xmx6g"
)
lazy val emberservice = (project in file("./emberservice"))
.settings(commonSettings: _*)
.settings(testSettings: _*)
.settings(
name := "emberservice",
libraryDependencies ++= Seq(
Libraries.scalatest,
Libraries.play_json,
Libraries.scala_j
),
resolvers ++= Seq(
"Apache Repository" at "https://repository.apache.org/content/repositories/releases/",
"Cloudera Repository" at "https://repository.cloudera.com/artifactory/cloudera-repos/",
Resolver.sonatypeRepo("public")
),
javaOptions in assembly += "-xmx6g"
)
.dependsOn(embercore)
lazy val emberdataset = (project in file("./emberdataset"))
.settings(commonSettings: _*)
.settings(testSettings: _*)
.settings(
name := "emberdataset",
libraryDependencies ++= Seq(
Libraries.scalatest,
Libraries.spark_core_conflP,
Libraries.spark_mllib_conflP,
Libraries.spark_sql_conflP,
Libraries.mysql_connector,
Libraries.spark_xml
),
resolvers ++= Seq(
"Apache Repository" at "https://repository.apache.org/content/repositories/releases/",
"Cloudera Repository" at "https://repository.cloudera.com/artifactory/cloudera-repos/",
Resolver.sonatypeRepo("public")
),
javaOptions in assembly += "-xmx6g"
)
.dependsOn(embercore)
lazy val embersession = (project in file("./embersession"))
.enablePlugins(LauncherJarPlugin)
.settings(commonSettings: _*)
.settings(testSettings: _*)
.settings(
name := "embersession",
libraryDependencies ++= Seq(
Libraries.scalatest,
Libraries.h2o_sparkling_water_core
exclude ("com.fasterxml.jackson.core", "jackson-core")
exclude ("com.fasterxml.jackson.core", "jackson-databind")
exclude ("javax.servlet", "servlet-api"),
// exclude ("org.apache.spark", "spark-sql_2.11") // Comment out for standard build. Uncomment for EmberSession assembly.
// exclude ("org.apache.spark", "spark-core_2.11") // Comment out for standard build. Uncomment for EmberSession assembly.
// exclude ("org.apache.spark", "spark-mllib_2.11") // Comment out for standard build. Uncomment for EmberSession assembly.
// exclude ("org.apache.hadoop", "hadoop-common"), // Comment out for standard build. Uncomment for EmberSession assembly.
Libraries.jackson_scala,
Libraries.duke,
Libraries.scala_library,
Libraries.spark_core_conflP,
Libraries.spark_mllib_conflP,
Libraries.spark_sql_conflP
),
mainClass in assembly := Some("com.metistream.ember.embersession.Test"),
javaOptions in assembly += "-xmx6g",
resolvers ++= Seq(
"Apache Repository" at "https://repository.apache.org/content/repositories/releases/",
"Cloudera Repository" at "https://repository.cloudera.com/artifactory/cloudera-repos/",
Resolver.sonatypeRepo("public")
),
assemblyShadeRules in assembly ++= Seq(
ShadeRule.rename("com.esotericsoftware.kryo.**" -> "emberkryo.#1").inAll,
ShadeRule.rename("com.fasterxml.jackson.**" -> "emberjackson.#1").inAll,
ShadeRule.rename("play.api.**" -> "emberplay.play.api.#1").inAll
),
assemblyMergeStrategy in assembly := {
case PathList("META-INF", "services", "org.apache.hadoop.fs.FileSystem") => MergeStrategy.filterDistinctLines
case PathList("reference.conf") => MergeStrategy.concat
case PathList("META-INF", xs # _*) => MergeStrategy.discard
case x => MergeStrategy.first
}
)
.dependsOn(embercore, emberdataset, emberservice)
lazy val emberconflagration = (project in file("security-layer"))
.enablePlugins(PlayScala)
.settings(commonSettings: _*)
.settings(testSettings: _*)
.settings(
name := "ember-conflagration",
libraryDependencies ++= Seq(
jdbc,
cache,
ws,
filters,
Libraries.play2_reactivemongo,
Libraries.mockito,
Libraries.embed_mongo,
Libraries.play_silhouette,
Libraries.silhouette_password,
Libraries.silhouette_persistence,
Libraries.silhouette_crypto,
Libraries.silhouette_testkit,
Libraries.scala_guice,
Libraries.ficus,
Libraries.mleap_runtime,
Libraries.google_api_dataproc,
Libraries.scalaj_http,
Libraries.google_core,
Libraries.google_client,
Libraries.google_sqladmin,
Libraries.google_cloud_compute,
Libraries.google_api_services,
Libraries.google_cloud_storage,
Libraries.postgresql_connector,
Libraries.jersey_media_glass,
Libraries.jersey_core_glass,
Libraries.jackson_xml,
Libraries.jackson_scala,
Libraries.janino,
Libraries.play_json_extensions,
Libraries.hapi_base,
Libraries.hapi_structures_v21,
Libraries.hapi_structures_v22,
Libraries.hapi_structures_v23,
Libraries.hapi_structures_v231,
Libraries.hapi_structures_v24,
Libraries.hapi_structures_v25,
Libraries.hapi_structures_v251,
Libraries.hapi_structures_v26,
Libraries.play_quartz_extension,
Libraries.elastic4s_core,
Libraries.elastic4s_http,
Libraries.scalatest,
specs2 % Test,
Libraries.uimaj_core,
Libraries.spark_core_confl,
Libraries.spark_mllib_confl,
Libraries.spark_sql_confl,
Libraries.unbound_id,
Libraries.swagger
),
coverageExcludedPackages := "<empty>;Reverse.*;router\\..*",
// Assembly Settings
assemblyShadeRules in assembly ++= Seq(
ShadeRule
.rename("com.google.common.**" -> "my_guava.#1")
.inLibrary("com.google.api-client" % "google-api-client" % "1.22.0")
),
mainClass in assembly := Some("play.core.server.ProdServerStart"),
fullClasspath in assembly += Attributed.blank(PlayKeys.playPackageAssets.value),
assemblyMergeStrategy in assembly := {
case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard
case PathList("META-INF", xs # _*) => MergeStrategy.first
case x => MergeStrategy.first
},
projectDependencies := {
Seq(
(projectID in emberdataset).value.excludeAll(ExclusionRule(organization = "org.slf4j"),
ExclusionRule(organization = "io.netty"))
)
},
fork in run := false,
resolvers ++= Seq(
"elasticsearch-releases" at "https://artifacts.elastic.co/maven",
"sonatype snapshots" at "https://oss.sonatype.org/content/repositories/snapshots/",
Resolver.bintrayRepo("iheartradio", "maven"),
"Atlassian Releases" at "https://maven.atlassian.com/public/",
Resolver.url("Typesafe Ivy releases", url("https://repo.typesafe.com/typesafe/ivy-releases"))(
Resolver.ivyStylePatterns)
),
javaOptions in assembly += "-xmx6g"
)
.dependsOn(embercore, emberdataset, emberetl)
I think it is just your particular app that doesn't work. This is possibly because you have multiple packages which are colliding with each other. Here's an example that works.
Directory structure
./build.sbt
./mod1
./mod1/src
./mod1/src/main
./mod1/src/main/scala
./mod1/src/main/scala/Hello.scala
./mod2
./mod2/app
./mod2/app/controllers
./mod2/app/controllers/HomeController.scala
./mod2/app/modules/MainModule.scala
./mod2/conf
./mod2/conf/application.conf
./mod2/conf/logback.xml
./mod2/conf/messages
./mod2/conf/routes
./mod3
./mod3/src
./mod3/src/main
./mod3/src/main/scala
./mod3/src/main/scala/Hello.scala
./project/plugins.sbt
Important files:
build.sbt
name := """root"""
organization := "com.example"
version := "1.0-SNAPSHOT"
lazy val mod1 = project in file("mod1")
lazy val mod2 = (project in file("mod2"))
.enablePlugins(PlayScala)
.settings(
name := """myplayproject""",
organization := "com.example",
version := "1.0-SNAPSHOT",
scalaVersion := "2.12.6",
libraryDependencies += guice,
libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "3.1.2" % Test
)
lazy val mod3 = project in file("mod3")
lazy val root = (project in file("."))
.aggregate(mod1)
.aggregate(mod2)
.aggregate(mod3)
HomeController.scala
package controllers
import javax.inject._
import play.api._
import play.api.mvc._
trait MyServiceLike {
def getString: String
}
class MyService extends MyServiceLike {
override def getString: String = "hello"
}
#Singleton
class HomeController #Inject()(cc: ControllerComponents, myService: MyServiceLike) extends AbstractController(cc) {
def index() = Action { implicit request: Request[AnyContent] =>
Ok(myService.getString)
}
}
project/plugins.sbt
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.16")
mod2/conf/application.conf
play.modules.enabled += "modules.MainModule"
mod2/app/modules/MainModule.scala
package modules
import controllers.MyService
import controllers.MyServiceLike
import play.api.Configuration
import play.api.Environment
import play.api.inject.Binding
import play.api.inject.Module
class MainModule extends Module {
override def bindings(environment: Environment, configuration: Configuration): Seq[Binding[_]] = Seq(
bind[MyServiceLike].to[MyService]
)
}
Run
Then, you can run by starting sbt:
project mod2
run

How to avoid writing pom when running docker:publishLocal?

I have two subprojects on build.sbt and one depends on the other (the cli depends on and aggregates core). The core will be published as a library and the cli will be publish as a docker image. The problem is when I do cli/docker:publishLocal I can't avoid the pom being written... How to avoid this? This is the current build.sbt file:
import sbt.Keys._
import sbt._
val scalaBinaryVersionNumber = "2.12"
val scalaVersionNumber = s"$scalaBinaryVersionNumber.4"
resolvers += Resolver.bintrayIvyRepo("sbt", "sbt-plugin-releases")
lazy val aggregatedProjects: Seq[ProjectReference] = Seq(core, cli)
lazy val testDependencies = Dependencies.specs2.map(_ % Test)
lazy val root = project
.in(file("."))
.settings(name := "root")
.settings(inThisBuild(List(
//Credentials for sonatype
credentials += Credentials(
"Sonatype Nexus Repository Manager",
"oss.sonatype.org",
sys.env.getOrElse("SONATYPE_USER", "username"),
sys.env.getOrElse("SONATYPE_PASSWORD", "password")),
scalaVersion := scalaVersionNumber,
version := "0.1.0-SNAPSHOT",
organization := "com.test",
scalacOptions ++= Common.compilerFlags,
scalacOptions.in(Test) ++= Seq("-Yrangepos"),
scalacOptions.in(Compile, console) --= Seq("-Ywarn-unused:imports", "-Xfatal-warnings"))))
.aggregate(aggregatedProjects: _*)
.settings(publish := {}, publishLocal := {}, publishArtifact := false)
lazy val core = project
.in(file("core"))
.settings(name := "core")
.settings(
// App Dependencies
libraryDependencies ++= Seq(
Dependencies.caseApp,
Dependencies.betterFiles,
Dependencies.jodaTime,
Dependencies.fansi,
Dependencies.scalajHttp,
Dependencies.cats) ++
Dependencies.circe ++
Dependencies.jackson ++
Dependencies.log4s
// Test Dependencies
libraryDependencies ++= testDependencies)
.settings(
// Sonatype repository settings
publishMavenStyle := true,
publishArtifact.in(Test) := false,
//publishArtifact.in(makePom.in(Docker)) := false,
publish.in(Docker) := {},
publishLocal.in(Docker) := {},
pomIncludeRepository := { _ =>
false
},
publishTo := sonatypePublishTo.value)
.settings(pomExtra := <scm>
<url>https://github.com/test</url>
<connection>scm:git:git#github.com:test.git</connection>
<developerConnection>scm:git:https://github.com/test.git</developerConnection>
</scm>)
lazy val cli = project
.in(file("cli"))
.enablePlugins(JavaAppPackaging)
.enablePlugins(DockerPlugin)
.settings(name := "cli")
.settings(Common.dockerSettings: _*)
.settings(Common.genericSettings: _*)
.settings(
//publish := publish.in(Docker).value,
//publishLocal := publishLocal.in(Docker).value,
publishArtifact := false)
.settings(libraryDependencies ++= testDependencies)
.dependsOn(core)
.aggregate(core)
// Scapegoat
scalaVersion in ThisBuild := scalaVersionNumber
scalaBinaryVersion in ThisBuild := scalaBinaryVersionNumber
scapegoatDisabledInspections in ThisBuild := Seq()
scapegoatVersion in ThisBuild := "1.3.4"
As you can see, I already tried to add "publishArtifact.in(makePom.in(Docker)) := false" to the core settings but this doesn't write the pom when I do core/publishLocal... I just want to avoid writing the pom when I do cli/docker:publishLocal.

Play sub-projects: how to convert to build.sbt

I've a working multi-module Play 2.2 application which is organized like this...
myApp
+ app
+ conf
+ project
+ build.properties
+ Build.scala
+ plugin.sbt
... where Build.scala contains the following statements:
import sbt._
import Keys._
import play.Project._
object ApplicationBuild extends Build {
val appName = "myApp"
val appVersion = "1.0-SNAPSHOT"
val authDependencies = Seq(
"se.radley" %% "play-plugins-salat" % "1.3.0"
)
val mainDependencies = Seq(
"se.radley" %% "play-plugins-salat" % "1.3.0"
)
lazy val auth = play.Project(
appName + "-auth",
appVersion,
authDependencies,
path = file("modules/auth")).settings(
lessEntryPoints <<= baseDirectory(customLessEntryPoints),
routesImport += "se.radley.plugin.salat.Binders._",
templatesImport += "org.bson.types.ObjectId",
testOptions in Test := Nil,
resolvers ++= Seq(Resolvers.sonatype, Resolvers.scalaSbt)
)
lazy val main = play.Project(
appName,
appVersion,
mainDependencies).settings(
scalacOptions += "-language:reflectiveCalls",
routesImport += "se.radley.plugin.salat.Binders._",
templatesImport += "org.bson.types.ObjectId",
testOptions in Test := Nil,
lessEntryPoints <<= baseDirectory(customLessEntryPoints),
resolvers ++= Seq(Resolvers.sonatype, Resolvers.scalaSbt)
).dependsOn(auth).aggregate(auth)
def customLessEntryPoints(base: File): PathFinder = {
(base / "app" / "assets" / "stylesheets" / "bootstrap" * "bootstrap.less") +++
(base / "app" / "assets" / "stylesheets" * "*.less")
}
}
object Resolvers {
val scalaSbt = Resolver.url("Scala Sbt", url("http://repo.scala-sbt.org/scalasbt/sbt-plugin-snapshots"))(Resolver.ivyStylePatterns)
val sonatype = Resolver.sonatypeRepo("snapshots")
}
Now reading the Play 2.2 documentation it looks like I should convert my project to build.sbt:
The following example uses a build.scala file to declare a play.Project. This approach was the way Play applications were defined prior to version 2.2. The approach is retained in order to support backward compatibility. We recommend that you convert to the build.sbt based approach or, if using a build.scala, you use sbt’s Project type and project macro.
Is there any working example that describes how to replace project/build.scala with build.sbt? I read some short articles here and there... but I was unable to get a working Play project.
There is no urgent need to convert your build to build.sbt. build.sbt is simpler, but basically just gets compiled into Build.scala.
The other answer to this question will work, but is perhaps a little verbose. Start with the SBT documentation:
http://www.scala-sbt.org/0.13.0/docs/Getting-Started/Multi-Project.html
Now, create specify your main project and sub projects, and put your main project settings into your main build.sbt file:
lazy val auth = project.in(file("modules/auth"))
lazy val main = project.in(file(".")).dependsOn(auth).aggregate(auth)
playScalaSettings
name := "myApp"
version := "1.0-SNAPSHOT"
libraryDependencies += "se.radley" %% "play-plugins-salat" % "1.3.0"
scalacOptions += "-language:reflectiveCalls"
routesImport += "se.radley.plugin.salat.Binders._"
templatesImport += "org.bson.types.ObjectId"
testOptions in Test := Nil
lessEntryPoints <<= baseDirectory(customLessEntryPoints)
resolvers ++= Seq(Resolvers.sonatype, Resolvers.scalaSbt)
object Resolvers {
val scalaSbt = Resolver.url("Scala Sbt", url("http://repo.scala-sbt.org/scalasbt/sbt-plugin-snapshots"))(Resolver.ivyStylePatterns)
val sonatype = Resolver.sonatypeRepo("snapshots")
}
And now, in modules/auth/build.sbt, put your settings for the auth module:
name := "myApp-auth"
lessEntryPoints <<= baseDirectory(customLessEntryPoints)
routesImport += "se.radley.plugin.salat.Binders._"
templatesImport += "org.bson.types.ObjectId"
testOptions in Test := Nil
resolvers ++= Seq(Resolvers.sonatype, Resolvers.scalaSbt)
Anyway, it might need a bit of tweaking, but hopefully you get the point.
if using a build.scala, you use sbt’s Project type and project macro
Replace play.Project with Project and fix the arguments according to the ScalaDoc, it should be something like
lazy val auth = Project(
appName + "-auth",
file("modules/auth")).settings(
version := appVersion,
libraryDependencies ++= authDependencies,
lessEntryPoints <<= baseDirectory(customLessEntryPoints),
routesImport += "se.radley.plugin.salat.Binders._",
templatesImport += "org.bson.types.ObjectId",
testOptions in Test := Nil,
resolvers ++= Seq(Resolvers.sonatype, Resolvers.scalaSbt)
)
lazy val main = Project(
appName,
file("app")).settings(
version := appVersion,
libraryDependencies ++= mainDependencies,
scalacOptions += "-language:reflectiveCalls",
routesImport += "se.radley.plugin.salat.Binders._",
templatesImport += "org.bson.types.ObjectId",
testOptions in Test := Nil,
lessEntryPoints <<= baseDirectory(customLessEntryPoints),
resolvers ++= Seq(Resolvers.sonatype, Resolvers.scalaSbt)
).dependsOn(auth).aggregate(auth)
Same definitions can be used in build.sbt instead. I would also extract common settings:
val commonSettings = Seq(
version := appVersion,
routesImport += "se.radley.plugin.salat.Binders._",
templatesImport += "org.bson.types.ObjectId",
testOptions in Test := Nil,
lessEntryPoints <<= baseDirectory(customLessEntryPoints),
resolvers ++= Seq(Resolvers.sonatype, Resolvers.scalaSbt)
)
lazy val auth = Project(
appName + "-auth",
file("modules/auth")).settings(commonSettings: _*).settings(
libraryDependencies ++= authDependencies
)
lazy val main = Project(
appName,
file("app")).settings(commonSettings: _*).settings(
libraryDependencies ++= mainDependencies,
scalacOptions += "-language:reflectiveCalls"
).dependsOn(auth).aggregate(auth)