Per-configuration classpath dependencies doesn't work with test->test in SBT? - scala

I've got a multi-project build with scalania main project as well as exercises and answers (sub)projects.
The scalania project is hosted on GitHub.
I'm trying to set up a SBT project configuration where the test classes are part of the exercises project while the answers project provides the solutions.
I read Per-configuration classpath dependencies in the official documentation of SBT and ended up with the following configuration in the scalania main project:
lazy val exercises = project
lazy val answers = project.dependsOn(exercises % "test->test")
It doesn't seem to work and upon test execution I used to get:
> project answers
[info] Set current project to scalania-answers (in build file:/Users/jacek/oss/scalania/)
> test
[info] Passed: Total 0, Failed 0, Errors 0, Passed 0
[info] No tests to run for answers/test:test
[success] Total time: 1 s, completed Oct 27, 2013 1:06:51 AM
It was until I changed answers/build.sbt to the following:
scalaSource in Test := (scalaSource in LocalProject("exercises") in Test).value
It works fine now.
> reload
[info] Loading global plugins from /Users/jacek/.sbt/0.13/plugins
[info] Loading project definition from /Users/jacek/oss/scalania/project
[info] Set current project to scalania-answers (in build file:/Users/jacek/oss/scalania/)
> project answers
[info] Set current project to scalania-answers (in build file:/Users/jacek/oss/scalania/)
> testOnly *s99.P01*
[info] Formatting 19 Scala sources {file:/Users/jacek/oss/scalania/}answers(test) ...
[info] Compiling 19 Scala sources to /Users/jacek/oss/scalania/answers/target/scala-2.10/test-classes...
[info] P01Spec
[info]
[info] P01 solution should
[info] + Find the last element of a list
[info]
[info]
[info] Total for specification P01Spec
[info] Finished in 151 ms
[info] 1 example, 0 failure, 0 error
[info] Passed: Total 1, Failed 0, Errors 0, Passed 1
[success] Total time: 74 s, completed Oct 27, 2013 1:09:07 AM
What's wrong with using project.dependsOn(exercises % "test->test") only? Am I missing something in the build configuration?

Declaring a dependency on tests in another project just makes the classpath available. Running its tests doesn't happen by default because otherwise tests would run multiple times in the common situation of just reusing code.
To run tests in another project, add the discovered tests from the other project to those for the current project:
definedTests in Test :=
(definedTests in Test).value ++
(definedTests in exercises in Test).value

Related

Using sbt run on simple tutorial example does not execute

On a Windows machine, I am running through the getting started tutorial here: https://www.scala-sbt.org/1.x/docs/sbt-by-example.html
I am able to start the sbt shell and compile but using the run command just hangs and I am forced to Ctrl-C to exit sbt.
Running scala against the JAR file directly also works as expected.
Sample output is the following:
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=256m; support was removed in 8.0
[info] Loading project definition from S:\foo-build\project
[info] Loading settings for project foo-build from build.sbt ...
[info] Set current project to foo-build (in build file:/S:/foo-build/)
[info] sbt server started at local:sbt-server-8c6933abcb6848dbd242
sbt:foo-build> about
[info] This is sbt 1.2.8
[info] The current project is ProjectRef(uri("file:/S:/foo-build/"), "foo-build") 0.1.0-SNAPSHOT
[info] The current project is built against Scala 2.12.7
[info] Available Plugins
[info] - sbt.ScriptedPlugin
[info] - sbt.plugins.CorePlugin
[info] - sbt.plugins.Giter8TemplatePlugin
[info] - sbt.plugins.IvyPlugin
[info] - sbt.plugins.JUnitXmlReportPlugin
[info] - sbt.plugins.JvmPlugin
[info] - sbt.plugins.SbtPlugin
[info] sbt, sbt plugins, and build definitions are using Scala 2.12.7
sbt:foo-build> compile
[success] Total time: 0 s, completed Feb 7, 2019 4:40:45 PM
sbt:foo-build> run
Terminate batch job (Y/N)? Y
This is enough of an answer for my own purposes.
I was able work around this issue by adding a line to my build.sbt file. After adding ThisBuild / scalaVersion := "2.12.8" I was able to use the run command. Following the tutorial linked in the main question I would not expect to have to do this but perhaps someone could shed some light.

Sbt always do fully recompile after restart sbt

[success] Total time: 132 s, completed Aug 25, 2017 3:08:56 PM
> compile
[success] Total time: 0 s, completed Aug 25, 2017 3:09:07 PM
>
$ sbt
[info] Loading global plugins from /home/jilen/.sbt/0.13/plugins
[info] Loading project definition from /home/jilen/Workspace/wx-web/project
[info] Updating {file:/home/jilen/Workspace/wx-web/project/}wx-web-build...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Set current project to wx-web (in build file:/home/jilen/Workspace/wx-web/)
> compile
[info] Compiling 574 Scala sources and 3 Java sources to /home/jilen/Workspace/wx-web/target/scala-2.11/classes...
As the log says when I start sbt, it do fully recompile which is already compiled before.
sbt.version 0.13.15
scala.version 2.11.11
Finally, it turns out to be a bug of sbt incremental compiler.

