Skip to content

Commit c04ca3d

Browse files
committed
Merge branch 'main' into tr-run-exclusive
2 parents 51e4fd1 + b181fa4 commit c04ca3d

File tree

26 files changed

+626
-130
lines changed

26 files changed

+626
-130
lines changed

changelog.adoc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ _2025-05-10_
489489

490490
* fix: Use root qualifier in Discover macro ({link-pr}/5055[#5055])
491491
* Fix selective execution when multiple changes are made to one module under `--watch` ({link-pr}/5032[#5032])
492-
* Add ability to define `package` `ExternalModule`s that can be calle via just `pkg.path/` rather than `pkg.path.ObjectName/` ({link-pr}/4920[#4920])
492+
* Add ability to define `package` ``ExternalModule``s that can be calle via just `pkg.path/` rather than `pkg.path.ObjectName/` ({link-pr}/4920[#4920])
493493
* Backport `javascriptlib` and `pythonlib` improvements from `main` branch ({link-pr}/4893[#4893])
494494
* Fix wildcard and type selector query bugs ({link-pr}/4862[#4862])
495495
* Lots of Mill `main` branch compatibility changes, adding the new name and deprecating the old one
@@ -1418,7 +1418,7 @@ __New features__
14181418
__Fixes and Improvements__
14191419

14201420
* Better detect Windows Subsystem for Linux environments {link-pr}/2901[#2901]
1421-
* Avoid evaluating `Task.Input`s twice {link-pr}/2952[#2952]
1421+
* Avoid evaluating ``Task.Input``s twice {link-pr}/2952[#2952]
14221422
* Deduplicate (anonymous) tasks in results {link-pr}/2959[#2959]
14231423
* Synchronize `evaluateGroupCached` to avoid concurrent access to cache {link-pr}/2980[#2980]
14241424
* Properly sanitize Windows reserved names and symbols in evaluator paths {link-pr}/2964[#2964], {link-pr}/2965[#2965]
@@ -2450,7 +2450,7 @@ The API is suspected to change before a 0.10.0 releae.*
24502450

24512451
_Changes since {prev-version}:_
24522452

2453-
* `ScalaModule with PublishModule`: the `scala-library` artifact is now always part of the dependencies in published `pom.xml`s and `ivy.xml`s
2453+
* `ScalaModule with PublishModule`: the `scala-library` artifact is now always part of the dependencies in published ``pom.xml``s and `ivy.xml`s
24542454
* New `JavaModule.mandatoryMvnDeps` target to provide essential dependencies like scala-library without forcing the user to call `super.mvnDeps`
24552455
* `ScalaJSModule.scalaLibraryMvnDeps` no longer contains the scala-js-library, but only the scala-library; if you need that, use `ScalaJSModule.mandatoryMvnDeps` instead.
24562456
* `import $ivy` support `$MILL_BIN_PLATFORM` variable and a new sort notations for external plugins
@@ -3280,7 +3280,7 @@ _2018-03-04_
32803280

32813281
* Speed up Mill client initialization by another 50-100ms
32823282

3283-
* Speed up incremental `assembly`s in the common case where upstream dependencies do not change.
3283+
* Speed up incremental ``assembly``s in the common case where upstream dependencies do not change.
32843284

32853285
* Make `ScalaJSModule#run` work with main-method discovery
32863286

dist/package.mill

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -223,30 +223,35 @@ object `package` extends MillJavaModule with DistModule {
223223
prepareBootstrapLauncher(millBootstrapBat().path, Task.dest, build.millVersion(), "mill.bat")
224224
}
225225

226-
def examplePathsWithArtifactName0: Task[Seq[PathRef]] = Task.Input {
227-
for (exampleMod <- build.example.exampleModules) yield PathRef(exampleMod.moduleDir)
226+
def examplePaths: Task[Seq[os.Path]] = Task.Input {
227+
build.example.exampleModules.map(_.moduleDir)
228228
}
229229

230-
def examplePathsWithArtifactName = Task {
231-
for (pr <- examplePathsWithArtifactName0()) yield {
232-
val example = pr.path.subRelativeTo(BuildCtx.workspaceRoot)
230+
def examplePathRefs: Task[Seq[PathRef]] = Task.Sources(
231+
build.example.exampleModules.map(_.moduleDir)*
232+
)
233+
234+
def exampleArtifactNames = Task {
235+
for (path <- examplePaths()) yield {
236+
val example = path.subRelativeTo(BuildCtx.workspaceRoot)
233237
val artifactName = example.segments.mkString("-")
234-
(pr, s"${build.dist.artifactFileNamePrefix()}-$artifactName")
238+
(path, s"${build.dist.artifactFileNamePrefix()}-$artifactName")
235239
}
236240
}
237241

238242
def exampleZips: T[Seq[PathRef]] = Task {
239-
examplePathsWithArtifactName().map { case (examplePath, exampleStr) =>
240-
os.copy(examplePath.path, Task.dest / exampleStr, createFolders = true)
241-
val ignoreErrorsOnCI = Task.dest / exampleStr / "ignoreErrorsOnCI"
242-
if (os.exists(ignoreErrorsOnCI)) os.remove(ignoreErrorsOnCI)
243-
val buildMill = Task.dest / exampleStr / "build.mill"
244-
os.write.over(buildMill, s"//| mill-version: ${build.millVersion()}\n" + os.read(buildMill))
245-
os.copy(bootstrapLauncher().path, Task.dest / exampleStr / "mill")
246-
os.copy(bootstrapLauncherBat().path, Task.dest / exampleStr / "mill.bat")
247-
val zip = Task.dest / s"$exampleStr.zip"
248-
os.proc("zip", "-r", zip, exampleStr).call(cwd = Task.dest)
249-
PathRef(zip)
243+
examplePathRefs().zip(exampleArtifactNames()).map {
244+
case (pr, (examplePath, exampleStr)) =>
245+
os.copy(pr.path, Task.dest / exampleStr, createFolders = true)
246+
val ignoreErrorsOnCI = Task.dest / exampleStr / "ignoreErrorsOnCI"
247+
if (os.exists(ignoreErrorsOnCI)) os.remove(ignoreErrorsOnCI)
248+
val buildMill = Task.dest / exampleStr / "build.mill"
249+
os.write.over(buildMill, s"//| mill-version: ${build.millVersion()}\n" + os.read(buildMill))
250+
os.copy(bootstrapLauncher().path, Task.dest / exampleStr / "mill")
251+
os.copy(bootstrapLauncherBat().path, Task.dest / exampleStr / "mill.bat")
252+
val zip = Task.dest / s"$exampleStr.zip"
253+
os.proc("zip", "-r", zip, exampleStr).call(cwd = Task.dest)
254+
PathRef(zip)
250255
}
251256
}
252257

example/depth/sandbox/1-task/build.mill

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
1-
// In order to help manage your build, Mill performs some rudimentary filesystem
2-
// sandboxing to keep different tasks and modules from interfering with each other.
3-
// This tries to ensure your tasks only read and write from their designated `.dest/`
4-
// folders, which are unique to each task and thus guaranteed not to collide with
5-
// the filesystem operations of other tasks that may be occurring in parallel.
6-
//
7-
//
81
// === `Task.dest`
92
// The standard way of working with a task's `.dest/` folder is through the `Task.dest`
103
// property. This is available within any task, and gives you access to the
@@ -24,11 +17,14 @@ object foo extends Module {
2417
.../out/foo/tDestTask.dest
2518
*/
2619

20+
// If you really need to reference paths outside of the `Task.dest`, you can do
21+
// so via `BuildCtx.workspaceRoot`.
22+
2723
// === Filesystem Read/Write Checks
2824
//
2925
// Mill enforces limits on what you can read and write while a task is executing.
3026
// In general, a task may only write to its own `Task.dest` folder, and may only
31-
// read from the `PathRef`s provided to it from upstream tasks
27+
// read from the ``PathRef``s provided to it from upstream tasks
3228

3329
def bannedWriteTask = Task {
3430
os.write(BuildCtx.workspaceRoot / "banned-path", "hello")
@@ -63,9 +59,9 @@ error: ...Reading from out/foo/tDestTask.json not allowed during execution of `b
6359

6460
val listed = BuildCtx.watchValue(os.list(BuildCtx.workspaceRoot).map(_.last))
6561

66-
// === Disabling Task Sandboxing
62+
// === Bypassing Task Sandboxing
6763
//
68-
// You can disable Mill's filesystem read/write limitations via
64+
// You can bypass Mill's filesystem read/write limitations via
6965
// `BuildCtx.withFilesystemCheckerDisabled`. Note that this bypasses the
7066
// best-practices that Mill tries to enforce on your tasks and may result in strange
7167
// bugs around caching, parallelism, and invalidation, so you shouldn't do this unless

example/depth/sandbox/2-test/build.mill

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ object bar extends MyModule
6363
// one another, which helps keep tests stable and deterministic even when run in
6464
// parallel
6565
//
66-
// === Escaping the Test Sandbox
66+
// === Bypassing the Test Sandbox
6767

6868
// Within a test, you can use the `MILL_WORKSPACE_ROOT` environment variable
6969
// to access the workspace root directory:
@@ -89,9 +89,7 @@ object qux extends JavaModule {
8989
*/
9090

9191
//
92-
// === Disabling Test Sandboxing
93-
//
94-
// Test sandboxing can be disabled by setting `def testSandboxWorkingDir = false`
92+
// Test sandboxing can also be disabled by setting `def testSandboxWorkingDir = false`
9593
// on your test module, which makes your unit tests run in the root of your
9694
// project workspace, with full access to the project files on disk.
9795
//

example/extending/jvmcode/1-subprocess/build.mill

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//
55
// * `defaultResolver().classpath` to resolve the dependencies from Maven Central,
66
// converting `org:name:version` coordinates (and their transitive dependencies) to
7-
// `PathRef`s referring to files on disk
7+
// ``PathRef``s referring to files on disk
88
//
99
// * `Jvm.runSubprocess`, which runs the given classpath files in a subprocess, starting
1010
// from specified `mainClass`
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// `PmdModule` Performs checks on Java source files using https://pmd.github.io/[PMD] and generates reports from these checks.
2+
//
3+
// PMD is a source code analyzer for Java that finds common programming flaws like unused variables,
4+
// empty catch blocks, unnecessary object creation, and more.
5+
//
6+
// To customize this plugin in a Java module:
7+
//
8+
// 1. Extend JavaModule with PmdModule.
9+
// 2. Define a PMD ruleset file(s) with `pmdRulesets` (default is `pmd-rules.xml` in root).
10+
// 3. Define the PMD version with `pmdVersion`.
11+
12+
package build
13+
14+
import mill._, javalib._
15+
import mill.javalib.pmd.PmdModule
16+
17+
object `package` extends JavaModule, PmdModule {
18+
def pmdVersion = "7.15.0"
19+
}
20+
21+
// Here's an example of a simple PMD ruleset file and a single Java source file.
22+
23+
/** See Also: pmd-ruleset.xml */
24+
/** See Also: src/foo/EmptyCatchBlock.java */
25+
26+
// CAUTION: Be careful, rule formats can differ between major PMD versions.
27+
28+
// You can either run the `pmd` command on selected modules
29+
// or use the external module `mill.javalib.pmd/`.
30+
31+
/** Usage
32+
33+
> ./mill pmd -s true -v false # <1>
34+
Running PMD ...
35+
Writing PMD output to .../out/pmd.dest/pmd-output.text ...
36+
...src/foo/EmptyCatchBlock.java:7: EmptyCatchBlock: Avoid empty catch blocks...
37+
PMD found 1 violation(s)
38+
39+
> ./mill mill.javalib.pmd/ # <2>
40+
error: Running PMD ...
41+
error: Writing PMD output to .../out/mill/javalib/pmd/PmdModule/pmd.dest/pmd-output.text ...
42+
error: 1 tasks failed
43+
error: mill.javalib.pmd.PmdModule.pmd PMD found 1 violation(s)
44+
45+
*/
46+
// <1> `-s` shows the results on the console, `-v` does not fail the build
47+
// <2> Use the external `mill.javalib.pmd` module with default configuration
48+
//
49+
// The `pmd` command accepts several options to customize its behavior. Mill supports:
50+
//
51+
// * `--stdout` / `-s` : Enable output to stdout. False by default. (PMD will write output to a file regardless of this option).
52+
//
53+
// * `--format` / `-f` : Output format of the report (`text`, `xml`, `html`). Defaults to `text`.
54+
//
55+
// * `--fail-on-violation` / `-v` : Fail if violations are found (true by default).
56+
//
57+
// For a full list of PMD options, see the PMD documentation:
58+
// https://pmd.github.io/pmd/pmd_userdocs_cli_reference.html.
59+
//
60+
// Here's an example of producing HTML report:
61+
62+
/** Usage
63+
> ./mill pmd -f "html" -s true -v false
64+
Writing PMD output to .../out/pmd.dest/pmd-output.html ...
65+
...<html><head><title>PMD</title></head><body>...
66+
...<center><h3>PMD report</h3></center><center><h3>Problems found</h3></center><table align="center" cellspacing="0" cellpadding="3"><tr>...
67+
...<th>#</th><th>File</th><th>Line</th><th>Problem</th></tr>...
68+
...<tr bgcolor="lightgrey">...
69+
...<td align="center">1</td>...
70+
...<td width="*%">...src/foo/EmptyCatchBlock.java</td>...
71+
...<td align="center" width="5%">7</td>...
72+
...<td width="*"><a href="https://docs.pmd-code.org/pmd-doc-7.15.0/pmd_rules_java_errorprone.html#emptycatchblock">Avoid empty catch blocks</a></td>...
73+
...</tr>...
74+
...</table></body></html>...
75+
...PMD found 1 violation(s)...
76+
*/
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ruleset name="Example ruleset"
3+
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0
6+
https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
7+
<description>
8+
Example PMD ruleset for Mill integration (Updated for PMD 7.15.0)
9+
</description>
10+
<rule ref="category/java/errorprone.xml/EmptyCatchBlock"/>
11+
</ruleset>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package foo;
2+
3+
public class EmptyCatchBlock {
4+
public void bar() {
5+
try {
6+
// do something
7+
} catch (Exception e) {
8+
// violation
9+
}
10+
}
11+
}

libs/init/package.mill

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ object `package` extends MillPublishScalaModule {
1818

1919
def exampleList: T[PathRef] = Task {
2020
val data: Seq[(os.SubPath, String)] =
21-
build.dist.examplePathsWithArtifactName().map { case (pathRef, str) =>
21+
build.dist.examplePaths().zip(build.dist.exampleArtifactNames()).map { case (path, str) =>
2222
val downloadUrl =
2323
s"${build.millDownloadUrlCurrent()}/$str.zip"
24-
val subPath = pathRef.path.subRelativeTo(BuildCtx.workspaceRoot / "example")
24+
val subPath = path.subRelativeTo(BuildCtx.workspaceRoot / "example")
2525
(subPath, downloadUrl)
2626
}
2727

libs/jvmlib/package.mill

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ object `package` extends MillStableScalaModule {
103103
s"${dep.group}:${dep.id}:${dep.version}"
104104
},
105105
"The dependency containing the worker implementation to be loaded at runtime."
106-
)
106+
),
107+
BuildInfo.Value("pmdVersion", Deps.RuntimeDeps.pmdDist.version)
107108
)
108109
}
109110

0 commit comments

Comments
 (0)