Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 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
8dff442
Merge branch 'main' into groovylib
lihaoyi Dec 8, 2025
34c27ce
Merge branch 'main' into groovylib
lostiniceland Dec 8, 2025
accb501
Merge branch 'main' into groovylib
lostiniceland Dec 9, 2025
6f408da
Fix dependency and import after changes from main
lostiniceland Dec 10, 2025
f174c22
enable Groovy scripting
lostiniceland Dec 10, 2025
473dbdc
update docs to new structure
lostiniceland Dec 10, 2025
beaebdf
[autofix.ci] apply automated fixes
autofix-ci[bot] Dec 10, 2025
d2599a2
Merge remote-tracking branch 'origin/main' into groovylib
lefou Dec 11, 2025
0c475bc
fix test
lefou Dec 11, 2025
d6da80f
Properly call super from bomMvnDeps
lefou Dec 11, 2025
79da168
Exclude MiMa problem
lefou Dec 11, 2025
20c6a0b
[autofix.ci] apply automated fixes
autofix-ci[bot] Dec 11, 2025
a0beb42
Rename page to match other languages
lefou Dec 11, 2025
03cb5f6
Added a declarative example and fixed website generation
lefou Dec 11, 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 @@ -157,6 +157,10 @@ jobs:
millargs: "'example.androidlib.__.shared.daemon'"
setup-android: true

- java-version: 17
millargs: "'example.groovylib.__.shared.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,4 @@
package mill.api.daemon.internal

@mill.api.daemon.experimental
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
1 change: 1 addition & 0 deletions core/eval/src/mill/eval/ScriptModuleInit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class ScriptModuleInit extends ((String, Evaluator) => Seq[Result[ExternalModule
case "java" => Result.Success("mill.script.JavaModule")
case "kt" => Result.Success("mill.script.KotlinModule")
case "scala" => Result.Success("mill.script.ScalaModule")
case "groovy" => Result.Success("mill.script.GroovyModule")
case _ =>
Result.Failure(
s"Script ${scriptFile.relativeTo(mill.api.BuildCtx.workspaceRoot)} has no `extends` clause configured and is of an unknown extension `${scriptFile.ext}`"
Expand Down
11 changes: 11 additions & 0 deletions example/groovylib/basic/1-script/Foo.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class Foo {

static void main(String[] args) {
if(args == null || args.length != 1){
println "Specify exactly one parameter for greeting"
System.exit(1)
}

println "Hello ${args[0]}"
}
}
32 changes: 32 additions & 0 deletions example/groovylib/basic/1-script/build.mill
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//// SNIPPET:FILE
/** See Also: Foo.groovy */
//// SNIPPET:END

//// SNIPPET:CMD
/** Usage
> ./mill Foo.groovy bar
Compiling 1 Groovy sources to...
Hello bar
*/
//// SNIPPET:END
//// SNIPPET:MORE

/** Usage
> ./mill Foo.groovy:run bar
Hello bar
*/

//// SNIPPET:END

//// SNIPPET:RESOLVE
/** Usage

> ./mill resolve Foo.groovy:_
Foo.groovy:run
Foo.groovy:runMain
Foo.groovy:compile
Foo.groovy:assembly
...

*/
//// SNIPPET:END
49 changes: 49 additions & 0 deletions example/groovylib/basic/11-declarative/build.mill
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// This is a basic Mill build for a single `GroovyModule`, with one
// third-party dependency and a test suite using the JUnit framework.
//
// 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.
//

/** See Also: build.mill.yaml */
/** See Also: test/package.mill.yaml */

/** Usage

> ./mill resolve _ # List what tasks are available to run
assembly
...
compile
...
run
...
test

*/

/** Usage
> ./mill run --text hello
<h1>hello</h1>
*/

/** Usage
> ./mill test
Running Test Class foo.FooTest
Test foo.FooTest#generate html created properly() finished...
Test foo.FooTest#generated html is properly escaped() finished...
Test foo.FooTest finished...

*/

/** Usage
> ./mill assembly # bundle classfiles and libraries into a jar for deployment

> ./mill show assembly # show the output of the assembly task
".../out/assembly.dest/out.jar"

> java -jar ./out/assembly.dest/out.jar --text hello
<h1>hello</h1>

*/
6 changes: 6 additions & 0 deletions example/groovylib/basic/11-declarative/build.mill.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
extends: [mill.groovylib.GroovyModule]
groovyVersion: 5.0.1
mvnDeps:
- org.apache.groovy:groovy-cli-commons
- org.apache.groovy:groovy-xml
mainClass: foo.Foo
32 changes: 32 additions & 0 deletions example/groovylib/basic/11-declarative/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)
}
}
4 changes: 4 additions & 0 deletions example/groovylib/basic/11-declarative/test/package.mill.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
extends: [build.GroovyTests, mill.javalib.TestModule.Junit5]
jupiterVersion: 5.13.4
mvnDeps:
- org.apache.groovy:groovy-test
15 changes: 15 additions & 0 deletions example/groovylib/basic/11-declarative/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>"
}
}
59 changes: 59 additions & 0 deletions example/groovylib/basic/3-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 {
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/3-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/3-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>"
}
}
13 changes: 13 additions & 0 deletions example/groovylib/basic/4-module-deps/bar/src/bar/Bar.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package bar

import groovy.xml.MarkupBuilder

class Bar {
static String generateHtml(String text) {
def writer = new StringWriter()
new MarkupBuilder(writer).h1 {
mkp.yield text
}
writer.toString()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package bar

import org.junit.jupiter.api.Test

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

@Test
void "generated html is properly escaped"() {
assert Bar.generateHtml("<hello>") == "<h1>&lt;hello&gt;</h1>"
}
}
53 changes: 53 additions & 0 deletions example/groovylib/basic/4-module-deps/build.mill
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package build
import mill.*, groovylib.*

object foo extends GroovyModule {

def groovyVersion = "5.0.1"

def moduleDeps = Seq(build.bar)
def mvnDeps = Seq(
mvn"org.apache.groovy:groovy-cli-commons" // BOM already loaded by module
)
}

object bar extends GroovyModule {

def groovyVersion = "5.0.1"

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

object test extends GroovyTests with TestModule.Junit5 {}
}
//// SNIPPET:TREE
// ----
// build.mill
// foo/
// src/
// foo/Foo.groovy
// test/
// src/
// foo/FooTests.groovy
// bar/
// src/
// bar/Bar.groovy
// test/
// src/
// bar/BarTests.groovy
// out/
// foo/
// compile.json
// compile.dest/
// ...
// bar/
// compile.json
// compile.dest/
// ...
// test/
// compile.json
// compile.dest/
// ...
// ----
//
Loading
Loading