How can I provide a project prefix in sbt for multi-project builds? - sbt

When I had a single-part project, from the command line I could say:
sbt testOnly *.FooSpec
Now that I have a multi-part project, that same command returns nothing--it can't find FooSpec. Imagine FooSpec lives in a subproject called 'part'. How can I specify 'part' in my sbt command? I tried:
sbt testOnly part:*.FooSpec
Didn't work.
(btw, I know I can do 'project part' then 'testOnly *.FooSpec' from inside sbt. I want to do this all from the shell, not inside sbt)

Related

Migrate from activator 0.13.x to sbt 1.x

I am migrating from activator from 0.13.x to sbt 1.x.
I used to compile my modules like this $ activator clean compile publish-local -Dversion=1
Now, I am trying to do it with sbt since activator has been deprecated, but I can not find how I should migrate to something similar like $ sbt clean compile publish-local -Dversion=1?
Activator (the CLI part) was just a wrapper around sbt with some custom commands. So what you wrote should work the same, expect that the snake-case was deprecated in favor of the camelCase:
sbt clean compile publishLocal
If you need to pass a var to the Java runtime with -D you have to place it before any commands: sbt -Dversion=1 ....
Notice that you use batch mode to run the commands:
Running in batch mode requires JVM spinup and JIT each time, so your build will run much slower. For day-to-day coding, we recommend using the sbt shell or Continuous build and test feature described below.
To follow this recommendation, just run sbt and then enter those commands one by one. Or to run them all sequentially, enter ; clean; compile; publishLocal.

Run SBT without installing it first

I was wondering if SBT has something similar to the Gradle Wrapper?
I would like to use it on a CI server without having to install SBT first.
The documentation mentions a sbt-launcher, but that seems to be geared towards running actual application instead of builds.
Yes, sbt-extras is a bash script that you can commit to your repository to act like the gradle wrapper.
The sbt-extras project is centered around a stand-alone script called sbt which can be directly used to run sbt without having it on the machine first.
The script has logic to determine the proper version of sbt for the project, download the correct version of the sbt jar, and then run the tasks through sbt.
If you copy the sbt script into your project, you can simply call it — from your CI server, locally, or wherever — to run sbt tasks without needing sbt installed separately.

SBT Plugin to modify compile and test tasks

I am in the process of creating a plugin that will modify both the compile:compile and test:test tasks. My ultimate aim is to be able to do sbt monkjack or sbt monkjack:test (either is fine). In the compile:compile scope I need to add a compiler plugin, and in the test:test scope I need to run some code after the tests have finished.
My first attempts were around trying to create a custom configuration but which to extend, compile or test, was unclear as both are needed (At the moment I have two, and I copy the CustomTest into the CustomCompile and then run monkjack:test). My second attempts were focusing on a custom task that in turn invoked (compile in Compile).value and (test in Test).value after setting various options.
I realize my knowledge of SBT tasks and how they are related/inherited/scoped is not great.
Q1. Is there a chain of tasks like in maven? In maven if you execute test, it will execute the other phases in order. So mvn clean test will automatically run prepare-sources, compile, etc etc. So in SBT if I run sbt test how are the other tasks automatically executed.
Q2. If you execute a task with a custom config, eg sbt millertime:test will that config propagate to the other tasks that run. Eg, is this the same as sbt monkjack:compile monkjack:test or the same as sbt compile monkjack:test or neither :)
Q3. How do tasks know which is their default config? If I do sbt compile how does SBT know that means sbt compile:compile?
Q4. Which is the best way to go here, a custom configuration or a new task.

How to execute tests in a single project only in multi-module build?

I have a multi-module build, and would like to run tests for different sub-projects independently.
Is there a way to do this in sbt, e.g. if my multi-project build has a core and commons projects, I'd like to only run test in the commons project.
Run sbt commons/test. See detailed explanation in Scopes.
You may also use the combination of two commands from sbt - changing the current project using project and executing test afterwards.
sbt "project commons" test
You can also use
sbt "; project commons; test"
It you are running sbt in interactive mode:
> project commons
> test
You can switch back to core with:
> project core
Never mind, I came across this:
How to execute package for one submodule only on Jenkins?
sbt "project core" test
Another way to do this.
Get into SBT interactive mode
> sbt
sbt:core> commons / test
No need to switch between projects.
to run sbt test only for ONLY the submodules having added, modified on deleted files, if you use git:
while read -r proj ; do sbt "project $proj" test ; \
done < <(git status --porcelain | cut -c 3- | cut -d/ -f1
There is another way to have sbt open for a particular module.
Go to the location of the module directory and type in the "sbt" command.
sbt will then open in interactive mode for that module only

Passing JVM args through sbt

I'm trying to add a 3rd party jar to my java library path. If I invoke sbt with -Djava.library.path=a-3rd-party-lib.jar, then it works for the first invocation of run-main MyClass inside sbt, but thereafter the 3rd party code complains that the jar is not in the java library path. I have also tried adding javaOptions += "-Djava.library.path=a-3rd-party-lib.jar" to my build.sbt file, but this hasn't worked (even for the first run). Qualifying this command as javaOptions in (Test,run) += "-Djava.library.path=a-3rd-party-lib.jar" (as seen in the docs) hasn't worked either.
Am I doing something wrong, or is this a strange bug?
FYI I'm using sbt 0.13.0
javaOptions only takes effect if you fork run and sbt does not fork by default. See the Forking documentation for details, but forking is enabled for run and runMain with:
fork in run := true

Resources