Skip to content
Open
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
541652c
Intial Groovy setup
lostiniceland Aug 20, 2025
51d6266
adding more test cases and fixing classloader issue during groovy com…
lostiniceland Sep 11, 2025
4bcb5b1
improve test-only-groovy to not rely on an existing outer module
lostiniceland Sep 12, 2025
45dfd9b
3-stage compile to support Groovy <-> Java cycles
lostiniceland Sep 15, 2025
cacf2c7
manage BOMs in Tests
lostiniceland Sep 16, 2025
eb13bc6
test with cross-compile Groovy 4 & 5
lostiniceland Sep 23, 2025
13c7ec9
samples
lostiniceland Sep 23, 2025
ea34a49
docs
lostiniceland Sep 24, 2025
9a26ea3
[autofix.ci] apply automated fixes
autofix-ci[bot] Sep 24, 2025
b8d28f7
Groovy Compiler options for bytecode version, preview features and as…
lostiniceland Sep 24, 2025
507b11b
[autofix.ci] apply automated fixes
autofix-ci[bot] Sep 24, 2025
e218ec2
Added example tests to CI setup
lefou Sep 26, 2025
485a8c3
Rudimentarily fix webpage generation
lefou Sep 26, 2025
f0cc0b8
Cleanup and Testcase for targetBytecode and previewEnabled
lostiniceland Sep 26, 2025
48b6020
[autofix.ci] apply automated fixes
autofix-ci[bot] Sep 26, 2025
21cf8f7
minor test improvement
lostiniceland Sep 26, 2025
0df8825
Mark API as experimental
lefou Sep 27, 2025
2c80e4b
Fix mima setup
lefou Sep 27, 2025
d232684
minor review remarks
lostiniceland Sep 29, 2025
7fac9ce
use Mill caching for stub folder
lostiniceland Sep 29, 2025
b5177ad
[autofix.ci] apply automated fixes
autofix-ci[bot] Sep 29, 2025
eed6b58
Revert back to experimental module
lostiniceland Oct 13, 2025
00b6893
[autofix.ci] apply automated fixes
autofix-ci[bot] Oct 13, 2025
ca34a80
Merge branch 'main' into groovylib
lostiniceland Nov 14, 2025
9bd964c
fix binary compat
lostiniceland Nov 14, 2025
7ec26ce
add scripting support
lostiniceland Nov 14, 2025
132d44e
Merge branch 'main' into groovylib
lostiniceland Nov 19, 2025
2c38719
Fixes after merge
lostiniceland Nov 19, 2025
f2e817b
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 19, 2025
fc252cc
get rid of example-usage-comments for now
lostiniceland Nov 19, 2025
e00d104
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 19, 2025
d8b8fb0
Fix integration tests
lostiniceland Nov 21, 2025
12ecb27
Merge branch 'main' into groovylib
lostiniceland Nov 21, 2025
fa4ca79
Merge branch 'main' into groovylib
lostiniceland Nov 28, 2025
6bbef67
Update core/api/daemon/src/mill/api/daemon/internal/GroovyModuleApi.s…
lostiniceland Nov 28, 2025
b18f152
Update libs/groovylib/src/mill/groovylib/GroovyModule.scala
lostiniceland Nov 28, 2025
3242bd4
Update libs/groovylib/src/mill/groovylib/GroovyWorkerManager.scala
lostiniceland Nov 28, 2025
14f8379
Update libs/groovylib/worker/src/mill/groovylib/worker/impl/GroovyWor…
lostiniceland Nov 28, 2025
e9a74bc
Update libs/script/src/GroovyModule.scala
lostiniceland Nov 28, 2025
650c611
Update libs/script/src/GroovyModule.scala
lostiniceland Nov 28, 2025
f91e58e
Update core/api/daemon/src/mill/api/daemon/internal/GroovyModuleApi.s…
lefou Nov 28, 2025
887ac9a
Merge groovy testing docu to groovy intro
lostiniceland Nov 28, 2025
3626125
Merge branch 'main' into groovylib
lihaoyi Dec 4, 2025
42be580
Update GroovyModule.scala
lihaoyi Dec 4, 2025
c9c8633
Update run-tests.yml
lihaoyi Dec 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ jobs:
millargs: "'example.androidlib.__.local.daemon'"
setup-android: true

- java-version: 17
millargs: "'example.groovylib.__.local.daemon'"
setup-android: true

- java-version: 17
millargs: "'example.thirdparty[android-compose-samples].packaged.daemon'"
setup-android: true
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package mill.api.daemon.internal

