libraryDependencies on sbt Build.scala Full Configuration with sub-projects - scala

I have a project foo with two children foo-core and foo-cli, foo-cli depends on foo-core
(I come from Java/Maven and tried to transpose the parent module with 2 submodules architecture).
Following https://github.com/harrah/xsbt/wiki/Full-Configuration, I wrote my project/Build.scala this way:
import sbt._
import Keys._
object MyBuild extends Build {
//Dependencies
val slf4s = "com.weiglewilczek.slf4s" %% "slf4s" % "1.0.6"
val slf4j = "org.slf4j" %% "slf4j-simple" % "1.5.6"
val grizzled = "org.clapper" %% "grizzled-slf4j" % "0.5"
val junit = "junit" % "junit" % "4.8" % "test"
//End dependencies
lazy val root : Project = Project("root", file(".")) aggregate(cli) settings(
mainClass:= Some("Main")
)
lazy val core : Project = Project("core", file("core"), delegates = root :: Nil) settings(
name := "foo-core",
libraryDependencies ++= Seq(grizzled)
)
lazy val cli: Project = Project("cli", file("cli")) dependsOn(core) settings(
name := "foo-cli",
libraryDependencies ++= Seq(grizzled)
)
}
This configuration does not work: grizzled library is not dowloaded when I run sbt reload;sbt +update (as indicated in http://software.clapper.org/grizzled-slf4j/) and thus the "import grizzli._" fail in my core and cli projects when I sbt compile.
Since I'm new to scala/sbt I imagine I'm doing something awful but can't figure why since I'm confused with all sbt 0.7/sbt0.10 conflicting configurations that were suggested
(like Subproject dependencies in SBT).
Any idea? Hint that could help me?
Thanks in advance

That's grizzled, not grizzli you are using as dependency. The import is:
import grizzled._
This works here from console on project cli and project core, with nothing more than the configuration file above.
Are you using SBT 0.10?

Related

SBT published jar corrupt

I am having a really strange problem:
I have a multi-module sbt project containing libraries that I publish locally.
Every once in a while the published jar is really a POM file!
Meaning I can open it with a text editor and see the POM for the library in question instead of the class files.
cleaning and rebuilding/republishing sometimes fixes it temporarily.
Also note that the jar in 'target/scala-2.11' is also a POM file.
Here is the Build.scala and sbt file for the libraries. (names are changed to protect the guilty :) due to company policies)
//////////////////Build.scala
import java.io._
import java.nio.file.{Paths, Files}
import sbt._
import xerial.sbt.Pack._
object Library extends Build {
lazy val rootProj = Project(id = "library", base = file(".")) aggregate(
projA,
projB,
projC,
projD
)
lazy val projA = Project(id = "projectA", base = file("ProjectA"))
lazy val projB = Project(id = "projectB", base = file("ProjectB"))
lazy val projC = Project(id = "projectC", base = file("ProjectC"))
.dependsOn(spatialMathProj)
lazy val projD = Project(id = "projectD", base = file("ProjectD"))
}
//////////////////build.sbt for projectD
name := "ProjectD"
version := "2.0-SNAPSHOT"
scalaVersion := "2.11.8"
publishArtifact in (Compile, packageDoc) := false
publishArtifact in (Compile, packageSrc) := false
libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.4.2"
libraryDependencies += "com.typesafe.akka" %% "akka-remote" % "2.4.2"
libraryDependencies += "net.sf.jung" % "jung2" % "2.0.1"
libraryDependencies += "net.sf.jung" % "jung-graph-impl" % "2.0.1"
libraryDependencies += "net.sf.jung" % "jung-visualization" % "2.0.1"
libraryDependencies += "com.plexsys" % "api_2.11" % "2.0-SNAPSHOT"
Has anyone else seen this?
Why is this happening?
I am using sbt version 0.13.7.
Thanks for any help you can offer.

Adding module dependency information in sbt's build.sbt file

