Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Annotation Processors with Lombok example, reorganize github actions test matrix #3331

Merged
merged 24 commits into from
Aug 4, 2024
56 changes: 33 additions & 23 deletions .github/workflows/actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,12 @@ jobs:
matrix:
include:
# bootstrap tests
- java-version: 8
buildcmd: ci/test-mill-release.sh
- java-version: 17
buildcmd: ci/test-mill-release.sh
# Limit some tests to Java 17 to limit CI times
- java-version: 17
- java-version: 8 # Have one job on oldest JVM
buildcmd: ci/test-mill-dev.sh
- java-version: 17 # Have one job on default JVM
buildcmd: ci/test-mill-release.sh
- java-version: 17
buildcmd: ci/test-mill-bootstrap.sh
# Have one job on latest JVM
- java-version: 20
buildcmd: ci/test-mill-bootstrap.sh
# Just some reporting to enable reasoning about library upgrades
- java-version: 8
buildcmd: |
Expand All @@ -64,24 +58,40 @@ jobs:
matrix:
java-version: [8, 17]
millargs:
# unit and module tests
# Run unit and module tests on both oldest and newest Java versions
- '"{main,scalalib,testrunner,bsp}.__.test"'
- '"scalajslib.__.test"'
- '"scalanativelib.__.test"'
# integration tests
- "integration.feature.__.server.test"
- "integration.feature.__.fork.test"
# contrib tests
- "contrib._.test"

include:
# Limit some tests to Java 17 to limit CI times
# Integration and example tests are slow, so don't run the on multiple Java versions

# Group these tests together to try and balance out the runtimes of each job
# Just running in `local` mode since they shouldn't depend on the mode
- java-version: 17
millargs: "'example.{basic,scalabuilds,scalamodule,web}[_].local.test'"
- java-version: 17
millargs: "'example.{basicjava,javabuilds,javamodule,javaweb}[_].local.test'"
- java-version: 17
millargs: "'example.{thirdparty,cross,misc,tasks}[_].local.test'"

# Most of these integration tests should not depend on which mode they
# are run in, so just run them in `local`
- java-version: 17
millargs: "'integration.{failure,feature,ide}[_].local.test'"

# These invalidation tests need to be exercised in all three execution modes
# to make sure they work with and without -i/--no-server being passed
- java-version: 17
millargs: "example.__.local.test"
millargs: "'integration.invalidation[_].local.test'"
- java-version: 17
millargs: "integration.feature.__.local.test"
millargs: "'integration.invalidation[_].fork.test'"
- java-version: 17
millargs: "integration.failure.__.test"
millargs: "'integration.invalidation[_].server.test'"

# Check docsite compiles
- java-version: 17
millargs: docs.githubPages

Expand Down Expand Up @@ -130,16 +140,16 @@ jobs:

include:
# Limit some tests to Java 17 to limit CI times
# just run a subset of examples/ on Windows, because for some reason running
# the whole suite can take hours on windows v.s. half an hour on linux
- java-version: 17
# just run a subset of examples/ on Windows, because for some reason running
# the whole suite can take hours on windows v.s. half an hour on linux
millargs: '"example.basic.__.local.test"'
millargs: '"example.basic[_].local.test"'
- java-version: 17
millargs: "integration.feature.__.fork.test"
millargs: "'integration.feature[_].fork.test'"
- java-version: 17
millargs: "integration.feature.__.server.test"
millargs: "'integration.invalidation[_].server.test'"
- java-version: 17
millargs: "integration.failure.__.fork.test"
millargs: "'integration.failure[_].fork.test'"
- java-version: 17
millargs: "contrib.__.test"