How to force SBT to use Javadoc instead of Scaladoc?

I have Java based a Play & Akka project that is built with SBT, is there any way to tell SBT to run Javadoc instead of Scaladoc when building the project? The SBT documentation says that
“sbt will run javadoc if there are only Java sources in the project. If there are any Scala sources, sbt will run scaladoc.”
and there are no Scala files in the project but Scaladoc is still run. I assume that this is because the Play plugin is converting the view templates and conf/routes file into Scala code before compilation happens.
tl;dr Change sources in (Compile, doc) to exclude *.scala files so scaladoc doesn't kick in.
As you can read below sources in (Compile, doc) holds all sources, both managed and unmanaged in a project:
> inspect compile:doc::sources
[info] Task: scala.collection.Seq[java.io.File]
[info] Description:
[info] All sources, both managed and unmanaged.
With some filtering you can achieve your goal quite easily - use the following in build.sbt:
sources in (Compile, doc) <<= sources in (Compile, doc) map { _.filterNot(_.getName endsWith ".scala") }
A sample project's session (comments with // are mine to enhance reading):
// display current setting's value
> show compile:doc::sources
[info] ArrayBuffer(/Users/jacek/sandbox/sbt-learning-space/src/main/scala/x.scala, /Users/jacek/sandbox/sbt-learning-space/src/main/java/Hello.java)
[success] Total time: 0 s, completed Aug 24, 2014 9:31:34 PM
// generate docs - scaladoc kicks in since there are scala files
> doc
[info] Updating {file:/Users/jacek/sandbox/sbt-learning-space/}sbt-learning-space...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Main Scala API documentation to /Users/jacek/sandbox/sbt-learning-space/target/scala-2.10/api...
model contains 3 documentable templates
[info] Main Scala API documentation successful.
Hello
[success] Total time: 1 s, completed Aug 24, 2014 9:32:15 PM
// change the value of sources in the current session only - use session save to retain it
> set sources in (Compile, doc) <<= sources in (Compile, doc) map { _.filterNot(_.getName endsWith ".scala") }
[info] Defining compile:doc::sources
[info] The new value will be used by compile:doc
[info] Reapplying settings...
[info] Set current project to hello (in build file:/Users/jacek/sandbox/sbt-learning-space/)
// display current setting's value - it only holds the single java file
> show compile:doc::sources
[info] ArrayBuffer(/Users/jacek/sandbox/sbt-learning-space/src/main/java/Hello.java)
[success] Total time: 0 s, completed Aug 24, 2014 9:33:23 PM
// generate docs - javadoc is properly generated
> doc
[info] Main Java API documentation to /Users/jacek/sandbox/sbt-learning-space/target/scala-2.10/api...
[info] Loading source file /Users/jacek/sandbox/sbt-learning-space/src/main/java/Hello.java...
[info] Constructing Javadoc information...
[info] Standard Doclet version 1.7.0_65
[info] Building tree for all the packages and classes...
[info] Generating /Users/jacek/sandbox/sbt-learning-space/target/scala-2.10/api/Hello.html...
[info] Generating /Users/jacek/sandbox/sbt-learning-space/target/scala-2.10/api/package-frame.html...
[info] Generating /Users/jacek/sandbox/sbt-learning-space/target/scala-2.10/api/package-summary.html...
[info] Generating /Users/jacek/sandbox/sbt-learning-space/target/scala-2.10/api/package-tree.html...
[info] Generating /Users/jacek/sandbox/sbt-learning-space/target/scala-2.10/api/constant-values.html...
[info] Building index for all the packages and classes...
[info] Generating /Users/jacek/sandbox/sbt-learning-space/target/scala-2.10/api/overview-tree.html...
[info] Generating /Users/jacek/sandbox/sbt-learning-space/target/scala-2.10/api/index-all.html...
[info] Generating /Users/jacek/sandbox/sbt-learning-space/target/scala-2.10/api/deprecated-list.html...
[info] Building index for all classes...
[info] Generating /Users/jacek/sandbox/sbt-learning-space/target/scala-2.10/api/allclasses-frame.html...
[info] Generating /Users/jacek/sandbox/sbt-learning-space/target/scala-2.10/api/allclasses-noframe.html...
[info] Generating /Users/jacek/sandbox/sbt-learning-space/target/scala-2.10/api/index.html...
[info] Generating /Users/jacek/sandbox/sbt-learning-space/target/scala-2.10/api/help-doc.html...
[info] Main Java API documentation successful.
Hello
[success] Total time: 1 s, completed Aug 24, 2014 9:34:01 PM
You could try and integrate genjavadoc into sbt, in order to generate a javadoc.
The ScalaDoc can still be generated using the normal doc task,
whereas the JavaDoc can be generated using genjavadoc:doc.
Another approach, allowed with scala 2.12.0-RC1 (Sept. 2016) and SI 4826 is to let scaladoc run! It will process javadoc comments!
Scaladoc already processes Java sources and produces Scaladoc for them.
It just ignores the doc comments.
Many of our Scala codebases have at least some Java in them for various reasons.
It'd be nice if Scaladoc could generate full documentation for these mixed codebases, including all doc comments.

