Reputation: 1059
I have an SBT project with 2 subprojects and I want to have test compiler settings different from the normal compiler settings, for all the subprojects. I.e. I want to enforce -Xfatal-warnings
for the main code but not for tests.
I'm looking for a solution that doesn't involve setting each subproject individuall but all at once.
I'm working with SBT 1.3.9 and Scala 2.13.3
This is a sample of what I have in SBT:
lazy val root: Project = project
.in(file("."))
.aggregate(projectA, projectB)
lazy val projectA: Project = project
.in(file("projectA"))
.settings(
name := "projectA",
)
lazy val projectB: Project = project
.in(file("projectA"))
.settings(
name := "projectA",
)
I tried plenty of options but I can't set test options different to compile options. As a quick summary, I tried to play around with scoping:
scalacOptions := Seq(XXX)
+ Test/scalacOptions := Seq(YYY)
Compile/scalacOptions := Seq(XXX)
+ Test/scalacOptions := Seq(YYY)
ThisBuild/scalacOptions := Seq(XXX)
+ ThisBuild/Test/scalacOptions := Seq(YYY)
ThisBuild/Compile/scalacOptions := Seq(XXX)
+ ThisBuild/Test/scalacOptions := Seq(YYY)
test
and played around with various combinations of the above.This question is the closest to what I need but it doesn't work, probably beucase it's not meant for multiproject files.
UPDATE:
I've just discovered that if I scope the setting to a specific project then I have the behaviour I want:
projectA / Compile / scalacOptions := Seq(XXX)
projectA / Test / scalacOptions := Seq(YYY)
projectB / Compile / scalacOptions := Seq(XXX)
projectB / Test / scalacOptions := Seq(YYY)
but if I use ThisBuild
it doesn't work
ThisBuild / Compile / scalacOptions := Seq(XXX)
ThisBuild / Test / scalacOptions := Seq(XXX)
Do I have a wrong understanding of something or is this a bug?
Upvotes: 3
Views: 559
Reputation: 48420
ThisBuild
scope axis value is often misunderstood when attempting to define common settings for multiple subprojects. Please note it does not mean
add this common setting to all the subprojects in this build
Instead the meaning is closer to
If a subproject does not define this setting, then, possibly, delegate (fall back) to
ThisBuild
For example, executing inspect Test / scalacOptions
on basic hello world project gives
...
[info] Provided by:
[info] ProjectRef(uri("file:/my/Path/To/Project/"), "root") / Test / scalacOptions
...
[info] Delegates:
[info] Test / scalacOptions
[info] Runtime / scalacOptions
[info] Compile / scalacOptions
[info] scalacOptions
[info] ThisBuild / Test / scalacOptions
[info] ThisBuild / Runtime / scalacOptions
[info] ThisBuild / Compile / scalacOptions
[info] ThisBuild / scalacOptions
[info] Zero / Test / scalacOptions
[info] Zero / Runtime / scalacOptions
[info] Zero / Compile / scalacOptions
[info] Global / scalacOptions
...
The Provided by
section shows the scope with highest precedence
ProjectRef(uri("file:/my/Path/To/Project/"), "root") / Test / scalacOptions
then Delegates
section shows the remainder of precedence order where we notice there are bunch of scopes "above" the ones using ThisBuild
as project axis. Therefore because of how sbt scope delegation rules work
ThisBuild / Test / scalacOptions
does not mean tests within subprojects will automatically pick up the new value as it is quite low in the picking order.
I believe the most straightforward approach around sbt's arguably confusing scoping rules is to define a val
with common settings and then simply add that value to each subproject, or define an auto plugin
Auto plugins can inject project settings across the board
Consider my related answer which demonstrates the two approaches.
Upvotes: 1