Expand Down
2 changes: 2 additions & 0 deletions build.sc
Original file line number Diff line number Diff line change
Expand Up @@ -1370,6 +1370,8 @@ object example extends MillScalaModule {
object integration extends MillScalaModule {
object failure extends Cross[IntegrationCrossModule](listIn(millSourcePath / "failure"))
object feature extends Cross[IntegrationCrossModule](listIn(millSourcePath / "feature"))
object invalidation extends Cross[IntegrationCrossModule](listIn(millSourcePath / "invalidation"))
object ide extends Cross[IntegrationCrossModule](listIn(millSourcePath / "ide"))
trait IntegrationCrossModule extends IntegrationTestCrossModule

def moduleDeps = Seq(scalalib, scalajslib, scalanativelib, runner.test)
Expand Down
1 change: 0 additions & 1 deletion ci/test-mill-bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,4 @@ ci/prepare-mill-bootstrap.sh

# Run tests
target/mill-release -i "__.compile"
target/mill-release -i "{main,scalalib}.__.test"
target/mill-release -i "example.basic[1-simple].server.test"
4 changes: 4 additions & 0 deletions docs/modules/ROOT/pages/Java_Module_Config.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,7 @@ If you are using millw, a more permanent solution could be to set the environmen
== Native C Code with JNI

include::example/javamodule/12-jni.adoc[]

== Annotation Processors with Lombok

include::example/javamodule/13-annotation-processors-lombok.adoc[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package bar;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;

public class GetterSetterExample {
/**
* Age of the person. Water is wet.
*
* @param age New value for this person's age. Sky is blue.
* @return The current value of this person's age. Circles are round.
*/
@Getter @Setter private int age = 10;

/**
* Name of the person.
* -- SETTER --
* Changes the name of this person.
*
* @param name The new value.
*/
@Setter(AccessLevel.PROTECTED) private String name;

@Override public String toString() {
return String.format("%s (age: %d)", name, age);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package bar;
import static org.junit.Assert.assertEquals;
import org.junit.Test;

public class HelloWorldTest {
@Test
public void testSimple() {
GetterSetterExample exampleValue = new GetterSetterExample();
assertEquals(exampleValue.getAge(), 10);
exampleValue.setAge(20);
assertEquals(exampleValue.getAge(), 20);
}
}
57 changes: 57 additions & 0 deletions example/javamodule/13-annotation-processors-lombok/build.sc
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import mill._, javalib._


object foo extends JavaModule {
def compileIvyDeps = Agg(ivy"org.projectlombok:lombok:1.18.34")

object test extends JavaTests with TestModule.Junit4
}

// This is an example of how to use Mill to build Java projects using Java annotations and
// annotation processors. In this case, we use the annotations provided by
// https://projectlombok.org[Project Lombok] to automatically generate getters and setters
// from class private fields

/** Usage

> ./mill foo.test
Test foo.HelloWorldTest.testSimple started
Test foo.HelloWorldTest.testSimple finished...
...

*/

// The Java compiler automatically discovers annotation processors based on the
// classes available during compilation, e.g. on `compileIvyDeps` or `ivyDeps`,
// which is what takes place in the example above.
//
// In some cases, you may need
// to pass in the annotation processors manually, e.g. if you need annotation
// processors that are not on the compilation classpath, or you need finer control
// over exactly which annotation processors are active. To do this, you can define
// a module to contain the exact annotation processors you want, and pass
// in `-processorpath` to `javacOptions` explicitly:

object processors extends JavaModule{
def ivyDeps = Agg(ivy"org.projectlombok:lombok:1.18.34")
}

object bar extends JavaModule {
def compileIvyDeps = Agg(ivy"org.projectlombok:lombok:1.18.34")

def javacOptions = Seq(
"-processorpath",
processors.runClasspath().map(_.path).mkString(":"),
)

object test extends JavaTests with TestModule.Junit4
}

/** Usage

> ./mill bar.test
Test bar.HelloWorldTest.testSimple started
Test bar.HelloWorldTest.testSimple finished...
...

*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package foo;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;

public class GetterSetterExample {
/**
* Age of the person. Water is wet.
*
* @param age New value for this person's age. Sky is blue.
* @return The current value of this person's age. Circles are round.
*/
@Getter @Setter private int age = 10;

/**
* Name of the person.
* -- SETTER --
* Changes the name of this person.
*
* @param name The new value.
*/
@Setter(AccessLevel.PROTECTED) private String name;

@Override public String toString() {
return String.format("%s (age: %d)", name, age);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package foo;
import static org.junit.Assert.assertEquals;
import org.junit.Test;

public class HelloWorldTest {
@Test
public void testSimple() {
GetterSetterExample exampleValue = new GetterSetterExample();
assertEquals(exampleValue.getAge(), 10);
exampleValue.setAge(20);
assertEquals(exampleValue.getAge(), 20);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,46 +11,48 @@ object SubprocessStdoutTests extends IntegrationTestSuite {
// Make sure that when a lot of printed/inherited stdout/stderr is printed
// in quick succession, the output ordering is preserved and it doesn't get
// jumbled up
assert(
res1.contains(
s"""print stdout1
|proc stdout1
|print stderr1
|proc stderr1
|print stdout2
|proc stdout2
|print stderr2
|proc stderr2
|print stdout3
|proc stdout3
|print stderr3
|proc stderr3
|print stdout4
|proc stdout4
|print stderr4
|proc stderr4
|print stdout5
|proc stdout5
|print stderr5
|proc stderr5
|print stdout6
|proc stdout6
|print stderr6
|proc stderr6
|print stdout7
|proc stdout7
|print stderr7
|proc stderr7
|print stdout8
|proc stdout8
|print stderr8
|proc stderr8
|print stdout9
|proc stdout9
|print stderr9
|proc stderr9""".stripMargin.replaceAll("\r\n", "\n")
retry(3) {
assert(
res1.contains(
s"""print stdout1
|proc stdout1
|print stderr1
|proc stderr1
|print stdout2
|proc stdout2
|print stderr2
|proc stderr2
|print stdout3
|proc stdout3
|print stderr3
|proc stderr3
|print stdout4
|proc stdout4
|print stderr4
|proc stderr4
|print stdout5
|proc stdout5
|print stderr5
|proc stderr5
|print stdout6
|proc stdout6
|print stderr6
|proc stderr6
|print stdout7
|proc stdout7
|print stderr7
|proc stderr7
|print stdout8
|proc stdout8
|print stderr8
|proc stderr8
|print stdout9
|proc stdout9
|print stderr9
|proc stderr9""".stripMargin.replaceAll("\r\n", "\n")
)
)
)
}

// Make sure subprocess output that isn't captures by all of Mill's stdout/stderr/os.Inherit
// redirects still gets pikced up from the stdout/stderr log files and displayed. They may
Expand Down