SBT Plugin to modify compile and test tasks - sbt

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.

Related

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

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)

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.

How to run sbt Revolver in test scope?

In a Akka project we're using the SBT Revolver plugin to run the application.
During development it would be useful if it would be possible to run the application in test scope so log- and application configuration get loaded which helps during development.
However, running 'sbt test:re-start' does not seems to use the test classpath and therefore does not run the correct application and does not use the correct configuration files.
Looking at the Revolver page it looks like the plugin creates it's own scope.
Does anyone know how to be able to use the test scope for running the Revolver plugin?
Try to configure the fullClasspath setting of revolver and add the Test classpath to it:
fullClasspath in Test in reStart <<= Classpaths.concatDistinct(fullClasspath in Test, fullClasspath in Runtime)

Is there a concept of a build script dependency?

In Gradle, there is a concept of a buildscript dependency, in that you can add an external dependency that the build script depends on to run. This is similar to SBT's plugins, except way more lightweight. With Gradle, I can add X as a dependency and then write Groovy code using the contents of X. I need to use an external Java library inside of my build script and the mechanisms to do this are far from obvious to me in SBT.
With SBT, the closest thing I've found in the documentation is addSbtPlugin, which works great if there is an X SBT plugin, but it isn't in this case.
Sbt builds are recursive, you can add a project/build.sbt file then add libraryDependency += ... to it.

Resources