How to get dependencyClasspath in sbt build without triggering compilation? - scala

In sbt show dependencyClasspath triggers compilation. Actually, it is the internalDependencyClasspath which does that. I was wondering if I can get the classpath of the inter-project dependencies for both Test and Compile scope without triggering compilation?

Here's a dirty little hack: temporarily remove all source files from project structure so that there's nothing to actually compile but target directories and project dependencies remain the same:
set every sources := Seq.empty
show dependencyClasspath

Related

Recompile build.sbt and project/ before testOnly

My structure of scala project is pretty simple:
/someApp
/scala
/project
Dependencies.scala
...
/main
...
/test
MyTest.scala
/target
...
build.sbt
Now, let's consider:
sbt> testOnly *MyTest
It recompiles MyTest.scala and executes it as I expect. However, when I introduce changes to build.sbt or project/Dependencies.scala it ignores these changes.
Could someone explain me and understand why does it happen? The sbt seems to be one huge mystery...
To include changes made to .sbt files or .scala files under the project folder, you'll need to run the reload command within the sbt shell.
You can also force sbt to reload each time it detects a change in these files by adding this line to your build.sbt:
Global / onChangedBuildSource := ReloadOnSourceChanges

SBT plugin how to make a source generator dependent on project's sources?

I'm trying to create a source generator in a SBT plugin that generate code based on the project's sources.
I tried something like this:
sourceGenerators in Compile += (sources in Compile) map { sources => doSomethingWithSources(sources) }
Unfortunately, SBT does not want to load this plugin due to the fact that there exists circular dependency.
Due to this fact I've created another task like this:
lazy val myTask = TaskKey[Unit]("myTask", "Do stuff")
This tasks actually depends on the sources value and generates the files.
Later I override the projectSettings value and add this:
myTask in Compile := {
val sourcesValue = (sources in Compile).value
doSomethingWithSources(sourcesValue)
},
sourcesGenerators in Compile += Def.task(Seq(new File("path/to/myGeneratedSource.scala"))).taskValue
I add this task as the dependency to the compile task in the build.sbt of the project that I want my plugin to do stuff like this:
compile in Compile <<= (compile in Compile) dependsOn (myTask in Compile)
While it works (the file is generated), when I launch the sbt command sbt run, it creates the file but does not compile it.
What is more, when I run just sbt compile run, it compiles only the project on the first (compile) task and generates my source and then on run part it compiles the generated source - so, in matter of speaking, it does somehow work, but it needs two compilations.
I'd like to ask if there is a simpler way to do this and, if not, how to make it work in only one compilation.

How to use external dependencies in sbt's .scala files?

This is for Scala 2.11.1 and sbt 0.13.5.
Say I have a Scala/sbt project with the following directory structure:
root/
build.sbt
src/ ..
project/
plugins.sbt
build.properties
LolUtils.scala
and I want to use some external library in LolUtils.scala. How is this generally accomplished in sbt?
If I simply add the libs I need into build.sbt via libraryDependencies += .. then it doesn't find them and fails on the import line with not found: object ...
If I add a separate project/build.sbt, for some reason it starts failing to resolve my plugins, plus I need to manually specify the Scala version in the nested project/build.sbt, which is unnecessary duplication.
What's the best way to accomplish this?
sbt is recursive which means that it uses itself to compile a build definition, i.e. *.sbt files and *.scala files under project directory. To add extra dependencies to use them in the build definition you have to declare them in a project/build.sbt.
There is one caveat to that. You can set any scalaVersion to your project, that is in build.sbt, but you should not modify scalaVersion in the project/build.sbt as it might conflict with the version sbt itself uses (that may or may not lead to binary incompatibility for plugins).
Sbt 0.13.5 is using Scala 2.10.4, and the library you're going to use must be compatible with that particular version of Scala.
> about
[info] This is sbt 0.13.5
...
[info] sbt, sbt plugins, and build definitions are using Scala 2.10.4

How to resolve a non-jar (dll/jnilib) library dependencies in sbt?

In a SBT build.sbt project file, is it possible to retrieve library dependencies which are not bundled as jar?
In my case, I am trying to use QTSampledSP which requires .dll and .jnilib libraries.
To download the artifact, you need to make Ivy (and hence sbt) explicitly aware of the DLL artifact. Add the following to build.sbt in your project.
lazy val QtSampledJniLibArt = Artifact("qtsampledsp-osx", "jnilib", "jnilib")
libraryDependencies += "com.tagtraum" % "qtsampledsp-osx" % "0.9.6" artifacts(QtSampledJniLibArt)
resolvers += "beatunes" at "http://www.beatunes.com/repo/maven2"
Then you need to tell sbt to pay attention to these artifacts (again build.sbt):
classpathTypes ++= Set("jnilib", "dll")
By default, sbt will only add a few types into the classpath (and jnilib and dll are not amongst them).
[sbt-0-13-1]> help classpathTypes
Artifact types that are included on the classpath.
[sbt-0-13-1]> show classpathTypes
[info] Set(eclipse-plugin, bundle, hk2-jar, orbit, jar)
Since these DLLs/jnilibs are needed on the classpath to run correctly, the above setting classpathTypes where you add the additional types will correct things as you can see below (don't forget to reload when in sbt console).
[sbt-0-13-1]> show classpathTypes
[info] Set(eclipse-plugin, bundle, hk2-jar, jnilib, orbit, jar, dll)
If you need to look in more detail at these files, check out the update report (from the update task) where you can inspect all configurations/modules/artifacts. Run show update in sbt console and look at the files in target/resolution-cache/reports.

Running SBT with -deprecation

I seem to have warnings in my project/build.scala file (NOT IN MY SCALA PROJECT). How do I configure SBT to run with the -deprecation flag.
// Does not help so do not suggest it!
scalacOptions ++= Seq("-unchecked", "-deprecation")
I know that SBT has the sbt.boot.properties files, but can't figure out if the flag should go in there or not. And if it is an example would be nice. Thx in advance.
BTW
I use SBT launcher for 0.12.2 and have the issue both with SBT 0.12.2 and 0.11.3. And I'm on Ubuntu in case that matters.
Simply put the scalacOptions setting in project/build.sbt. Settings for your project and your build definition go in different files, because they have to be compiled before they can be used and as you want to change compiler settings, this is not possible to handle in the same file.
edit: Just to prevent confusion, ./build.sbt, project/build.scala and project/build.sbt are different. In the first one you put your normal settings for the project and in the latter two (never both used together) you can put settings that affect the compilation of your project files.