Skip to content

Commit c82f9a2

Browse files
committed
manage BOMs in Tests
Starting with JUnit 5.12 and Spock 2.3 a BOM is available on Maven Central. If the version matches the BOMs will be automatically added. For JUnit, this has the effect that the platform-launcher is also managed in the BOM so it is actually not necessary to specify a platform-launcher-version. Hence the launcher is also added when the version is not set and the minimum version is met.
1 parent 68c5dcb commit c82f9a2

File tree

5 files changed

+219
-41
lines changed

5 files changed

+219
-41
lines changed

libs/groovylib/package.mill

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import millbuild.*
77

88
object `package` extends MillPublishScalaModule with BuildInfo {
99

10-
def moduleDeps = Seq(build.libs.javalib, build.libs.javalib.testrunner, api)
10+
def moduleDeps = Seq(build.libs.util, build.libs.javalib, build.libs.javalib.testrunner, api)
1111
def localTestExtraModules: Seq[MillJavaModule] =
1212
super.localTestExtraModules ++ Seq(worker)
1313

libs/groovylib/src/mill/groovylib/GroovyModule.scala

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import mill.*
1010
import mainargs.Flag
1111
import mill.api.daemon.internal.bsp.{BspBuildTarget, BspModuleApi}
1212
import mill.javalib.api.internal.{JavaCompilerOptions, JvmWorkerApi, ZincCompileJava}
13+
import mill.util.Version
1314

1415
/**
1516
* Core configuration required to compile a single Groovy module.
@@ -28,8 +29,18 @@ trait GroovyModule extends JavaModule with GroovyModuleApi { outer =>
2829
*/
2930
def groovyLanguageVersion: T[String] = Task { groovyVersion().split("[.]").take(2).mkString(".") }
3031

32+
private def isGroovyBomAvailable: T[Boolean] = Task {
33+
if (groovyVersion().isBlank) {
34+
false
35+
} else {
36+
Version.isAtLeast(groovyVersion(), "4.0.26")(using Version.IgnoreQualifierOrdering)
37+
}
38+
}
39+
3140
override def bomMvnDeps: T[Seq[Dep]] = super.bomMvnDeps() ++
32-
Seq(mvn"org.apache.groovy:groovy-bom:${groovyVersion()}")
41+
Seq(groovyVersion())
42+
.filter(_.nonEmpty && isGroovyBomAvailable())
43+
.map(v => mvn"org.apache.groovy:groovy-bom:$v")
3344

3445
/**
3546
* All individual source files fed into the compiler.

libs/groovylib/test/src/mill/groovylib/HelloGroovyTests.scala

Lines changed: 88 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package mill
22
package groovylib
33

44
import mill.javalib.{JavaModule, TestModule}
5-
import mill.api.{Task}
5+
import mill.api.Task
66
import mill.api.Discover
77
import mill.testkit.{TestRootModule, UnitTester}
88
import utest.*
@@ -11,6 +11,7 @@ object HelloGroovyTests extends TestSuite {
1111

1212
val groovy4Version = "4.0.28"
1313
val junit5Version = sys.props.getOrElse("TEST_JUNIT5_VERSION", "5.13.4")
14+
val spockGroovy4Version = "2.3-groovy-4.0"
1415

1516
object HelloGroovy extends TestRootModule {
1617

@@ -25,12 +26,8 @@ object HelloGroovyTests extends TestSuite {
2526
HelloGroovy.`groovy-tests`
2627
)
2728

28-
override def groovyVersion = groovy4Version
29-
override def depManagement = Seq(
30-
mvn"org.junit.jupiter:junit-jupiter-engine:$junit5Version"
31-
)
32-
override def jupiterVersion = junit5Version
33-
override def junitPlatformVersion = "1.13.4"
29+
override def groovyVersion: T[String] = groovy4Version
30+
override def jupiterVersion: T[String] = junit5Version
3431
}
3532

3633
}
@@ -39,39 +36,54 @@ object HelloGroovyTests extends TestSuite {
3936
override def groovyVersion: T[String] = groovy4Version
4037
override def mainClass = Some("jointcompile.JavaMain")
4138
}
39+
40+
object deps extends Module {
41+
42+
object groovyBom extends GroovyModule {
43+
override def groovyVersion: T[String] = groovy4Version
44+
}
45+
46+
object groovyNoBom extends GroovyModule {
47+
// Groovy-BOM available starting with 4.0.26
48+
override def groovyVersion: T[String] = "4.0.25"
49+
}
50+
51+
object `spockBom` extends GroovyModule with TestModule.Spock {
52+
override def spockVersion: T[String] = spockGroovy4Version
53+
override def groovyVersion: T[String] = groovy4Version
54+
}
55+
56+
object `spockNoBom` extends GroovyModule with TestModule.Spock {
57+
// Groovy-BOM available starting with 2.3
58+
override def spockVersion: T[String] = "2.2-groovy-4.0"
59+
override def groovyVersion: T[String] = groovy4Version
60+
}
61+
62+
}
4263

4364
trait Test extends GroovyModule {
4465

4566
override def mainClass = Some("hello.Hello")
4667

4768
object test extends GroovyTests with TestModule.Junit5 {
48-
override def depManagement = Seq(
49-
mvn"org.junit.jupiter:junit-jupiter-engine:5.13.4"
50-
)
51-
override def jupiterVersion = "5.13.4"
69+
override def jupiterVersion: T[String] = junit5Version
5270
override def junitPlatformVersion = "1.13.4"
5371
}
5472

5573
object script extends GroovyModule {
56-
override def groovyVersion = "4.0.28"
74+
override def groovyVersion: T[String] = groovy4Version
5775
override def mainClass = Some("HelloScript")
5876
}
5977

6078
object staticcompile extends GroovyModule {
61-
override def groovyVersion = "4.0.28"
79+
override def groovyVersion: T[String] = groovy4Version
6280
override def mainClass = Some("hellostatic.HelloStatic")
6381
}
6482

6583
object spock extends GroovyTests with TestModule.Spock {
66-
override def junitPlatformVersion = "1.13.4"
67-
override def spockVersion = "2.3-groovy-4.0"
68-
override def groovyVersion = "4.0.28"
69-
70-
def bomMvnDeps = Seq(
71-
mvn"org.junit:junit-bom:5.13.4",
72-
// mvn"org.apache.groovy:groovy-bom:${groovyVersion()}",
73-
mvn"org.spockframework:spock-bom:${spockVersion()}"
74-
)
84+
override def jupiterVersion: T[String] = junit5Version
85+
override def spockVersion: T[String] = spockGroovy4Version
86+
override def groovyVersion: T[String] = groovy4Version
7587
}
7688
}
7789
object main extends Test {
@@ -91,6 +103,7 @@ object HelloGroovyTests extends TestSuite {
91103
def m = HelloGroovy.main
92104
def mixed = HelloGroovy.`groovy-tests`
93105
def joint = HelloGroovy.`joint-compile`
106+
def deps = HelloGroovy.deps
94107

95108
test("running a Groovy script") {
96109
testEval().scoped { eval =>
@@ -182,6 +195,58 @@ object HelloGroovyTests extends TestSuite {
182195
val Right(_) = eval.apply(joint.run()): @unchecked
183196
}
184197
}
185-
198+
199+
test("dependency management"){
200+
201+
test("groovy"){
202+
203+
val groovyBom = mvn"org.apache.groovy:groovy-bom:$groovy4Version"
204+
205+
test("groovy bom is added when version is at least 4.0.26") {
206+
testEval().scoped { eval =>
207+
val Right(result) = eval.apply(deps.groovyBom.bomMvnDeps): @unchecked
208+
209+
assert(
210+
result.value.contains(groovyBom)
211+
)
212+
}
213+
}
214+
215+
test("groovy bom is NOT added when version is below 4.0.26") {
216+
testEval().scoped { eval =>
217+
val Right(result) = eval.apply(deps.groovyNoBom.bomMvnDeps): @unchecked
218+
219+
assert(
220+
!result.value.contains(groovyBom)
221+
)
222+
}
223+
}
224+
}
225+
226+
test("spock") {
227+
228+
val spockBom = mvn"org.spockframework:spock-bom:$spockGroovy4Version"
229+
230+
test("spock bom is added when version is at least 2.3") {
231+
testEval().scoped { eval =>
232+
val Right(result) = eval.apply(deps.spockBom.bomMvnDeps): @unchecked
233+
234+
assert(
235+
result.value.contains(spockBom)
236+
)
237+
}
238+
}
239+
240+
test("spock bom is NOT added when version is below 2.3") {
241+
testEval().scoped { eval =>
242+
val Right(result) = eval.apply(deps.spockNoBom.bomMvnDeps): @unchecked
243+
244+
assert(
245+
!result.value.contains(spockBom)
246+
)
247+
}
248+
}
249+
}
250+
}
186251
}
187252
}

libs/javalib/src/mill/javalib/TestModule.scala

Lines changed: 57 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,10 @@ import mill.api.Task
99
import mill.api.TaskCtx
1010
import mill.api.DefaultTaskModule
1111
import mill.javalib.bsp.BspModule
12-
import mill.util.Jvm
12+
import mill.util.{Jvm, Version}
1313
import mill.api.JsonFormatters.given
1414
import mill.constants.EnvVars
15-
import mill.javalib.testrunner.{
16-
DiscoverTestsMain,
17-
Framework,
18-
TestArgs,
19-
TestResult,
20-
TestRunner,
21-
TestRunnerUtils
22-
}
15+
import mill.javalib.testrunner.{DiscoverTestsMain, Framework, TestArgs, TestResult, TestRunner, TestRunnerUtils}
2316

2417
import java.nio.file.Path
2518

@@ -358,24 +351,53 @@ object TestModule {
358351
* You can override the [[junitPlatformVersion]] and [[jupiterVersion]] task
359352
* or provide the JUnit 5-dependencies yourself.
360353
*
354+
* In case the [[jupiterVersion]] is set (and it is > 5.12), it pulls in JUnit-BOM in [[bomMvnDeps]]. If this is
355+
* true, then there is no need to specify the [[junitPlatformVersion]] anymore, because this is managed by the
356+
* BOM.
357+
*
361358
* See: https://junit.org/junit5/
362359
*/
363360
trait Junit5 extends TestModule {
364361

365-
/** The JUnit 5 Platfrom version to use, or empty, if you want to provide the dependencies yourself. */
362+
/** The JUnit 5 Platform version to use, or empty, if you want to provide the dependencies yourself. */
366363
def junitPlatformVersion: T[String] = Task { "" }
367364

368-
/** The JUnit Jupiter version to use, or empty, if you want to provide the dependencie yourself. */
365+
/** The JUnit Jupiter version to use, or empty, if you want to provide the dependencies yourself. */
369366
def jupiterVersion: T[String] = Task { "" }
367+
368+
private def isJupiterBomAvailable: T[Boolean] = Task {
369+
if(jupiterVersion().isBlank){
370+
false
371+
}else{
372+
Version.isAtLeast(jupiterVersion(), "5.12.0")(using Version.IgnoreQualifierOrdering)
373+
}
374+
}
370375

371376
override def testFramework: T[String] = "com.github.sbt.junit.jupiter.api.JupiterFramework"
372377

378+
override def bomMvnDeps: T[Seq[Dep]] = Task {
379+
super.bomMvnDeps() ++
380+
Seq(jupiterVersion())
381+
.filter(!_.isBlank() && isJupiterBomAvailable())
382+
.flatMap(v =>
383+
Seq(
384+
mvn"org.junit:junit-bom:${v.trim()}"
385+
)
386+
)
387+
}
388+
373389
override def mandatoryMvnDeps: T[Seq[Dep]] = Task {
374390
super.mandatoryMvnDeps() ++
375391
Seq(mvn"${mill.javalib.api.Versions.jupiterInterface}") ++
376-
Seq(junitPlatformVersion())
377-
.filter(!_.isBlank())
378-
.map(v => mvn"org.junit.platform:junit-platform-launcher:${v.trim()}") ++
392+
Seq(junitPlatformVersion()).flatMap(v => {
393+
if (!v.isBlank) {
394+
Some(mvn"org.junit.platform:junit-platform-launcher:${v.trim()}")
395+
} else if (isJupiterBomAvailable()) {
396+
Some(mvn"org.junit.platform:junit-platform-launcher")
397+
} else {
398+
None
399+
}
400+
}) ++
379401
Seq(jupiterVersion())
380402
.filter(!_.isBlank())
381403
.map(v => mvn"org.junit.jupiter:junit-jupiter-api:${v.trim()}")
@@ -603,6 +625,8 @@ object TestModule {
603625
/**
604626
* TestModule that uses Spock Test Framework to run tests.
605627
* You can override the [[spockVersion]] task or provide the Spock dependency yourself.
628+
*
629+
* In case the version is set, it pulls in Spock-BOM in [[bomMvnDeps]] and Spock-Core in [[mvnDeps]]
606630
*/
607631
trait Spock extends TestModule.Junit5 {
608632

@@ -616,7 +640,24 @@ object TestModule {
616640
""
617641
}
618642

619-
// TODO currently bomMvnDeps not in JavaModuleBase so we cannot pull in the Spock-BOM
643+
private def isSpockBomAvailable: T[Boolean] = Task {
644+
if (spockVersion().isBlank) {
645+
false
646+
} else {
647+
Version.isAtLeast(spockVersion(), "2.3")(using Version.IgnoreQualifierOrdering)
648+
}
649+
}
650+
651+
override def bomMvnDeps: T[Seq[Dep]] = Task {
652+
super.bomMvnDeps() ++
653+
Seq(spockVersion())
654+
.filter(!_.isBlank() && isSpockBomAvailable())
655+
.flatMap(v =>
656+
Seq(
657+
mvn"org.spockframework:spock-bom:${v.trim()}"
658+
)
659+
)
660+
}
620661

621662
override def mandatoryMvnDeps: T[Seq[Dep]] = Task {
622663
super.mandatoryMvnDeps() ++
@@ -650,6 +691,7 @@ object TestModule {
650691
def mvnDeps: T[Seq[Dep]] = Seq()
651692
def mandatoryMvnDeps: T[Seq[Dep]] = Seq()
652693
def resources: T[Seq[PathRef]] = Task { Seq.empty[PathRef] }
694+
def bomMvnDeps: T[Seq[Dep]] = Seq()
653695
}
654696

655697
trait ScalaModuleBase extends mill.Module {

0 commit comments

Comments
 (0)