trait GroovyModuleApi extends JavaModuleApi
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ object BspModuleApi {
val Java = "java"
val Scala = "scala"
val Kotlin = "kotlin"
val Groovy = "groovy"
}

/** Used to define the [[BspBuildTarget.tags]] field. */
Expand Down
59 changes: 59 additions & 0 deletions example/groovylib/basic/1-simple/build.mill
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//// SNIPPET:BUILD

package build
import mill.*, groovylib.*

object foo extends GroovyModule {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
object foo extends GroovyModule {
@mill.api.experimental
object foo extends GroovyModule {

def groovyVersion = "5.0.1"

def mvnDeps = Seq(
mvn"org.apache.groovy:groovy-cli-commons", // BOM already loaded by module
mvn"org.apache.groovy:groovy-xml" // BOM already loaded by module
)

def mainClass = Some("foo.Foo")

object test extends GroovyTests with TestModule.Junit5 {
def jupiterVersion = "5.13.4"

def mvnDeps = Seq(
mvn"org.apache.groovy:groovy-test" // BOM already loaded by module
)
}
}

// This is a basic Mill build for a single `GroovyModule`, with one
// third-party dependency and a test suite using the JUnit framework.
//// SNIPPET:TREE
// ----
// build.mill
// foo/
// src/
// foo/Foo.groovy
// resources/
// ...
// test/
// src/
// foo/FooTest.groovy
// out/foo/
// compile.json
// compile.dest/
// ...
// test/
// compile.json
// compile.dest/
// ...
// ----
//
// NOTE: The default Mill source folder layout `foo/src/` differs from that of Maven/Gradle's
// `foo/src/main/groovy`. If you wish to use the Maven source folder layout, e.g. for migrating
// an existing codebase, you should use
// xref:#_maven_compatible_modules[Maven-Compatible Modules]
//
//// SNIPPET:DEPENDENCIES
//
// This example project uses two third-party dependencies
// - Groovy-Cli-Commons for CLI argument parsing
// - Groovy-Xml for HTML templating and escaping
// and uses them to wrap a given input string in HTML templates with proper escaping.
//
32 changes: 32 additions & 0 deletions example/groovylib/basic/1-simple/foo/src/foo/Foo.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package foo

import groovy.xml.MarkupBuilder
import groovy.cli.commons.CliBuilder

class Foo {
static String generateHtml(String text) {
def writer = new StringWriter()
new MarkupBuilder(writer).h1 {
mkp.yield text
}
writer.toString()
}

static void main(String[] args) {
def cli = new CliBuilder(usage:'help')
cli.t(longOpt:'text', args: 1, 'Passes text to the HTML generation')
def options = cli.parse(args)

if (!options) {
return
}

if (options.h) {
cli.usage()
return
}

String textToProcess = options.t ?: "hello from main"
println generateHtml(textToProcess)
}
}
15 changes: 15 additions & 0 deletions example/groovylib/basic/1-simple/foo/test/src/foo/FooTest.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package foo

import org.junit.jupiter.api.Test

class FooTest {
@Test
void "generate html created properly"() {
assert Foo.generateHtml("hello") == "<h1>hello</h1>"
}

@Test
void "generated html is properly escaped"() {
assert Foo.generateHtml("<hello>") == "<h1>&lt;hello&gt;</h1>"
}
}
38 changes: 38 additions & 0 deletions example/groovylib/basic/2-compat-modules/build.mill
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//// SNIPPET:ALL
// Mill's default folder layout of `foo/src/` and `foo/test/src` differs from that
// of Maven or Gradle's `foo/src/main/groovy/` and `foo/src/test/groovy/`. If you are
// migrating an existing codebase, you can use Mill's `GroovyMavenModule` and
// `GroovyMavenTests` as shown below to preserve filesystem compatibility with an existing
// Maven or Gradle build:

package build
import mill.*, groovylib.*

object foo extends GroovyMavenModule {

def groovyVersion = "5.0.1"

object test extends GroovyMavenTests with TestModule.Junit5 {}
object integration extends GroovyMavenTests with TestModule.Junit5 {}
}

// `GroovyMavenModule` is a variant of `GroovyModule`
// that uses the more verbose folder layout of Maven, `sbt`, and other tools:
//
// - `foo/src/main/java`
// - `foo/src/main/groovy`
// - `foo/src/test/java`
// - `foo/src/test/groovy`
// - `foo/src/integration/java`
// - `foo/src/integration/groovy`
//
// Rather than Mill's
//
// - `foo/src`
// - `foo/test/src`
//
// This is especially useful if you are migrating from Maven to Mill (or vice
// versa), during which a particular module may be built using both Maven and
// Mill at the same time
//
// For more details on migrating from other build tools, see xref:migrating/migrating.adoc[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package foo

import org.junit.jupiter.api.Test

class FooIntegrationTests {
@Test
void "hello should print correct greeting"() {
// Groovy creates an implicit class for the script named after the file
def foo = new Foo()
assert foo.hello() == "Hello World, Earth"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package foo

def run(){
println(hello())
}

def hello() {
"Hello World, ${Foo2.VALUE}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package foo;

public class Foo2 {
public static final String VALUE = "Earth";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package foo

import org.junit.jupiter.api.Test

class FooTest {

@Test
void "hello should print correct greeting"() {
// Groovy creates an implicit class for the script named after the file
def foo = new Foo()
assert foo.hello() == "Hello World, Earth"
}
}
9 changes: 9 additions & 0 deletions example/groovylib/testing/1-test-suite/bar/src/bar/Bar.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package bar

def hello() {
"Hello World"
}

def run(){
println new Bar().hello()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package bar

import org.junit.jupiter.api.Test
import groovy.mock.interceptor.MockFor

class BarTests{
@Test
void "hello"() {
def result = new Bar().hello()
assert result == "Hello World"
}

@Test
void "world"() {
def result = new Bar().hello()
assert result.endsWith("World")
}

@Test
void "using groovy mocks"() {
def mockBar = new MockFor(Bar)
mockBar.demand.hello { "Hello GroovyMock World" }

mockBar.use{
def result = new Bar().hello()
assert result == "Hello GroovyMock World"
}
}
}
31 changes: 31 additions & 0 deletions example/groovylib/testing/1-test-suite/build.mill
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//// SNIPPET:BUILD1
package build
import mill.*, groovylib.*

object foo extends GroovyModule {

def groovyVersion = "5.0.1"

object test extends GroovyTests with TestModule.Junit5 {
def jupiterVersion = "5.13.4"

def mvnDeps = Seq(
mvn"org.apache.groovy:groovy-test" // BOM already loaded by module
)
}
}

object bar extends GroovyModule {

def mainClass = Some("bar.Bar")

def groovyVersion = "5.0.1"

object test extends GroovyTests, TestModule.Junit5 {
def jupiterVersion = "5.13.4"

def mvnDeps = Seq(
mvn"org.apache.groovy:groovy-test" // BOM already loaded by module
)
}
}
11 changes: 11 additions & 0 deletions example/groovylib/testing/1-test-suite/foo/src/foo/Foo.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package foo

class Foo {
def hello() {
"Hello World"
}

static void main(String[] args){
println Foo().hello()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package foo

import org.junit.jupiter.api.Test
import groovy.mock.interceptor.MockFor

class FooMoreTests{
@Test
void "hello"() {
def result = new Foo().hello()
assert result == "Hello World"
}

@Test
void "world"() {
def result = new Foo().hello()
assert result.endsWith("World")
}

@Test
void "using groovy mocks"() {
def mockFoo = new MockFor(Foo)
mockFoo.demand.hello { "Hello GroovyMock World" }

mockFoo.use{
def result = new Foo().hello()
assert result == "Hello GroovyMock World"
}
}
}
20 changes: 20 additions & 0 deletions example/groovylib/testing/2-integration-suite/build.mill
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//// SNIPPET:BUILD2
package build
import mill.*, groovylib.*
object qux extends GroovyModule {

def groovyVersion = "5.0.1"

object test extends GroovyTests with TestModule.Junit5 {
def mvnDeps = super.mvnDeps() ++ Seq(
mvn"org.apache.groovy:groovy-test"
)
}
object integration extends GroovyTests with TestModule.Junit5 {
def mvnDeps = super.mvnDeps() ++ Seq(
mvn"org.apache.groovy:groovy-test"
)
}
}

// The integration suite is just another regular test module within the parent GroovyModule
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package qux

import org.junit.jupiter.api.Test

class QuxIntegrationTests {

@Test
void "hello"() {
def result = new Qux().hello()
assert result == "Hello World"
}

@Test
void "world"() {
def result = new Qux().hello()
assert result.endsWith("World")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package qux

class Qux {
static void main(String[] args){
println(hello())
}

String hello(){
"Hello World"
}
}
Loading
Loading