Abhijit Sarkar
Abhijit Sarkar

Reputation: 24568

How to apply common test configuration to all projects?

I'm migrating an old project to Scala 3. The build.sbt is as follows:

import Dependencies._

inThisBuild(
  Seq(
    scalaVersion := "2.12.7",
    scalacOptions ++= Seq(
      "-unchecked",
      // more
    )
  )
    ++ inConfig(Test)(Seq(
    testOptions += Tests.Argument(TestFrameworks.ScalaTest, "-o", "-e"),
    // more
  ))
)

lazy val root = (project in file("."))
  .aggregate(
    `test-util`
  )

lazy val `test-util` = project

Now, I want to separate stuff inside inThisBuild for legibility.

import Dependencies._

ThisBuild / scalaVersion := "3.0.1"
ThisBuild / scalacOptions ++= Seq(
  "-unchecked",
  // more
)

lazy val testSettings = inConfig(Test)(
  Seq(
    testOptions += Tests.Argument(TestFrameworks.ScalaTest, "-o", "-e"),
    // more
  ))


lazy val root = (project in file("."))
  .aggregate(
    `test-util`
  )
  .settings(testSettings)

lazy val `test-util` = project

As you can see, I'm having to apply the testSettings for each project. Ideally, I'd like to do something like ThisBuild / Test := testSettings but that is not valid syntax.

Is there a way to apply the testSettings to all projects without having to explicitly set .settings(testSettings)?

Edit:

I understand I can write each line of testSettings with ThisBuild / Test prefix, but I’d rather not repeat the same prefix. I’m looking for something like what I’ve done with scalacOptions.

Upvotes: 3

Views: 140

Answers (2)

Mario Galic
Mario Galic

Reputation: 48420

Is there a way to apply the testSettings to all projects without having to explicitly set .settings(testSettings)

Consider creating an auto plugin which can inject settings automatically in all the sub-projects, for example in project/CommonTestSettings.scala

import sbt._
import Keys._

object CommonTestSettings extends sbt.AutoPlugin {
  override def requires = plugins.JvmPlugin
  override def trigger = allRequirements
  override lazy val projectSettings =
    inConfig(Test)(
      Seq(
        testOptions += Tests.Argument(TestFrameworks.ScalaTest, "-o", "-e")
        // more
      )
    )
}

You can test with show testOptions which should reveal the common settings in all the sub-projects, for example in my project where root aggregates foo and bar I get something like

sbt:sbt-multi-project> show testOptions
[info] foo / Test / testOptions
[info]  List(Argument(Some(TestFramework(org.scalatest.tools.Framework, org.scalatest.tools.ScalaTestFramework)),List(-o, -e)))
[info] bar / Test / testOptions
[info]  List(Argument(Some(TestFramework(org.scalatest.tools.Framework, org.scalatest.tools.ScalaTestFramework)),List(-o, -e)))
[info] Test / testOptions
[info]  List(Argument(Some(TestFramework(org.scalatest.tools.Framework, org.scalatest.tools.ScalaTestFramework)),List(-o, -e)))

Upvotes: 2

gianluca aguzzi
gianluca aguzzi

Reputation: 1724

As you can done with scalaVersion and scalacOptions, you can do with Test. For example:

lazy val testSettings = inConfig(Test)(
  Seq(
    testOptions += Tests.Argument(TestFrameworks.ScalaTest, "-o", "-e"),
    // more
  ))

Can be rewritten as:

ThisBuild / Test / testOptions += Test.Argument(TestFrameworks.ScalaTest, "-o", "-e")

Is it this that you want? Or do you want to pass a sequence directly?

Upvotes: 0

Related Questions