Skip to content

Commit 9593582

Browse files
authored
Improvements to examples and integration tests (#6254)
* Move spring-boot examples to config-based `build.mill.yaml` syntax. I leave one programmatic example so people know you can use it, but as a getting started experience the config-based syntax is probably superior * Make plugin examples publish against Mill1.0.0/Scala3.7.4/Java11, with an explanation of why * Use `IntegrationTester.EvalResult` in `ExampleTester` to improve readability of command line error output
1 parent 8dbcf48 commit 9593582

File tree

40 files changed

+215
-139
lines changed

40 files changed

+215
-139
lines changed

example/extending/plugins/1-writing-mill-plugins/build.mill

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
1-
//| mill-jvm-version: 17
21
// This example demonstrates how to write and test Mill plugin, and publish it to
32
// Sonatype's Maven Central so it can be used by other developers over the internet
43
// via xref:extending/import-mvn-plugins.adoc[//| mvnDeps].
54

65
// == Project Configuration
76
package build
87
import mill.*, scalalib.*, publish.*
9-
import mill.util.BuildInfo.{millVersion, millBinPlatform}
108

119
object myplugin extends ScalaModule, PublishModule {
12-
def scalaVersion = "3.8.0-RC1"
10+
def millVersion = "1.0.6"
11+
12+
def scalaVersion = "3.7.4"
13+
14+
def jvmId = "11"
1315

1416
// Set the `platformSuffix` so the name indicates what Mill version it is compiled for
15-
def platformSuffix = s"_mill$millBinPlatform"
17+
def platformSuffix = s"_mill1"
1618

1719
// Depend on `mill-libs` so we can compile against Mill APIs
1820
def mvnDeps = Seq(mvn"com.lihaoyi::mill-libs:$millVersion")
@@ -45,11 +47,12 @@ object myplugin extends ScalaModule, PublishModule {
4547
// It looks like any other Scala project, except for a few dependencies on `mill-libs`
4648
// and `mill-testkit` to bring in the appropriate libraries
4749

48-
// Note that when publishing artifacts to Maven repositories, the JVM version used to build the
49-
// artifacts will be the minimum version that downstream projects will need to use in order to
50-
// use your artifacts. Thus it is best to set your `mill-jvm-version` to the lowest version
51-
// possible, e.g. `mill-jvm-version: 17` in this example which is the lowest version supported
52-
// by Mill.
50+
// NOTE: that Mill 1.x is _backwards compatible_ but not _forwards compatible_ with regard to plugins,
51+
// so a plugin published for a particular version of Mill will work on _newer_ versions of Mill,
52+
// but not _older_ versions. Thus when publishing plugins it is usually best to publish for as
53+
// old a 1.x version of Mill as you can, to ensure maximal compatibility with downstream projects.
54+
// In this example, we publish for Mill-1.0.6/Scala-3.7.4/JDK11, even though our plugins own build
55+
// may be on a version of Mill 1.1.0 or later.
5356

5457
// == Plugin Implementation
5558

@@ -115,7 +118,7 @@ compiling 1 Scala source...
115118
> sed -i.bak 's/0.0.1/0.0.2/g' build.mill
116119

117120
> ./mill myplugin.publishLocal
118-
Publishing Artifact(com.lihaoyi,myplugin_millSNAPSHOT_3,0.0.2) to ivy repo...
121+
Publishing Artifact(com.lihaoyi,myplugin_mill1_3,0.0.2) to ivy repo...
119122

120123
*/
121124
// Mill plugins are JVM libraries like any other library written in Java or Scala. Thus they

example/extending/plugins/2-plugin-integration-tests/build.mill

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66

77
package build
88
import mill.*, scalalib.*, publish.*
9-
import mill.util.BuildInfo.{millVersion, millBinPlatform}
109

1110
object myplugin extends ScalaModule, PublishModule {
12-
def scalaVersion = "3.8.0-RC1"
11+
def millVersion = "1.0.6"
12+
13+
def scalaVersion = "3.7.4"
14+
15+
def jvmId = "11"
1316

1417
// Set the `platformSuffix` so the name indicates what Mill version it is compiled for
15-
def platformSuffix = s"_mill$millBinPlatform"
18+
def platformSuffix = s"_mill1"
1619

1720
// Depend on `mill-libs` so we can compile against Mill APIs
1821
def mvnDeps = Seq(mvn"com.lihaoyi::mill-libs:$millVersion")
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//| mill-jvm-version: 17
2+
3+
// Spring boot projects can also be built using Mill's programmatic `build.mill` syntax,
4+
// as shown below:
5+
6+
package build
7+
import mill.*, javalib.*
8+
9+
object `package` extends JavaModule {
10+
def mvnDeps = Seq(
11+
mvn"org.springframework.boot:spring-boot-starter-web:2.5.6",
12+
mvn"org.springframework.boot:spring-boot-starter-actuator:2.5.6"
13+
)
14+
15+
object test extends JavaTests, TestModule.Junit5 {
16+
def mvnDeps = Seq(mvn"org.springframework.boot:spring-boot-starter-test:2.5.6")
17+
}
18+
}
19+
20+
/** Usage
21+
22+
> ./mill test
23+
...com.example.HelloSpringBootTest#shouldReturnDefaultMessage() finished...
24+
25+
> ./mill runBackground
26+
27+
> curl http://localhost:8086
28+
...<h1>Hello, World!</h1>...
29+
30+
> ./mill clean runBackground
31+
32+
*/
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
server.port=8086
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.example;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
import org.springframework.web.bind.annotation.GetMapping;
6+
import org.springframework.web.bind.annotation.RestController;
7+
8+
@SpringBootApplication
9+
public class HelloSpringBoot {
10+
11+
public static void main(String[] args) {
12+
SpringApplication.run(HelloSpringBoot.class, args);
13+
}
14+
15+
@RestController
16+
class HelloController {
17+
@GetMapping("/")
18+
public String hello() {
19+
return "<h1>Hello, World!</h1>";
20+
}
21+
}
22+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.example;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
5+
import org.junit.jupiter.api.Test;
6+
import org.springframework.beans.factory.annotation.Autowired;
7+
import org.springframework.boot.test.context.SpringBootTest;
8+
import org.springframework.boot.test.web.client.TestRestTemplate;
9+
import org.springframework.boot.web.server.LocalServerPort;
10+
11+
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
12+
public class HelloSpringBootTest {
13+
14+
@LocalServerPort
15+
private int port;
16+
17+
@Autowired
18+
private TestRestTemplate restTemplate;
19+
20+
@Test
21+
public void shouldReturnDefaultMessage() {
22+
String response = restTemplate.getForObject("http://localhost:" + port + "/", String.class);
23+
assertEquals("<h1>Hello, World!</h1>", response);
24+
}
25+
}

example/javalib/springboot/2-todo-spring-boot/build.mill

Lines changed: 0 additions & 64 deletions
This file was deleted.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/** See Also: build.mill.yaml */
2+
3+
// This is a larger example using Spring Boot, using Mill's
4+
// xref:javalib/intro.adoc#_programmatic_modules[programmatic build.mill] syntax,
5+
// implementing the well known https://todomvc.com/[TodoMVC] example app. Apart from
6+
// running a webserver, this example also demonstrates:
7+
//
8+
// * Serving HTML templates using Thymeleaf
9+
// * Serving static Javascript and CSS using Webjars
10+
// * Querying a SQL database using JPA and H2
11+
// * Unit testing using a H2 in-memory database
12+
// * Integration testing using Testcontainers Postgres in Docker
13+
14+
/** Usage
15+
16+
> ./mill test
17+
...com.example.TodomvcTests#homePageLoads() finished...
18+
...com.example.TodomvcTests#addNewTodoItem() finished...
19+
20+
> ./mill integration
21+
...com.example.TodomvcIntegrationTests#homePageLoads() finished...
22+
...com.example.TodomvcIntegrationTests#addNewTodoItem() finished...
23+
24+
> ./mill test.runBackground
25+
26+
> curl http://localhost:8087
27+
...<h1>todos</h1>...
28+
29+
> ./mill clean runBackground
30+
31+
*/
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
mill-jvm-version: 17
2+
extends: [mill.javalib.JavaModule]
3+
mvnDeps:
4+
- org.springframework.boot:spring-boot-starter-data-jpa:2.5.4
5+
- org.springframework.boot:spring-boot-starter-thymeleaf:2.5.4
6+
- org.springframework.boot:spring-boot-starter-validation:2.5.4
7+
- org.springframework.boot:spring-boot-starter-web:2.5.4
8+
- javax.xml.bind:jaxb-api:2.3.1
9+
- org.webjars:webjars-locator:0.41
10+
- org.webjars.npm:todomvc-common:1.0.5
11+
- org.webjars.npm:todomvc-app-css:2.4.1
12+
13+
object test:
14+
extends: [JavaTests, mill.javalib.TestModule.Junit5]
15+
mainClass: com.example.TodomvcApplication
16+
mvnDeps:
17+
- com.h2database:h2:2.3.230
18+
- org.springframework.boot:spring-boot-starter-test:2.5.6
19+
20+
object integration:
21+
extends: [JavaTests, mill.javalib.TestModule.Junit5]
22+
mainClass: com.example.TodomvcApplication
23+
mvnDeps:
24+
- org.testcontainers:testcontainers:1.18.0
25+
- org.testcontainers:junit-jupiter:1.18.0
26+
- org.testcontainers:postgresql:1.18.0
27+
- org.postgresql:postgresql:42.6.0
28+
- org.springframework.boot:spring-boot-starter-test:2.5.6

0 commit comments

Comments
 (0)