Prevent sbt from publishing an automatically aggregated root project

I have an sbt multi project build with two projects core and mac. I don't have a root project which aggregates them. Unfortunately sbt does create one automatically.
How can I prevent this dummy aggregate project from being published? I get something like "default-6a1ca6" apart from core and mac when I run sbt publish-local.
I am looking for something like
autoRoot := false
?
For sbt 1.x you can also use
lazy val root = (project in file(".")).
aggregate(core, mac).
settings(
skip in publish := true
)
See https://github.com/sbt/sbt/issues/3136
tl;dr Use packagedArtifacts in file(".") := Map.empty
With the latest SBT 0.13.1 and the following two files (and no other files inside the project):
build.sbt
lazy val core = project
lazy val mac = project
project/build.properties
sbt.version=0.13.1
...executing sbt publish-local gives:
$ sbt publish-local
...
[info] Set current project to root-0__multi (in build file:/Users/jacek/sandbox/so/0__multi/)
...
[info] published mac_2.10 to /Users/jacek/.ivy2/local/mac/mac_2.10/0.1-SNAPSHOT/poms/mac_2.10.pom
[info] published mac_2.10 to /Users/jacek/.ivy2/local/mac/mac_2.10/0.1-SNAPSHOT/jars/mac_2.10.jar
[info] published mac_2.10 to /Users/jacek/.ivy2/local/mac/mac_2.10/0.1-SNAPSHOT/srcs/mac_2.10-sources.jar
[info] published mac_2.10 to /Users/jacek/.ivy2/local/mac/mac_2.10/0.1-SNAPSHOT/docs/mac_2.10-javadoc.jar
[info] published ivy to /Users/jacek/.ivy2/local/mac/mac_2.10/0.1-SNAPSHOT/ivys/ivy.xml
[info] published root-0__multi_2.10 to /Users/jacek/.ivy2/local/default/root-0__multi_2.10/0.1-SNAPSHOT/poms/root-0__multi_2.10.pom
[info] published root-0__multi_2.10 to /Users/jacek/.ivy2/local/default/root-0__multi_2.10/0.1-SNAPSHOT/jars/root-0__multi_2.10.jar
[info] published root-0__multi_2.10 to /Users/jacek/.ivy2/local/default/root-0__multi_2.10/0.1-SNAPSHOT/srcs/root-0__multi_2.10-sources.jar
[info] published root-0__multi_2.10 to /Users/jacek/.ivy2/local/default/root-0__multi_2.10/0.1-SNAPSHOT/docs/root-0__multi_2.10-javadoc.jar
[info] published ivy to /Users/jacek/.ivy2/local/default/root-0__multi_2.10/0.1-SNAPSHOT/ivys/ivy.xml
[info] published core_2.10 to /Users/jacek/.ivy2/local/core/core_2.10/0.1-SNAPSHOT/poms/core_2.10.pom
[info] published core_2.10 to /Users/jacek/.ivy2/local/core/core_2.10/0.1-SNAPSHOT/jars/core_2.10.jar
[info] published core_2.10 to /Users/jacek/.ivy2/local/core/core_2.10/0.1-SNAPSHOT/srcs/core_2.10-sources.jar
[info] published core_2.10 to /Users/jacek/.ivy2/local/core/core_2.10/0.1-SNAPSHOT/docs/core_2.10-javadoc.jar
[info] published ivy to /Users/jacek/.ivy2/local/core/core_2.10/0.1-SNAPSHOT/ivys/ivy.xml
[success] Total time: 2 s, completed Feb 4, 2014 1:38:28 AM
It means that by default all there projects are published.
When you however add the setting packagedArtifacts in file(".") := Map.empty to set packagedArtifacts for the current (root) project:
build.sbt
lazy val core = project
lazy val mac = project
packagedArtifacts in file(".") := Map.empty
...executing sbt publish-local gives:
$ sbt publish-local
...
[info] Set current project to root-0__multi (in build file:/Users/jacek/sandbox/so/0__multi/)
...
[info] published ivy to /Users/jacek/.ivy2/local/default/root-0__multi_2.10/0.1-SNAPSHOT/ivys/ivy.xml
[info] published core_2.10 to /Users/jacek/.ivy2/local/core/core_2.10/0.1-SNAPSHOT/poms/core_2.10.pom
[info] published core_2.10 to /Users/jacek/.ivy2/local/core/core_2.10/0.1-SNAPSHOT/jars/core_2.10.jar
[info] published core_2.10 to /Users/jacek/.ivy2/local/core/core_2.10/0.1-SNAPSHOT/srcs/core_2.10-sources.jar
[info] published core_2.10 to /Users/jacek/.ivy2/local/core/core_2.10/0.1-SNAPSHOT/docs/core_2.10-javadoc.jar
[info] published ivy to /Users/jacek/.ivy2/local/core/core_2.10/0.1-SNAPSHOT/ivys/ivy.xml
[info] published mac_2.10 to /Users/jacek/.ivy2/local/mac/mac_2.10/0.1-SNAPSHOT/poms/mac_2.10.pom
[info] published mac_2.10 to /Users/jacek/.ivy2/local/mac/mac_2.10/0.1-SNAPSHOT/jars/mac_2.10.jar
[info] published mac_2.10 to /Users/jacek/.ivy2/local/mac/mac_2.10/0.1-SNAPSHOT/srcs/mac_2.10-sources.jar
[info] published mac_2.10 to /Users/jacek/.ivy2/local/mac/mac_2.10/0.1-SNAPSHOT/docs/mac_2.10-javadoc.jar
[info] published ivy to /Users/jacek/.ivy2/local/mac/mac_2.10/0.1-SNAPSHOT/ivys/ivy.xml
[success] Total time: 1 s, completed Feb 4, 2014 1:39:34 AM
No current (root) project is published.
This answer is a work around: Create an explicit root project and disable publishing for it. I wish there was a simpler way, though.

