Target Query Syntax
When interacting with Mill from the CLI, you often need to select targets or modules. In most places, where Mill accepts a target, it really accepts a target selector query, which is the name of a target in its simplest form, but it can also contain wildcards, type pattern and other special syntax, making it a powerful tool to select specific targets.
Selecting dedicated targets
When invoking Mill, the simplest way to run a target is to give it with a fully qualified names.
Examples:
> mill for.compile > mill for.run hello world > mill foo.testCached
Selecting multiple targets
If you want to select more than one target, you have multiple options:
You can also combine these techniques to properly select your targets
Enumerations
Enumeration are denoted by curly braces ({
, }
).
Inside the curly braces you can place two or more selector paths, separated with a comma (,
).
Examples:
-
{foo,bar}
simple enumerates two targets,foo
andbar
-
foo.{compile,run}
expands tofoo.compile
andfoo.run
-
{_,foo.bar}.baz
expands to_.baz
andfoo.bar.baz
Some Shells like mill "foo.{compile.run}" |
Wildcard selections
There are two wildcards, you can use as path segment.
-
_
The single underscore acts as a placeholder for a single segment. -
__
The double underscore acts as a placeholder for many segments. In particular, it can represent an empty segment.
With wildcards, you can get explicit control over the position of a target in the build tree.
E.g. the filter _._._.jar
will match all jar targets, that are on the third-level of the build tree.
Type filters for wildcard selections
Type filters are always combined with wildcard. They are used to limit the scope of the wildcard to only match path segments of the specified types. For module paths this means, the represented module needs to be an instance of the specified type.
A type filter always starts with a wildcard (_
, __
) followed by a colon (:
) and finally the type qualifier.
The type is matched by its name and optionally by its enclosing types and packages, separated by a .
sign.
Since this is also used to separate target path segments, a type selector segment containing a .
needs to be enclosed in parentheses.
A fully qualified type can be denoted with the _root_
package.
> mill resolve __:TestModule.jar > mill resolve "(__:scalalib.TestModule).jar" > mill resolve "(__:mill.scalalib.TestModule).jar" > mill resolve "(__:_root_.mill.scalalib.TestModule).jar"
If the type qualifier starts with a ^
or !
, it’s only matching types which are not instances of the specified type.
> mill resolve __:^TestModule.jar
You can also add more than one type filters to a wildcard.
> mill resolve "__:JavaModule:^ScalaModule:^TestModule.jar"
Type filter are currently only supported for module selections, but not for target selections. That means, you can’t filter based on the result type of a target. |
Start a new target selector with +
On the Mill CLI you can also start a complete new target selector with the +
sign.
There is a subtile difference between the expansion of enumerations, wildcards and wildcards with type filters in contrast to the start of a new selector with +
.
For all the former versions, Mill parses them into a complex but single target selector path and subsequent parameters are used for all resolved targets.
Whereas the +
start a completely new selector path to which you can also provide a different parameter list. This is important when using command targets which can accept their own parameters. The JavaModule.run
command is an example.
> mill foo.run hello (1) > mill {foo,bar}.run hello (2) > mill __:JavaModule:^TestModule.run hello (3) > mill foo.run hello + bar.run world (4)
1 | Runs foo.run with the parameter hello |
2 | Expands to foo.run and bar.run and runs both with the parameter hello . |
3 | Selects the run command of all Java modules, but not test moudles, and runs them with the parameter hello . |
4 | Runs fun.run with the parameter hello and bar.run with the parameter world . |