Explain SBT syntax like compile:compile - scala

Although SBT is called simple build tools, it's far from being simple. I still can't get this syntax in sbt session like compile:compile? What's the difference between this and just compile?

The main trick in here is in scopes. If you want really understand how SBT works then always use three commands:
show <setting> - Displays the value of the specified setting.
show <task> - Evaluates the specified task and display the value returned by the task.
inspect <key> - shows info about setting
inspect tree <key> - displays key and its dependencies in a tree structure.
There are many other good commands, but this will help you most to understand the basics of SBT.
As for the syntax. Each build consists of settings, tasks, projects and scopes. There are too much to tell about them, there is a good explanation given on the official site. And the syntax you gave is all about this terms, for example let's take a look at:
compile:scalaSource::sourceDirectory
1 2 3
1 - it is a Compile scope
2 - it is a dependant Setting
3 - dependency Setting
If you type inspect scalaSource you'll see that, if you type just scalaSource in the SBT session this will call scalaSource in the compile scope(compile:scalaSource), this explains the difference between compile:compile and compile, this are the same (call inspect on compile). The second thing you should take a look at in inspect scalaSource is the Dependencies: part: compile:sourceDirectory, so scalaSource depends on the sourceDirectory setting in compile:sourceDirectory and if you've seen some build on github, in *.sbt or *.scala build files it's written like:
sourceDirectory in (Compile, scalaSource) := ....
Just for the exercise, call:
show compile:scalaSource::sourceDirectory
and you'll see the output like this: <project-dir>/src/main and then call:
set sourceDirectory in (Compile, scalaSource) <<= baseDirectory(_ / "src" / "sc")
and then again:
show compile:scalaSource::sourceDirectory

Related

How do I configure scoverage when using SBT?

When using the cobertura-maven-plugin for Java, I get a nice <instrumentation> block in the config where I can put the incredibly useful <ignoreMethodAnnotation> block.
Best thing to happen to coverage since the gin martini.
Now I'm using scoverage-sbt, but I can't seem to find where I can configure it! The available keys in build.scala are limited. I can do package exclusion and file exclusion but there's nowhere to tell cobertura anything else.
Is there a -D I can supply on the SBT command line, maybe?
There is no similar configuration in Scoverage ATM.
update:
You can use special comments to exclude a block of code from instrumentation:
// $COVERAGE-OFF
...
// $COVERAGE-ON$
One way to pass parameters and commands into SBT from the command line is:
$ sbt 'set coverageEnabled := true' clean coverage test coverageReport coverageAggregate codacyCoverage
Where you call SBT once and then separate each parameter or command by a space.
In this example, I first set the property coverageEnabled := true and then run several commands in sequence: clean, coverage, test, coveraReport, coverageAggregate and finally codacyCoverage
Please note that setting properties like this requires that you enclose your statements in single quotes, for example:
$ sbt 'set coverageEnabled := true'...

How to run sbt tests for debugging when debug is disabled by default?

I find it incredibly awkward to have to restart sbt with special flags if I want to run the tests (or a main) with debug enabled. It's also a pain if the main or test is usually in a forked JVM:
How to set fork in Test when -jvm-debug given on command line?
Is there any simple way to conditionally do a run, test, test-quick or test-only and ask for debugging to be enabled in the forked process? e.g. with syntax like test-only -jdb
I don't really want to have to write my own Tasks to do this... maintaining them is going to be a nightmare. But I guess that would allow syntax like module/jdb:test-only
While Eugene accurately mentions that we could provide debug:testOnly out of the box, the following should help you out:
val DebugTest = config("dtest") extend Test
lazy val myproject =
project.configs(DebugTest).
settings(inConfig(DebugTest)(Defaults.testSettings):_*).
settings(
fork in DebugTest := true,
javaOptions in DebugTest += "debugging options",
definedTests in DebugTest := (definedTests in Test).value
)
This should allow you to do dtest:testOnly *, dtest:run and dtest:test on myproject. The forked JVM (note fork in DebugTest := true) will use whatever debugging options you've provided.
I don't think there's any simple feature that enables debugging out of the box.
As you mentioned on sbt-dev list, making a custom configuration like debug:testOnly sounds like a good strategy.

CoffeeScript and sbt-concat

I'm having trouble concatenating and fingerprinting all the CoffeeScript files in Play application. Everything works fine for JavaScript files with build.sbt like this one
pipelineStages := Seq(concat, digest)
Concat.groups := Seq(
"javascripts/app.js" -> group(((sourceDirectory in Assets).value / "javascripts") * "*.js")
)
But when sourceDirectory is changed to resourcesManaged that supposedly contains compiled CoffeeScript files sbt-concat doesn't pick them up.
sbt-coffeescript, and all other official source task plugins, don't put their files in resourcesManaged in Assets, but instead their own sub-directory in target/web/<taskname>. They scope the resourcesManaged setting to their main task, in this case this means resourcesManaged in (Assets, coffeescript) and resourcesManaged in (TestAssets, coffeescript).
When you run sbt coffeescript you can see the files are output to target/web/coffeescript/main. You can verify this by running show web-assets:coffeescript::resourceManaged from the sbt console.

How to exclude unmanaged resources from Compile scope only (not from Test)

In one of my sub projects, I am trying to exclude *.conf and *.groovy files from my list of unmanaged resources:
excludeFilter in Compile in unmanagedResources := "*.conf" || "*.groovy"
Now, this works but has the unintended effect of removing the *.conf files from Test.
I tried to add the following includeFilter setting :
includeFilter in Test in unmanagedResources := "*.conf"
However, this does not work.
I figure that there is a relationship between Test and Compile that may be causing this issue.
Any suggestions would be helpful.
Thanks.
There are two issues here and you've identified the main one, which is the relationship between Test and Compile. The other is that a file must both be included by includeFilter and not be excluded by excludeFilter.
Test gets its settings from Compile if none are specified for Test explicitly. When you define excludeFilter in Compile, it applies to Test as well. So, you can define excludeFilter in Test to be the default, which is to ignore hidden files:
excludeFilter in Test := HiddenFileFilter
(Or, you can use NoFilter to not have any exclusions.)

Scala SBT CoffeeScripted, correctly override compile target

Groping in the dark, I just resorted to a pathetic hack (note the path backtracking):
(resourceManaged in (Compile, CoffeeKeys.coffee)) <<=
(crossTarget in Compile)(_ / "../../../apache/static" / "js")
Is there any way to specify the absolute target write path with coffeescripted-sbt? The intro/overview states
You can override this behavior by overriding the resourceManaged
setting scoped to your configration and the CoffeeKeys.coffee task.
Below is an example you can append to your build definition which will
copy generated javascript to target/:scala-version/your_preference/js
That's great, but I'd like to write directly to apache statics directory, and not 4 levels deep in my sbt-eclipse project
Should note: I'm getting the Unicorn is Angry quite often on GitHub these days, so issue tracker isn't much help.
Thanks for any clues, what I have works, but I'd like to know how to set the absolute path properly
(resourceManaged in (Compile, CoffeeKeys.coffee)) <<=
(crossTarget in Compile)(_ / "pref" / "js")
Sets compile target relative to the default, which is "project_root/target/scala-version/"
The solution is refreshingly simple:
resourceManaged in (Compile, CoffeeKeys.coffee) :=
file("/absolute/path/to/apache/static/js")
SBT user group thread