I have a multi module project in IntelliJ, as in this screen capture shows, contexProcessor module depends on contextSummary module.
IntelliJ takes care of everything once I setup the dependencies in Project Structure.
However, when I run sbt test with the following setup in build.sbt, I got an error complaining that it can't find the packages in contextSummary module.
name := "contextProcessor"
version := "1.0"
scalaVersion := "2.11.7"
libraryDependencies += "org.scalatest" % "scalatest_2.11" % "2.2.2" % "test"
How to teach sbt that the missing modules are found?
I could use the build.sbt file in the main root directory.
lazy val root = (project in file(".")).aggregate(contextSummary, contextProcessor)
lazy val contextSummary = project
lazy val contextProcessor = project.dependsOn(contextSummary)
Reference: http://www.scala-sbt.org/0.13.5/docs/Getting-Started/Multi-Project.html
For testing only one project, I can use project command in sbt.
> sbt
[info] Set current project to root (in build file:/Users/smcho/Desktop/code/ContextSharingSimulation/)
> project contextProcessor
[info] Set current project to contextProcessor (in build file:/Users/smcho/Desktop/code/ContextSharingSimulation/)
> test
For batch mode as in How to pass command line args to program in SBT 0.13.1?
sbt "project contextProcessor" test
I think a simple build.sbt might not be enough for that.
You would need to create a more sophisticated project/Build.scala like that:
import sbt._
import sbt.Keys._
object Build extends Build {
lazy val root = Project(
id = "root",
base = file("."),
aggregate = Seq(module1, module2)
)
lazy val module1 = Project(
id = "module1",
base = file("module1-folder"),
settings = Seq(
name := "Module 1",
version := "1.0",
scalaVersion := "2.11.7",
libraryDependencies += "org.scalatest" % "scalatest_2.11" % "2.2.2" % "test"
lazy val module2 = Project(
id = "module2",
base = file("module2-folder"),
dependencies = Seq(module1),
settings = Seq(
name := "Module 2",
version := "1.0",
scalaVersion := "2.11.7",
libraryDependencies += "org.scalatest" % "scalatest_2.11" % "2.2.2" % "test"
}

How to use SBT IntegrationTest configuration from Scala objects

To make our multi-project build more manageable we split up our Build.scala file into several files, e.g. Dependencies.scala contains all dependencies:
import sbt._
object Dependencies {
val slf4j_api = "org.slf4j" % "slf4j-api" % "1.7.7"
...
}
We want to add integration tests to our build. Following the SBT documentation we added
object Build extends sbt.Build {
import Dependencies._
import BuildSettings._
import Version._
import MergeStrategies.custom
lazy val root = Project(
id = "root",
base = file("."),
settings = buildSettings ++ Seq(Git.checkNoLocalChanges, TestReport.testReport)
).configs(IntegrationTest).settings(Defaults.itSettings: _*)
...
}
where Dependencies, BuildSettings, Version and MergeStrategies are custom Scala objects definied in their own files.
Following the documentation we want to add some dependencies for the IntegrationTest configuration in Dependencies.scala:
import sbt._
object Dependencies {
val slf4j_api = "org.slf4j" % "slf4j-api" % "1.7.7"
val junit = "junit" % "junit" % "4.11" % "test,it"
...
}
Unfortunately this breaks the build:
java.lang.IllegalArgumentException: Cannot add dependency
'junit#junit;4.11' to configuration 'it' of module ... because this configuration doesn't exist!
I guess I need to import the IntegrationTest configuration. I tried importing the IntegrationTest configuration in Dependencies.scala:
import sbt.Configurations.IntegrationTest
IntegrationTest is a lazy val defined in the Configurations object:
object Configurations {
...
lazy val IntegrationTest = config("it") extend (Runtime)
...
}
But that did not solve the problem.
Does someone has an idea how to solve this?
You need to add the config to the Project object before you add the dependency to the Project object.
Your code quotes show you doing the former, but you don't show where you are doing the latter in your quoted code.
Please could you post the full config, or try moving those two around each other?
Here is where the config is added to the Project object in the SBT docs you linked to:
lazy val root = (project in file(".")).
configs(IntegrationTest).
Your quoted code above which declares a lazy val but does not use it is not sufficient to get the "it" config into use:
lazy val IntegrationTest = config("it") extend (Runtime)

How to set-up the sbt-proguard plugin in Build.scala

I want to use the sbt-proguard plugin in my project, but I need to set it up in a Build.scala file.
I read the documentation but there is just an example for the build.sbt file, which won't work in my case. I need to know how to configure the plugin for my Build.scala file.
Here's the link to the repo: https://github.com/sbt/sbt-proguard/blob/master/README.md#example
FYI: I'm using scala.version=2.11.4 and sbt.version=0.13.5
(Note: sbt currently recommends multi-project build.sbt instead of build.scala.)
Some of the sbt plugins use scripted to test itself, which sets up fake builds under src/sbt-test. If you find one it could contain nice samples on how to set up the plugin.
sbt-proguard created a sample called akka supposedly used by Akka project.
import sbt._
import sbt.Keys._
import com.typesafe.sbt.SbtProguard._
object SampleBuild extends Build {
import ProguardKeys.{ mergeStrategies, merge, options }
import ProguardOptions.keepMain
import ProguardMerge.append
lazy val proguardAkka = Project(
id = "proguard-akka",
base = file("."),
settings = Defaults.defaultSettings ++ proguardSettings ++ Seq(
scalaVersion := "2.10.1",
libraryDependencies += "com.typesafe.akka" %% "akka-remote" % "2.1.2",
merge in Proguard := true,
mergeStrategies in Proguard += append("reference.conf"),
options in Proguard += keepMain("A"),
options in Proguard += keepMain("B"),
options in Proguard += "-dontoptimize", // reduce time for proguard
options in Proguard += ProguardConf.akka
)
)
}
object ProguardConf {
val akka = ....
}

Factoring libraryDependencies in multi project Build.sbt

I'm trying to write a concise multi project Build.sbt, so I tried to put all library dependencies in root project and then make others depends on it. My Build.sbt looks like the following:
object KataBuild extends Build {
lazy val fizzBuzz = Project(
id = "fizzBuzz",
base = file("fizzBuzz"),
settings = Project.defaultSettings ++ Seq(
name := "fizzBuzz",
version := "1.0",
scalaVersion := "2.10.3"
)
)
lazy val kata = Project(
id = "scala-kata",
base = file("."),
settings = Project.defaultSettings ++ Seq(
name := "scala-kata",
version := "1.0",
scalaVersion := "2.10.3",
libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest" % "2.1.0" % "test"
)
)
) aggregate(fizzBuzz)
fizzBuzz dependsOn(kata)
}
But running test from the main project (scala-kata) fails to build test for fizzBuzz. What am I missing?
Your question is similar to this one. In short, fizzBuzz.dependsOn(kata) means that its compile configuration depends on the kata's compile configuration, but you want to link the test configurations.
The 'Per-configuration classpath dependencies' section of the sbt docs show you how you can make a test->test dependency instead.
However, if you are not going to use kata's test sources but are just looking for a way to include Scala-Test in fizzBuzz, just add it explicitly to fizzBuzz's library dependencies, too. You can define a helper value
lazy val scalaTest = "org.scalatest" %% "scalatest" % "2.1.0" % "test"
Then you can add it to be sub project's library dependencies (libraryDependencies += scalaTest).