SBT does not want to enter my project (using project command)

My build is simple:
lazy val stampleWebProject = play.Project("stample-web", appVersion, appDependencies,path = file("stample-web"))
.dependsOn(stampleCoreProject,stampleSearchProject)
.aggregate(stampleCoreProject,stampleSearchProject)
lazy val stampleCoreProject = Project(id = "stample-core",base = file("stample-core"))
lazy val stampleSearchProject = Project(id = "stample-search",base = file("stample-search"))
All these projects have a build.sbt file with dependencies, without any scala build (which would be ignored as far as I know)
When I start SBT (12.4), I get the following:
[info] Set current project to stample-core (in build file:/home/sebastien/Bureau/Stample/)
> projects
[info] In file:/home/sebastien/Bureau/Stample/
[info] * stample-core
[info] stample-search
[info] stample-web
> project stample-search
[info] Set current project to stample-search (in build file:/home/sebastien/Bureau/Stample/)
> projects
[info] In file:/home/sebastien/Bureau/Stample/
[info] stample-core
[info] * stample-search
[info] stample-web
> project stample-core
[info] Set current project to stample-core (in build file:/home/sebastien/Bureau/Stample/)
> projects
[info] In file:/home/sebastien/Bureau/Stample/
[info] * stample-core
[info] stample-search
[info] stample-web
> project stample-web
[info] Set current project to stample-search (in build file:/home/sebastien/Bureau/Stample/)
[stample-search] $ projects
[info] In file:/home/sebastien/Bureau/Stample/
[info] stample-core
[info] stample-search
[info] * stample-web
[stample-search] $ compile
[info] Updating {file:/home/sebastien/Bureau/Stample/}stample-core...
[info] Resolving org.slf4j#slf4j-api;1.6.6 ...
[info] Done updating.
[info] Updating {file:/home/sebastien/Bureau/Stample/}stample-web...
[error] a module is not authorized to depend on itself: stample-search#stample-search_2.10;1.0
[error] (stample-web/*:update) java.lang.IllegalArgumentException: a module is not authorized to depend on itself: stample-search#stample-search_2.10;1.0
[error] Total time: 1 s, completed 26 août 2013 21:57:45
I do not understand some stuff here:
How is choosen the project in which we are by default. I've seem documentation was added in SBT 13.0 but did not see it in the 12.4 multibuild documentation.
How comes I type project stample-web and it tells me I'm in stample-search
Why is there a special display in my sbt console for the project I'm in (stample-web or stample-search, I don't really know...) (this appears here: [stample-search] $ compile, is this relative to play projects?
Why it can't compile stample-search, since it doesn't depend on itself in my build (I suspect it tries to compile the web project but there's a naming problem or something?
Is this an SBT bug. If so, is it possible to use the new 13.0 version with Play framework?
Eugene Yokota is right: I have a conflict in the stample-web folder, which was set the stample-web name in the scala build, but it has a wrong build.sbt in the folder which has name := stample-search