From 76b8f6407191c0994f5d455e3005023df32b2270 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Tue, 28 Jan 2025 15:51:16 +0800 Subject: [PATCH] Doc Review `Java Library Dependencies` to `Java Web Project Examples` (#4420) --- .../ROOT/pages/cli/installation-ide.adoc | 67 ++++++++++++------- .../ROOT/pages/comparisons/why-mill.adoc | 26 ++++--- .../ROOT/pages/pythonlib/dependencies.adoc | 2 +- .../builtins/1-builtin-commands/build.mill | 23 +++++++ .../modules/8-diy-java-modules/build.mill | 2 +- .../linting/3-palantirformat/build.mill | 2 +- .../module/8-annotation-processors/build.mill | 4 +- example/javalib/publishing/5-jlink/build.mill | 27 ++++---- .../javalib/publishing/6-jpackage/build.mill | 62 +++++++---------- .../publishing/8-native-image-libs/build.mill | 3 +- .../javalib/testing/1-test-suite/build.mill | 4 ++ .../build.mill | 2 +- .../publishing/8-native-image-libs/build.mill | 3 +- .../kotlinlib/testing/1-test-suite/build.mill | 4 ++ example/pythonlib/basic/1-simple/build.mill | 2 +- .../4-downloading-unmanaged-wheels/build.mill | 2 +- .../pythonlib/testing/1-test-suite/build.mill | 5 +- .../dependencies/1-ivy-deps/build.mill | 2 +- .../4-downloading-unmanaged-jars/build.mill | 2 +- .../5-repository-config/build.mill | 2 +- .../scalalib/module/11-main-class/build.mill | 2 +- .../publishing/1-assembly-config/build.mill | 2 +- .../publishing/7-native-image/build.mill | 4 +- .../publishing/8-native-image-libs/build.mill | 13 ++-- .../scalalib/testing/1-test-suite/build.mill | 26 ++++--- .../scalalib/testing/2-test-deps/build.mill | 2 +- 26 files changed, 175 insertions(+), 120 deletions(-) diff --git a/docs/modules/ROOT/pages/cli/installation-ide.adoc b/docs/modules/ROOT/pages/cli/installation-ide.adoc index f76ec3ddf11..dcca1f1f5e3 100644 --- a/docs/modules/ROOT/pages/cli/installation-ide.adoc +++ b/docs/modules/ROOT/pages/cli/installation-ide.adoc @@ -14,8 +14,8 @@ globally. [#_bootstrap_scripts] == Bootstrap Scripts -Although the Mill example projects come with their own `./mill` and `./mill.bat` bootstrap script, -you can also download it manually: +The Mill example projects in this documentation come with `./mill` and `./mill.bat` +bootstrap script, included. You can also download the boostrap script manually: [source,bash,subs="verbatim,attributes"] ---- @@ -58,7 +58,7 @@ pick one most similar to what you are doing so you can hit the ground running wo The default Mill executable configured above requires a JVM (11 or above) installed globally in order to run, and imposes some Java startup overhead (100-200ms) when running Mill from the -command line.You can also use Mill's native executables by appending a `-native` suffix to the +command line. You can also use Mill's native executables by appending a `-native` suffix to the Mill version: [source,bash,subs="verbatim,attributes"] @@ -67,27 +67,41 @@ echo {mill-last-tag}-native > .mill-version ---- Using the `-native` suffix should provide a faster CLI experience than using Mill's default -JVM launcher. Mill native executables are supported on the following OS/CPU combinations: +JVM launcher, and makes it easier to install Mill in environments without a JVM pre-installed. -- `windows-amd64` (Intel Windows) -- `linux-amd64` (Intel Linux) -- `mac-aarch64` (M1-M4 Mac) -If you are on a combination not supported by Mill's native executables, use the default +Mill native executables are supported on the following OS/CPU combinations: + +|=== +| | Windows | Mac | Linux +| Intel | Y | Y | Y +| ARM | | Y | Y +|=== + +Notably, Mill native executables _do not_ support Windows-ARM, due to limitations in the +upstream Graal Native Image tooling (see https://github.com/oracle/graal/issues/9215[oracle/graal#9215]). +If you are on a platform not supported by Mill's native executables, use the default JVM launcher instead. === Customizing Mill's JVM -To use Mill in environments without a JVM installed, the native launcher can download its -own JVM as necessary. You need to specify the version you want via a `.mill-jvm-version` -file such as: +Mill allows you to specify the exact JVM version you want to use to run the build tool +via a `.mill-jvm-version` file such as: ```bash echo temurin:17.0.6 > .mill-jvm-version ``` -`.mill-jvm-version` can also be used with Mill's default JVM launcher, if you want -your Mill process to use a different JVM than what you have installed globally. +This has two benefits + +* `.mill-jvm-version` can also be used with Mill's default JVM launcher if you want +your Mill process to use a different JVM than what you have installed globally. This +can help ensure your project uses a consistent JVM version and behaves identically regardless +of what the developer may have installed on their laptop or dev environment + +* `.mill-jvm-version` can be used together with <>s to build your +project without needing a JVM pre-installed at all. This simplifies project setup and +onboarding of new developers. == IDE Support @@ -97,12 +111,7 @@ your Mill process to use a different JVM than what you have installed globally. Mill supports IntelliJ and VSCode and in general any client of the standard https://build-server-protocol.github.io/[Build Server Protocol (BSP)]. -To prepare your project for IDEs, and in general any BSP client, you can run this command to generate the BSP configuration files: -[source,bash] ----- -./mill mill.bsp.BSP/install ----- Your IDEs may already auto-detect the Mill project and run this command on behalf of you, when opening/importing the project. @@ -111,7 +120,7 @@ Your IDEs may already auto-detect the Mill project and run this command on behal To use Mill with IntelliJ, first ensure you have the free https://plugins.jetbrains.com/plugin/1347-scala[IntelliJ Scala Plugin] installed. This is necessary as Mill build files are written in Scala, -even if you are using it to build a Java or Kotlin project. +even if you are using it to build a Java or Kotlin or Python project. Once you have the plugin installed, you can use IntelliJ to open any project containing a Mill `build.mill` file, and IntelliJ will automatically load the @@ -139,6 +148,14 @@ those updates by opening the "BSP" tab and clicking the "Refresh" button image::basic/IntellijRefresh.png[] +To prepare your project for IDEs, and in general any BSP client, you can also +run this command to generate the BSP configuration files: + +[source,bash] +---- +./mill mill.bsp.BSP/install +---- + ==== IntelliJ IDEA XML Support Apart from using the Build Server Protocol, you can also generate IDEA project @@ -235,7 +252,7 @@ MILL_VERSION=0.5.0-3-4faefb ./mill __.compile to override the Mill version manually. This takes precedence over the version specified in `./mill`, `.config/mill-version` or `.mill-version` -== Working without access to Maven Central +== Using Mill without access to Maven Central Under some circumstances (e.g. corporate firewalls), you may not have access maven central. The typical symptom will be error messages which look like this; @@ -251,19 +268,21 @@ Resolution failed for 1 modules: ---- It is expected that basic commands (e.g. clean) will not work, as Mill saying it is -unable to resolve it's own, fundamental, dependencies. Under such circumstances, you +unable to resolve it's own, fundamental, dependencies from the default Maven Central +JVM package repository. Under such circumstances, you will normally have access to some proxy, or other corporate repository which resolves maven artifacts. The strategy is simply to tell mill to use that instead. -The idea is to set an environment variable COURSIER_REPOSITORIES (see coursier docs). +To resolve this, you can set an environment variable COURSIER_REPOSITORIES (see coursier docs) +to point at your own server that mirrors the Maven Central artifacts. The below command should pass the environment variable to the `mill` command. ---- - COURSIER_REPOSITORIES=https://packages.corp.com/artifactory/maven/ mill resolve _ +COURSIER_REPOSITORIES=https://packages.corp.com/artifactory/maven/ mill resolve _ ---- If you are using bootstrap script, a more permanent solution could be to set the environment variable -at the top of the bootstrap script, or as a user environment variable etc. +at the top of the bootstrap script, or as a user environment variable. diff --git a/docs/modules/ROOT/pages/comparisons/why-mill.adoc b/docs/modules/ROOT/pages/comparisons/why-mill.adoc index b8341ec45cc..dd72327f618 100644 --- a/docs/modules/ROOT/pages/comparisons/why-mill.adoc +++ b/docs/modules/ROOT/pages/comparisons/why-mill.adoc @@ -215,13 +215,12 @@ the Gradle build in an IDE, the IDE can only explore the configuration logic (th `getCompilerArgs` method above) and is unable to explore the actual build logic (how `getCompilerArgs` _actually gets used in Gradle_) -In comparison, Mill's `.mill` files are all statically typed, and as a result IntelliJ is easily able to -pull up the documentation for `def javacOptions`, even though it doesn't have any special support -for Mill built into the IDE: +In comparison, not only are Mill's `.mill` files statically typed, allowing IDEs like IntelliJ +to pull up the documentation for `def javacOptions`: image::comparisons/IntellijMockitoMillJavacOptionsDocs.png[] -Apart from static typing, the way Mill builds are structured also helps the IDE: Mill +The way Mill builds are structured also helps the IDE: Mill code _actually performs your build_, rather than configuring some opaque build engine. While that sounds academic, one concrete consequence is that IntelliJ is able to take your `def javacOptions` override and @@ -364,7 +363,7 @@ Line Count: 18 Next, we'll look at a more realistic example, which includes usage of third-party libraries in the build. -### Using Libraries from Maven Central in Tasks +### Using Third-Party JVM Libraries in Tasks Earlier on we discussed possibly pre-rendering HTML pages in the build so they can be served at runtime. The use case for this are obvious: if a page never changes, rendering @@ -386,9 +385,14 @@ import $ivy.`org.thymeleaf:thymeleaf:3.1.1.RELEASE` import org.thymeleaf.TemplateEngine import org.thymeleaf.context.Context object foo extends JavaModule { + /** Total number of lines in module source files */ + def lineCount = Task { + allSourceFiles().map(f => os.read.lines(f.path).size).sum + } + def htmlSnippet = Task { val context = new Context() - context.setVariable("heading", "hello") + context.setVariable("heading", "Line Count is: " + lineCount()) new TemplateEngine().process( "

", context @@ -411,14 +415,14 @@ is inspectable from the Mill command line via `show`, and we wire it up into ```bash > mill show foo.htmlSnippet -"

hello

" +"

Line count is: 17

" > mill foo.compile compiling 1 Java source... ... > mill foo.run -generated snippet.txt resource:

hello

+generated snippet.txt resource:

Line count is: 17

``` Rendering HTML using the Thymeleaf templating engine is not rocket science, but what is @@ -434,9 +438,9 @@ interesting here is what we did _not_ need to do: implement the functionality we need. -Instead, we could simply import Thymeleaf directly from Maven Central and use it just -like we would use it in any Java application, with IDE support, typechecking, -and automatic parallelism and caching. +Instead, we could simply import Thymeleaf as a Java library directly from Maven Central +and use it just like we would use it in any Java application, with IDE support, +typechecking, and automatic parallelism and caching. ''' diff --git a/docs/modules/ROOT/pages/pythonlib/dependencies.adoc b/docs/modules/ROOT/pages/pythonlib/dependencies.adoc index 79e946ce869..edc0bcc1ede 100644 --- a/docs/modules/ROOT/pages/pythonlib/dependencies.adoc +++ b/docs/modules/ROOT/pages/pythonlib/dependencies.adoc @@ -4,7 +4,7 @@ include::partial$gtag-config.adoc[] This page goes into more detail about configuring third party dependencies -for `PythonModule`s. +for ``PythonModule``s. == Adding Dependencies diff --git a/example/cli/builtins/1-builtin-commands/build.mill b/example/cli/builtins/1-builtin-commands/build.mill index f5b8a2c72b1..d4054d15820 100644 --- a/example/cli/builtins/1-builtin-commands/build.mill +++ b/example/cli/builtins/1-builtin-commands/build.mill @@ -404,3 +404,26 @@ kotlinlib/web/1-hello-ktor // project isn't going to be everything that you need, at least it'll get most of the // tedious boilerplate set up, so you can hit the group running working on the things // that are unique to your particular project.. +// +// `init` can also be used to initialize a Mill build configuration based on +// an existing Maven or Gradle build. See the linked page for more details: +// +// * xref:migrating/maven.adoc[] +// * xref:migrating/gradle.adoc[] +// +// == selective.* +// +// Mill comes with builtin `selective.*` commands to work with Selective Test Execution. +// See the linked page for more details: +// +// * xref:large/selective-execution.adoc[] +// +// == shutdown +// +// `./mill shutdown` is used to shut down the background daemon that Mill uses to keep +// the build code performant. Without calling `shutdown`, the background daemon will +// automatically shut itself down after 30 minutes of inactivity. + +// == version +// +// `./mill version` prints the current Mill version diff --git a/example/fundamentals/modules/8-diy-java-modules/build.mill b/example/fundamentals/modules/8-diy-java-modules/build.mill index 678dd913b0f..a5dc0fd9b69 100644 --- a/example/fundamentals/modules/8-diy-java-modules/build.mill +++ b/example/fundamentals/modules/8-diy-java-modules/build.mill @@ -106,7 +106,6 @@ object qux extends DiyJavaModule { // label = "foo"; // // "foo.bar.classPath" -> "foo.compile" [constraint=false]; -// "foo.bar.classPath" -> "foo.classPath" // "foo.sources" -> "foo.compile" -> "foo.classPath" -> "foo.assembly" // "foo.mainClass" -> "foo.assembly" // } @@ -116,6 +115,7 @@ object qux extends DiyJavaModule { // label = "qux"; // // "qux.mainClass" -> "qux.assembly" +// "foo.bar.classPath" -> "foo.classPath" // "foo.classPath" -> "qux.compile" [constraint=false]; // "foo.classPath" -> "qux.classPath" // "qux.sources" -> "qux.compile" -> "qux.classPath" -> "qux.assembly" diff --git a/example/javalib/linting/3-palantirformat/build.mill b/example/javalib/linting/3-palantirformat/build.mill index fc795c11f9e..fb47fe1e82e 100644 --- a/example/javalib/linting/3-palantirformat/build.mill +++ b/example/javalib/linting/3-palantirformat/build.mill @@ -27,7 +27,7 @@ error: ...palantirformat aborted due to format error(s) (or invalid plugin setti > ./mill palantirformat --check # check should succeed now ...checking format in java sources ... */ -// You can also use Palantir Java Format globally on all `JavaModule`s in your build by running +// You can also use Palantir Java Format globally on all ``JavaModule``s in your build by running // `mill.javalib.palantirformat.PalantirFormatModule/`. /** Usage diff --git a/example/javalib/module/8-annotation-processors/build.mill b/example/javalib/module/8-annotation-processors/build.mill index dee830273a4..0147992fede 100644 --- a/example/javalib/module/8-annotation-processors/build.mill +++ b/example/javalib/module/8-annotation-processors/build.mill @@ -50,7 +50,7 @@ object bar extends JavaModule { /** Usage - > ./mill bar.test +> ./mill bar.test Test bar.HelloWorldTest.testSimple started Test bar.HelloWorldTest.testSimple finished... ... @@ -58,4 +58,4 @@ Test bar.HelloWorldTest.testSimple finished... */ // Many Java frameworks and libraries such as xref:javalib/web-examples#_micronaut_hello_world_app[Micronaut] -// or ErrorProne use annotation processors, and can be set up in this way. \ No newline at end of file +// or ErrorProne use annotation processors, and can be set up in this way. diff --git a/example/javalib/publishing/5-jlink/build.mill b/example/javalib/publishing/5-jlink/build.mill index 6aae51422cc..1b3e616bed3 100644 --- a/example/javalib/publishing/5-jlink/build.mill +++ b/example/javalib/publishing/5-jlink/build.mill @@ -1,7 +1,6 @@ // This example illustrates how to use Mill to generate a runtime image using the `jlink` tool. // Starting with JDK 9, `jlink` bundles Java app code with a stripped-down version of the JVM. -//// SNIPPET:BUILD package build import mill._, javalib._ import mill.javalib.Assembly._ @@ -12,22 +11,21 @@ object foo extends JavaModule with JlinkModule { def jlinkModuleVersion: T[Option[String]] = T { Option("1.0") } def jlinkCompressLevel: T[String] = T { "2" } } -//// SNIPPET:END - +// // Most of the work is done by the `trait JlinkModule` in two steps: - -// 1.0. it uses the `jmod` tool to create a `jlink.jmod` file for the main Java module. +// +// * It uses the `jmod` tool to create a `jlink.jmod` file for the main Java module. // The main Java module is typically the module containing the `mainClass`. - +// // If your build file doesn't explicitly specify a `mainClass`, `JlinkModule` will infer it from `JavaModule`, which is its parent trait. // See xref:javalib/module-config.adoc#specifying-main-class[Specifying the Main Class] to learn more on how to influence the inference process. // You can explicitly specify a `mainClass` like so in your build file: +// +// ```scala +// def mainClass: T[Option[String]] = { Some("com.foo.app.Main") } +// ``` -//// SNIPPET:BUILD -// def mainClass: T[Option[String]] = { Option("com.foo.app.Main") } -//// SNIPPET:END - -// 2.0. it then uses the `jlink` tool, to link the previously created `jlink.jmod` with a runtime image. +// * It then uses the `jlink` tool, to link the previously created `jlink.jmod` with a runtime image. // With respect to the `jlinkCompressLevel` option, on recent builds of OpenJDK and its descendants, // `jlink` will accept [`0`, `1`, `2`] but it will issue a deprecation warning. @@ -37,11 +35,14 @@ object foo extends JavaModule with JlinkModule { // as valid values for compression, with `0` being "no compression" // and 2 being "ZIP compression". -/** Usage - // To use a specific JDK, first set your `JAVA_HOME` environment variable prior to running the build. +// ``` // export JAVA_HOME=/Users/mac/.sdkman/candidates/java/17.0.9-oracle/ +// ``` + +/** Usage + > mill foo.jlinkAppImage diff --git a/example/javalib/publishing/6-jpackage/build.mill b/example/javalib/publishing/6-jpackage/build.mill index ff88bb8bc8f..5713c176099 100644 --- a/example/javalib/publishing/6-jpackage/build.mill +++ b/example/javalib/publishing/6-jpackage/build.mill @@ -1,7 +1,6 @@ // This example illustrates how to use Mill to generate a native package/installer // using the `jpackage` tool. -//// SNIPPET:BUILD package build import mill._, javalib._ import mill.javalib.Assembly._ @@ -17,7 +16,6 @@ object foo extends JavaModule with JpackageModule { Rule.AppendPattern(".*\\.conf") ) } -//// SNIPPET:END // JPMS (Java Platform Module System) is a modern distribution format that was designed // to avoid several of the shortcomings of the ubiquitous JAR format, especially "JAR Hell". @@ -33,7 +31,6 @@ object foo extends JavaModule with JpackageModule { // The above build file expects the following project layout: // -//// SNIPPET:TREE // // ---- // build.mill @@ -45,57 +42,50 @@ object foo extends JavaModule with JpackageModule { // module-info.java // ---- // -//// SNIPPET:END - -// The build defines a `foo` module that uses the `trait JpackageModule`. - -// NOTE: The term `Module` is also used in Mill to refer to xref:fundamentals/modules.adoc[traits]. -// This is not to be confused with Java app code structured as modules according to the JPMS format. - -// The `JpackageModule` trait will infer most of the options needed to assemble a native -// package/installer, but you can still customize its output. In our example, we specified: - -// def jpackageType = "pkg" - -// This tells `jpackage` to generate a `.pkg`, which is the native installer format on macOS. -// Valid values on macOS are: `dmg`, `pkg` and `app-image`. - -// NOTE: `jpackage` doesn't not support cross-targeting. Cross-targeting in this -// context means the `jpackage` binary shipped with a macOS JDK -// cannot be used to produce a native installer for another OS like Windows or Linux. +// +// /** Usage -> mill foo.assembly - -> mill show foo.assembly -".../out/foo/assembly.dest/out.jar" - -> java -jar ./out/foo/assembly.dest/out.jar -INFO: Loaded application.conf from resources: Foo Application Conf -INFO: Hello World application started successfully - > mill foo.jpackageAppImage > mill show foo.jpackageAppImage ".../out/foo/jpackageAppImage.dest/image" */ +// +// NOTE: The term `Module` is also used in Mill to refer to xref:fundamentals/modules.adoc[Mill Modules]. +// This is not to be confused with Java app code structured as modules according to the JPMS format. +// +// The `JpackageModule` trait will infer most of the options needed to assemble a native +// package/installer, but you can still customize its output. In our example, we specified: +// +// ```scala +// def jpackageType = "pkg" +//``` +// +// This tells `jpackage` to generate a `.pkg`, which is the native installer format on macOS. +// Valid values on macOS are: `dmg`, `pkg` and `app-image`. +// +// NOTE: `jpackage` doesn't support cross-build to a different OS/CPU combination than +// the one you the build is running on. For example, the `jpackage` binary shipped with a macOS JDK +// cannot be used to produce a native installer for another OS like Windows or Linux. +// // On macOS, `jpackageType` accepts 3 values: "dmg" or "pkg" or "app-image" (default). - -// Setting `def jpackageType = "dmg"` will produce: +// +// * Setting `def jpackageType = "dmg"` will produce: // ---- // ls -l ./out/foo/jpackageAppImage.dest/image // ... foo-1.0.dmg // ---- - -// Setting `def jpackageType = "pkg"` will produce: +// +// * Setting `def jpackageType = "pkg"` will produce: // ---- // ls -l ./out/foo/jpackageAppImage.dest/image // ... foo-1.0.pkg // ---- - -// Setting `def jpackageType = "app-image"` will produce: +// +// * Setting `def jpackageType = "app-image"` will produce: // ---- // ls -l ./out/foo/jpackageAppImage.dest/image // ... foo.app/ diff --git a/example/javalib/publishing/8-native-image-libs/build.mill b/example/javalib/publishing/8-native-image-libs/build.mill index 69f240fa5e9..67225a90630 100644 --- a/example/javalib/publishing/8-native-image-libs/build.mill +++ b/example/javalib/publishing/8-native-image-libs/build.mill @@ -27,6 +27,7 @@ object ZincWorkerGraalvm extends ZincWorkerModule { // libraries, in this case ArgParse4J and Thymeleaf. ArgParse4J does use some dynamic // resource loading and reflection, and so we need to pass the `-H:IncludeResourceBundles` // flag to `nativeImageOptions` in order to be compatible. We also demonstrate setting -// `nativeImageOptions`, in this case using `-Os` to optimize for the smallest binary size. +// using `-Os` to optimize for the smallest binary size, +// which is available in the `graalvm-community:23` JDK selected above. //// SNIPPET:END diff --git a/example/javalib/testing/1-test-suite/build.mill b/example/javalib/testing/1-test-suite/build.mill index e197f3955be..64dc81b51ea 100644 --- a/example/javalib/testing/1-test-suite/build.mill +++ b/example/javalib/testing/1-test-suite/build.mill @@ -11,6 +11,10 @@ object foo extends JavaModule { ) } } + +/** See Also: foo/src/foo/Foo.java */ +/** See Also: foo/test/src/foo/FooTests.java */ + // This build defines a single module with a test suite, configured to use // "JUnit" as the testing framework, along with Mockito. Test suites are themselves // ``JavaModule``s, nested within the enclosing module, diff --git a/example/javascriptlib/dependencies/3-downloading-unmanaged-packages/build.mill b/example/javascriptlib/dependencies/3-downloading-unmanaged-packages/build.mill index 2f4e1ab35d3..b03629486c3 100644 --- a/example/javascriptlib/dependencies/3-downloading-unmanaged-packages/build.mill +++ b/example/javascriptlib/dependencies/3-downloading-unmanaged-packages/build.mill @@ -26,7 +26,7 @@ Sorted with lodash: [a,b,e,k,l,m,o,p] // downloaded from the same URL will always contain the same contents. // NOTE: An unmanaged depedencies downloaded via `requests.get` is still unmanaged: even though you -// downloaded it from somewhere, `requests.get` does not know how to pull in third party +// downloaded it from somewhere, `requests.get` does not know how to pull in transitive // dependencies or de-duplicate different versions. // In case you **do** want mill to take care of managing dependencies of a package, diff --git a/example/kotlinlib/publishing/8-native-image-libs/build.mill b/example/kotlinlib/publishing/8-native-image-libs/build.mill index 80d9d619dc6..22b0928f91e 100644 --- a/example/kotlinlib/publishing/8-native-image-libs/build.mill +++ b/example/kotlinlib/publishing/8-native-image-libs/build.mill @@ -29,7 +29,8 @@ object ZincWorkerGraalvm extends ZincWorkerModule { // This example shows how to generate native images for projects using third-party // libraries, in this case Clikt and KotlinX-HTML. We also demonstrate setting // `nativeImageOptions`, in this case using `-Os` to optimize for the smallest binary size, -// and the `--initialize-at-build-time` flag seems to be necessary for this particular set +// which is available in the `graalvm-community:23` JDK selected above. The +// `--initialize-at-build-time` flag is also necessary for this particular set // of libraries and flags. //// SNIPPET:END diff --git a/example/kotlinlib/testing/1-test-suite/build.mill b/example/kotlinlib/testing/1-test-suite/build.mill index c2bc445eeef..fe89a36d483 100644 --- a/example/kotlinlib/testing/1-test-suite/build.mill +++ b/example/kotlinlib/testing/1-test-suite/build.mill @@ -20,6 +20,10 @@ object foo extends KotlinModule { def kotlincOptions = super.kotlincOptions() ++ Seq("-jvm-target", "11") } } + +/** See Also: foo/src/foo/Foo.kt */ +/** See Also: foo/test/src/foo/FooTests.kt */ + // This build defines a single module with a test suite, configured to use // "JUnit" + "Kotest" as the testing framework, along with Mockito. Test suites are themselves // ``KotlinModule``s, nested within the enclosing module, diff --git a/example/pythonlib/basic/1-simple/build.mill b/example/pythonlib/basic/1-simple/build.mill index 1053a4d2d32..4492515b6c6 100644 --- a/example/pythonlib/basic/1-simple/build.mill +++ b/example/pythonlib/basic/1-simple/build.mill @@ -18,7 +18,7 @@ object foo extends PythonModule { // or browse the full sources via the **browse** link. // Ensure you have a JVM installed; the `./mill` script manages all other dependencies. // All examples, from simple hello-world projects on this page to advanced -// link:[web build examples(Coming Soon...)] and link:[real-world projects(Coming Soon...)], +// xref:pythonlib/web-examples.adoc[web build examples] // are fully executable and tested in Mill’s CI workflows. // // The source code for this module lives in the `src/` folder. diff --git a/example/pythonlib/dependencies/4-downloading-unmanaged-wheels/build.mill b/example/pythonlib/dependencies/4-downloading-unmanaged-wheels/build.mill index 5eb12d24ad0..cf1c221bf89 100644 --- a/example/pythonlib/dependencies/4-downloading-unmanaged-wheels/build.mill +++ b/example/pythonlib/dependencies/4-downloading-unmanaged-wheels/build.mill @@ -28,7 +28,7 @@ Hello, world! // downloaded from the same URL will always contain the same contents. // // NOTE: An unmanaged wheel downloaded via `requests.get` is still unmanaged: even though you -// downloaded it from somewhere, `requests.get` does not know how to pull in third party +// downloaded it from somewhere, `requests.get` does not know how to pull in transitive // dependencies or de-duplicate different versions on the classpath. All the same caveats you need // to worry about when dealing with xref:#_unmanaged_wheels[unmanaged wheels] apply here as well. In // case you **do** want mill to take care of managing dependencies of a package which is not diff --git a/example/pythonlib/testing/1-test-suite/build.mill b/example/pythonlib/testing/1-test-suite/build.mill index a752c07d005..d440ffc1454 100644 --- a/example/pythonlib/testing/1-test-suite/build.mill +++ b/example/pythonlib/testing/1-test-suite/build.mill @@ -8,8 +8,11 @@ object foo extends PythonModule { } } +/** See Also: foo/src/foo.py */ +/** See Also: foo/test/src/test_foo.py */ + // This build defines a single module with a test suite, configured to use -// "Unittest" as the testing framework. Test suites are themselves ``PythonModule``s, +// `Unittest` as the testing framework. Test suites are themselves ``PythonModule``s, // nested within the enclosing module, and have all the normal tasks // available to run, but with an additional `.test` task // that runs the tests. You can also run the test suite directly, in which case diff --git a/example/scalalib/dependencies/1-ivy-deps/build.mill b/example/scalalib/dependencies/1-ivy-deps/build.mill index dbefb17dde7..29f1102e969 100644 --- a/example/scalalib/dependencies/1-ivy-deps/build.mill +++ b/example/scalalib/dependencies/1-ivy-deps/build.mill @@ -33,7 +33,7 @@ object `package` extends RootModule with ScalaModule { // //// SNIPPET:END // -// To select the test-jars from a dependency use the following syntax: +// To select the test-jars from a dependency use the `;classifier=tests` syntax, e.g.: // // * `ivy"org.apache.spark::spark-sql:2.4.0;classifier=tests` // diff --git a/example/scalalib/dependencies/4-downloading-unmanaged-jars/build.mill b/example/scalalib/dependencies/4-downloading-unmanaged-jars/build.mill index 3989935a3bf..f129049b484 100644 --- a/example/scalalib/dependencies/4-downloading-unmanaged-jars/build.mill +++ b/example/scalalib/dependencies/4-downloading-unmanaged-jars/build.mill @@ -39,6 +39,6 @@ I weigh twice as much as you // // NOTE: An unmanaged jar downloaded via `requests.get` is still unmanaged: even // though you downloaded it from somewhere, it `requests.get` does not know how to -// pull in third party dependencies or de-duplicate different versions on the classpath +// pull in transitive dependencies or de-duplicate different versions on the classpath // All the same caveats you need to worry about when dealing with xref:#_unmanaged_jars[unmanaged jars] // apply here as well. diff --git a/example/scalalib/dependencies/5-repository-config/build.mill b/example/scalalib/dependencies/5-repository-config/build.mill index a2f2595a2f0..fdabf9d6694 100644 --- a/example/scalalib/dependencies/5-repository-config/build.mill +++ b/example/scalalib/dependencies/5-repository-config/build.mill @@ -39,7 +39,7 @@ object foo extends ScalaModule { // central.to=http://example.com:8080/nexus/content/groups/public // ---- // -// Note theses default config file locatations: +// The default location of this config file on each OS is as follows: // // * Linux: `~/.config/coursier/mirror.properties` // * MacOS: `~/Library/Preferences/Coursier/mirror.properties` diff --git a/example/scalalib/module/11-main-class/build.mill b/example/scalalib/module/11-main-class/build.mill index 591accab670..668fb97fa2d 100644 --- a/example/scalalib/module/11-main-class/build.mill +++ b/example/scalalib/module/11-main-class/build.mill @@ -21,4 +21,4 @@ Hello Qux */ // `def mainClass` also adds the -// main class to your `foo.jar` and `foo.assembly` jars. \ No newline at end of file +// main class to your `foo.jar` and `foo.assembly` jars. diff --git a/example/scalalib/publishing/1-assembly-config/build.mill b/example/scalalib/publishing/1-assembly-config/build.mill index 0c52b109e19..63efdc71371 100644 --- a/example/scalalib/publishing/1-assembly-config/build.mill +++ b/example/scalalib/publishing/1-assembly-config/build.mill @@ -24,7 +24,7 @@ object bar extends ScalaModule { } //// SNIPPET:END -// When you make a runnable jar of your project with `assembly` command, +// When you make a runnable jar of your project with the `.assembly` task, // you may want to exclude some files from a final jar (like signature files, // and manifest files from library jars), and merge duplicated files (for // instance `reference.conf` files from library dependencies). diff --git a/example/scalalib/publishing/7-native-image/build.mill b/example/scalalib/publishing/7-native-image/build.mill index f09cca70e1d..755afc4f09b 100644 --- a/example/scalalib/publishing/7-native-image/build.mill +++ b/example/scalalib/publishing/7-native-image/build.mill @@ -18,8 +18,8 @@ object ZincWorkerGraalvm extends ZincWorkerModule { //// SNIPPET:END // // This example uses `NativeImageModule` to generate a native executable using https://www.graalvm.org/[Graal VM]. -// NOTE: For build portability, it is recommended to use a custom JDK via a custom `ZincWorkerModule` overriding -// `def jvmId`. +// We recommend you xref:fundamentals/configuring-jvm-versions.adoc[configure a specific JDK version] +// via a custom `ZincWorkerModule` overriding `def jvmId` (shown above), as not every JVM can build Graal native images. /** Usage diff --git a/example/scalalib/publishing/8-native-image-libs/build.mill b/example/scalalib/publishing/8-native-image-libs/build.mill index c4a14eacd8f..7c50c972374 100644 --- a/example/scalalib/publishing/8-native-image-libs/build.mill +++ b/example/scalalib/publishing/8-native-image-libs/build.mill @@ -22,14 +22,11 @@ object ZincWorkerGraalvm extends ZincWorkerModule { // This example shows how to generate native images for projects using third-party // libraries, in this case Scalatags and Mainargs. We also demonstrate setting -//// `nativeImageOptions`, in this case using `-Os` to optimize for the smallest binary size. +// using `-Os` to optimize for the smallest binary size +// which is available in the `graalvm-community:23` JDK selected above //// SNIPPET:END -// You can see the Graal documentation to see what flags are available: -// -// * https://www.graalvm.org/21.3/reference-manual/native-image/Options/ - /** Usage > ./mill show foo.nativeImage @@ -39,7 +36,11 @@ object ZincWorkerGraalvm extends ZincWorkerModule { */ -// You can also access the `native-image` compiler directly via `show foo.nativeImageTool` +// You can see the Graal documentation to see what flags are available: +// +// * https://www.graalvm.org/21.3/reference-manual/native-image/Options/ +// +// Or access the `native-image` compiler directly via `show foo.nativeImageTool` // if you want to experiment it or view its `--help` text to see what you need to pass to // `nativeImageOptions`: diff --git a/example/scalalib/testing/1-test-suite/build.mill b/example/scalalib/testing/1-test-suite/build.mill index 2b7dcface4b..9b1bf4cb3a9 100644 --- a/example/scalalib/testing/1-test-suite/build.mill +++ b/example/scalalib/testing/1-test-suite/build.mill @@ -10,6 +10,9 @@ object foo extends ScalaModule { } } +/** See Also: foo/src/Foo.scala */ +/** See Also: foo/test/src/FooTests.scala */ + // This build defines a single module with a test suite, configured to use // "uTest" as the testing framework. Test suites are themselves ``ScalaModule``s, // nested within the enclosing module, @@ -64,6 +67,7 @@ object bar extends ScalaModule { def ivyDeps = Agg(ivy"com.lihaoyi::utest:0.8.5") } } + //// SNIPPET:END /** Usage @@ -91,29 +95,29 @@ object bar extends ScalaModule { /** Usage > mill foo.test */ -// * `foo.test`: runs tests in a subprocess in an empty `sandbox/` folder. This is short -// for `foo.test.test`, as `test` is the default task for ``TestModule``s. +// `foo.test`: runs tests in a subprocess in an empty `sandbox/` folder. This is short +// for `foo.test.test`, as `test` is the default task for ``TestModule``s. /** Usage > mill foo.test.testCached */ -// * `foo.test.testCached`: runs the tests in an empty `sandbox/` folder and caches the results -// if successful. This can be handy if you are you working on some upstream modules and only -// want to run downstream tests which are affected: using `testCached`, downstream tests which -// are not affected will be cached after the first run and not re-run unless you change some -// file upstream of them. +// `foo.test.testCached`: runs the tests in an empty `sandbox/` folder and caches the results +// if successful. This can be handy if you are you working on some upstream modules and only +// want to run downstream tests which are affected: using `testCached`, downstream tests which +// are not affected will be cached after the first run and not re-run unless you change some +// file upstream of them. // /** Usage > mill foo.test.testLocal */ -// * `foo.test.testLocal`: runs tests in an isolated classloader as part of the main Mill process. -// This can be faster than `.test`, but is less flexible (e.g. you cannot pass `forkEnv`) -// and more prone to interference (`testLocal` runs do not run in xref:depth/sandboxing.adoc[sandbox folders]) +// `foo.test.testLocal`: runs tests in an isolated classloader as part of the main Mill process. +// This can be faster than `.test`, but is less flexible (e.g. you cannot pass `forkEnv`) +// and more prone to interference (`testLocal` runs do not run in xref:depth/sandboxing.adoc[sandbox folders]) // // It is common to run tests with xref:cli/flags.adoc#_watch_w[-w/--watch] -// enabled, so that once you save a file to disk the selected tests get re-run. +// enabled, so that once you edit a file on disk the selected tests get re-run. // // NOTE: Mill runs tests with the working directory set to an empty // xref:depth/sandboxing.adoc[sandbox/ folder] by default. diff --git a/example/scalalib/testing/2-test-deps/build.mill b/example/scalalib/testing/2-test-deps/build.mill index 31462ec5f42..8a55bc238f4 100644 --- a/example/scalalib/testing/2-test-deps/build.mill +++ b/example/scalalib/testing/2-test-deps/build.mill @@ -4,7 +4,7 @@ // -- // // You might be used to test-scoped dependencies from other build tools like -// Maven, Gradle or sbt. As test modules in Mill are just regular modules, +// Maven, Gradle or SBT. As test modules in Mill are just regular modules, // there is no special need for a dedicated test-scope. You can use `ivyDeps` // and `runIvyDeps` to declare dependencies in test modules, and test modules // can use their `moduleDeps` to also depend on each other