From 98643f7daafa253f03db14ebda6ea9a46edd7f74 Mon Sep 17 00:00:00 2001 From: Naftoli Gugenheim <98384+nafg@users.noreply.github.com> Date: Mon, 28 Nov 2022 22:42:45 -0500 Subject: [PATCH 1/2] docs: Split Intro_to_Mill.adoc into 4 pages --- docs/antora/modules/ROOT/nav.adoc | 6 + .../modules/ROOT/pages/Intro_to_Mill.adoc | 1176 ----------------- .../modules/ROOT/pages/Usage_Basics.adoc | 858 ++++++++++++ .../ROOT/pages/Usage_Installation.adoc | 261 ++++ .../modules/ROOT/pages/Usage_OutDir.adoc | 75 ++ 5 files changed, 1200 insertions(+), 1176 deletions(-) create mode 100644 docs/antora/modules/ROOT/pages/Usage_Basics.adoc create mode 100644 docs/antora/modules/ROOT/pages/Usage_Installation.adoc create mode 100644 docs/antora/modules/ROOT/pages/Usage_OutDir.adoc diff --git a/docs/antora/modules/ROOT/nav.adoc b/docs/antora/modules/ROOT/nav.adoc index 68dbd12e021..405a1966521 100644 --- a/docs/antora/modules/ROOT/nav.adoc +++ b/docs/antora/modules/ROOT/nav.adoc @@ -1,4 +1,10 @@ * xref:Intro_to_Mill.adoc[] + +* Usage +** xref:Usage_Installation.adoc[] +** xref:Usage_Basics.adoc[] +** xref:Usage_OutDir.adoc[] + * xref:Configuring_Mill.adoc[] * xref:Common_Project_Layouts.adoc[] * xref:Tasks.adoc[] diff --git a/docs/antora/modules/ROOT/pages/Intro_to_Mill.adoc b/docs/antora/modules/ROOT/pages/Intro_to_Mill.adoc index 5be90d99a51..82f4cc5b25b 100644 --- a/docs/antora/modules/ROOT/pages/Intro_to_Mill.adoc +++ b/docs/antora/modules/ROOT/pages/Intro_to_Mill.adoc @@ -18,1179 +18,3 @@ It can be xref:Extending_Mill.adoc[extended] to support any other language or pl If you are using Mill, you will find the following book by the Author useful in using Mill to the fullest: * https://handsonscala.com/ - -== Installation - -=== OS X - -Installation via https://github.com/Homebrew/homebrew-core/blob/master/Formula/mill.rb[homebrew]: - -[source,sh] ----- -brew install mill - ----- - -=== Arch Linux - -Arch Linux has a https://www.archlinux.org/packages/community/any/mill/[Community package for mill]: - -[source,bash] ----- -pacman -S mill - ----- - -=== FreeBSD - -Installation via http://man.freebsd.org/pkg/8[pkg(8)]: - -[source,sh] ----- -pkg install mill - ----- - -=== Gentoo Linux - -[source,sh] ----- -emerge dev-java/mill-bin - ----- - -=== Windows - -To get started, download Mill from -{mill-github-url}/releases/download/{mill-last-tag}/{mill-last-tag}-assembly[Github releases], and save it as `mill.bat`. - -If you're using https://scoop.sh[Scoop] you can install Mill via - -[source,bash] ----- -scoop install mill ----- - -Mill also works on "sh" environments on Windows (e.g., -https://www.msys2.org[MSYS2], -https://www.cygwin.com[Cygwin], -https://gitforwindows.org[Git-Bash], -https://docs.microsoft.com/en-us/windows/wsl[WSL]); to get started, follow the instructions in the <<_manual>> -section below. Note that: - -* In some environments (such as WSL), Mill might have to be run without a server (using `-i`, `--interactive` - , `--no-server`, or - `--repl`.) - -* On Cygwin, run the following after downloading mill: - -[source,bash] ----- -sed -i '0,/-cp "\$0"/{s/-cp "\$0"/-cp `cygpath -w "\$0"`/}; 0,/-cp "\$0"/{s/-cp "\$0"/-cp `cygpath -w "\$0"`/}' /usr/local/bin/mill ----- - -=== Docker - -You can download and run -a https://hub.docker.com/r/nightscape/scala-mill/["Docker image containing OpenJDK, Scala and Mill"] using - -[source,bash] ----- -docker pull nightscape/scala-mill -docker run -it nightscape/scala-mill ----- - -=== Manual - -To get started, download Mill and install it into your HOME ".local/bin" via the following -`curl`/`chmod` command: - -[source,bash,subs="verbatim,attributes"] ----- -sh -c "curl -L {mill-github-url}/releases/download/{mill-last-tag}/{mill-last-tag} > ~/.local/bin/mill && chmod +x ~/.local/bin/mill" ----- - -=== Bootstrap Scripts (Linux/OS-X Only) - -If you are using Mill in a codebase, you can commit the bootstrap launcher as a -`./mill` script in the project folder: - -[source,bash,subs="verbatim,attributes"] ----- -curl -L {mill-github-url}/releases/download/{mill-last-tag}/{mill-last-tag} > mill && chmod +x mill ----- - -Now, anyone who wants to work with the project can simply use the `./mill` -script directly: - -[source,bash] ----- -./mill version -./mill __.compile # double underscore ----- - -The `mill` command will automatically use the version specified by the bootstrap script, even if you installed it via -other means. The `./mill` file has a version number embedded within it, which you can update simply by editing the -script. Note this only works for versions 0.5.0 and above. - -Bootstrap scripts are also useful for running Mill in CI, ensuring that your Jenkins/Travis/etc. box has the correct -version of Mill present to build/compile/test your code. - -=== millw - -Instead of installing Mill directly, you can also use https://github.com/lefou/millw[lefou/millw] as drop-in -replacement for `mill`. It provides a small shell script and also a Windows batch file, that transparently downloads `mill` -and executes it on your behalf. It respects various ways to configure the preferred Mill version (`MILL_VERSION` env -var, `.mill-version` file, `--mill-version` option) and can also be used as a bootstrap script in your project. - -=== Coursier (unsupported) - -Installing mill via `coursier` or `cs` is currently not officially supported. There are various issues, especially with -interactive mode. - -== Updating Mill - -Once installed mill is able to use newer or different versions for each project automatically. You don't need to install -multiple versions of mill yourself. - -See section <<_overriding_mill_versions>> how to do it. - -== Getting Started - -The simplest Mill build for a Java project looks as follows: - -.`build.sc` -[source,scala] ----- -import mill._, scalalib._ - -object foo extends JavaModule {} ----- - -The simplest Mill build for a Scala project looks as follows: - -.`build.sc` -[source,scala,subs="attributes,verbatim"] ----- -import mill._, scalalib._ - -object foo extends ScalaModule { - def scalaVersion = "{example-scala-version}" -} ----- - -Both of these would build a project laid out as follows: - ----- -build.sc -foo/ - src/ - FileA.java - FileB.scala - resources/ - ... -out/ - foo/ - ... ----- - -You can download an example project with this layout here: - -* {mill-github-url}/releases/download/{mill-last-tag}/{mill-last-tag}-example-1.zip[Example 1] - -The source code for this module would live in the `foo/src/` folder, matching the name you assigned to the module. -Output for this module (compiled files, resolved dependency lists, …) would live in `out/foo/`. - -This can be run from the Bash shell via: - -[source,bash] ----- -$ mill foo.compile # compile sources into classfiles - -$ mill foo.run # run the main method, if any - -$ mill foo.runBackground # run the main method in the background - -$ mill foo.launcher # prepares a foo/launcher.dest/run you can run later - -$ mill foo.jar # bundle the classfiles into a jar - -$ mill foo.assembly # bundle classfiles and all dependencies into a jar - -$ mill -i foo.console # start a Scala console within your project (in interactive mode: "-i") - -$ mill -i foo.repl # start an Ammonite REPL within your project (in interactive mode: "-i") ----- - -You can run `+mill resolve __+` to see a full list of the different tasks that are available, `+mill resolve foo._+` to see -the tasks within `foo`, `mill inspect foo.compile` to inspect a task's doc-comment documentation or what it depends on, -or `mill show foo.scalaVersion` to show the output of any task. - -The most common *tasks* that Mill can run are cached *targets*, such as -`compile`, and un-cached *commands* such as `foo.run`. Targets do not re-evaluate unless one of their inputs changes, -whereas commands re-run every time. - -== Output - -Mill puts all its output in the top-level `out/` folder. The above commands would end up in: - -[source,text] ----- -out/ - foo/ - compile.dest - compile.log - compile.json - - run.dest - run.log - run.json - - runBackground.dest - runBackground.log - runBackground.json - - launcher.dest - launcher.log - launcher.json - - jar.dest - jar.log - jar.json - - assembly.dest - assembly.log - assembly.json ----- - -For each task there's a `foo.json` file containing the metadata returned by that task, and -two optional paths: a `foo.dest/` folder containing any files that the task generates and a `foo.log` file containing the the logs of running that task. For example, `out/foo/compile.dest/` contains the -compiled classfiles, while `out/foo/assembly.dest/` contains the self-contained assembly with the project's classfiles -jar-ed up with all its dependencies. - -Given a task `foo.bar`, all its output and results are inside its respective `out/foo/bar/` folder. - -== Multiple Modules - -=== Java Example - -.`build.sc` -[source,scala] ----- -import mill._, scalalib._ - -object foo extends JavaModule - -object bar extends JavaModule { - def moduleDeps = Seq(foo) -} ----- - -=== Scala Example - -.`build.sc` -[source,scala,subs="attributes,verbatim"] ----- -import mill._, scalalib._ - -object foo extends ScalaModule { - def scalaVersion = "{example-scala-version}" -} - -object bar extends ScalaModule { - def moduleDeps = Seq(foo) - - def scalaVersion = "{example-scala-version}" -} ----- - -You can define multiple modules the same way you define a single module, using -`def moduleDeps` to define the relationship between them. -The above builds expect the following project layout: - ----- -build.sc -foo/ - src/ - Main.scala - resources/ - ... -bar/ - src/ - Main2.scala - resources/ - ... -out/ - foo/ - ... - bar/ - ... ----- - -And can be built/run using: - -[source,bash] ----- -$ mill foo.compile -$ mill bar.compile - -$ mill foo.run -$ mill bar.run - -$ mill foo.jar -$ mill bar.jar - -$ mill foo.assembly -$ mill bar.assembly ----- - -Mill's evaluator will ensure that the modules are compiled in the right order, and recompiled as necessary when source -code in each module changes. - -Modules can also be nested: - -.`build.sc` -[source,scala,subs="attributes,verbatim"] ----- -import mill._, scalalib._ - -object foo extends ScalaModule { - def scalaVersion = "{example-scala-version}" - - object bar extends ScalaModule { - def moduleDeps = Seq(foo) - - def scalaVersion = "{example-scala-version}" - } -} ----- - -Which would result in a similarly nested project layout: - ----- -build.sc -foo/ - src/ - Main.scala - resources/ - ... - bar/ - src/ - Main2.scala - resources/ - ... -out/ - foo/ - ... - bar/ - ... ----- - -Where the nested modules can be run via: - -[source,bash] ----- -$ mill foo.compile -$ mill foo.bar.compile - -$ mill foo.run -$ mill foo.bar.run - -$ mill foo.jar -$ mill foo.bar.jar - -$ mill foo.assembly -$ mill foo.bar.assembly ----- - -== Watch and Re-evaluate - -You can use the `--watch` flag to make Mill watch a task's inputs, re-evaluating the task as necessary when the inputs -change: - -[source,bash] ----- -$ mill --watch foo.compile -$ mill --watch foo.run -$ mill -w foo.compile -$ mill -w foo.run ----- - -Mill's `--watch` flag watches both the files you are building using Mill, as well as Mill's own `build.sc` file and -anything it imports, so any changes to your `build.sc` will automatically get picked up. - -For long-running processes like web servers, you can use `runBackground` to make sure they recompile and restart when code changes, -forcefully terminating the previous process even though it may be still alive: - -[source,bash] ----- -$ mill -w foo.compile -$ mill -w foo.runBackground ----- - -== Parallel Task Execution (Experimental) - -By default, mill will evaluate all tasks in sequence. -But mill also supports processing tasks in parallel. -This feature is currently experimental and we encourage you to report any issues you find on our bug tracker. - -To enable parallel task execution, use the `--jobs` (`-j`) option followed by a number of maximal parallel threads. - -Example: Use up to 4 parallel threads to compile all modules: - -[source,bash] ----- -mill -j 4 __.compile ----- - -To use as many threads as your machine has (logical) processor cores use `--jobs 0`. -To disable parallel execution use `--jobs 1`. -This is currently the default. - -Please note that the maximal possible parallelism depends on your project. -Tasks that depend on each other can't be processed in parallel. - -== Command-line usage - -Mill is a command-line tool and supports various options. - -Run `mill --help` for a complete list of options - -.Output of `mill --help` ----- -Mill Build Tool -usage: mill [options] [[target [target-options]] [+ [target ...]]] - --no-default-predef Disable the default predef and run Ammonite with the minimal predef possible - -s --silent Make ivy logs go silent instead of printing though failures will still throw - exception - -w --watch Watch and re-run your scripts when they change - --bsp Run a BSP server against the passed scripts - -c --code Pass in code to be run immediately in the REPL - -h --home The home directory of the REPL; where it looks for config and caches - -p --predef Lets you load your predef from a custom location, rather than the "default - location in your Ammonite home - --color Enable or disable colored output; by default colors are enabled in both REPL - and scripts if the console is interactive, and disabled otherwise - --thin Hide parts of the core of Ammonite and some of its dependencies. By default, - the core of Ammonite and all of its dependencies can be seen by users from - the Ammonite session. This option mitigates that via class loader isolation. - --help Print this message - -h --home The home directory of the REPL; where it looks for config and caches - --repl Run Mill in interactive mode and start a build REPL. In this mode, no mill - server will be used. Must be the first argument. - --no-server Run Mill in interactive mode, suitable for opening REPLs and taking user - input. In this mode, no mill server will be used. Must be the first argument. - -i --interactive Run Mill in interactive mode, suitable for opening REPLs and taking user - input. In this mode, no mill server will be used. Must be the first argument. - -v --version Show mill version and exit. - -b --bell Ring the bell once if the run completes successfully, twice if it fails. - --disable-ticker Disable ticker log (e.g. short-lived prints of stages and progress bars) - -d --debug Show debug output on STDOUT - -k --keep-going Continue build, even after build failures - -D --define Define (or overwrite) a system property - -j --jobs Allow processing N targets in parallel. Use 1 to disable parallel and 0 to - use as much threads as available processors. - rest ... The name of the targets you want to build, followed by any parameters you - wish to pass to those targets. ----- - -All _options_ must be given before the first target. - -A _target_ is a fully qualified task or command optionally followed by target specific arguments. -You can use wildcards and brace-expansion to select multiple targets at once or to shorten the path to deeply nested targets. -If you provide optional target arguments and your wildcard or brace-expansion is resolved to multiple targets, the arguments will be applied to each of the targets. - -.Wildcards and brace-expansion -|=== -| Wildcard | Function -|`_` | matches a single segment of the target path -| `__` | matches arbitrary segments of the target path -| `{a,b}` | is equal to specifying two targets `a` and `b` -|=== - -You can use the `+` symbol to add another target with optional arguments. -If you need to feed a `+` as argument to your target, you can mask it by preceding it with a backslash (`\`). - -=== Examples - -`+mill foo._.compile+`:: Runs `compile` for all direct sub-modules of `foo` -`+mill foo.__.test+` :: Runs `test` for all sub-modules of `foo` -`+mill {foo,bar}.__.testCached+` :: Runs `testCached` for all sub-modules of `foo` and `bar` -`+mill __.compile + foo.__.test+` :: Runs all `compile` targets and all tests under `foo`. - -== Command-line Tools - -Mill comes with a few useful command-line utilities built into it: - -=== init - -[source,bash] ----- -$ mill -i init com-lihaoyi/mill-scala-hello.g8 -.... -A minimal Scala project. - -name [Scala Seed Project]: hello - -Template applied in ./hello ----- - -The `init` command generates a project based on a Giter8 template. -It prompts you to enter project name and creates a folder with that name. -You can use it to quickly generate a starter project. -There are lots of templates out there for many frameworks and tools! - - -=== resolve - -[source,bash] ----- -$ mill resolve _ -[1/1] resolve -clean -foo -inspect -par -path -plan -resolve -show -shutdown -version -visualize -visualizePlan - -$ mill resolve _.compile -[1/1] resolve -foo.compile - -$ mill resolve foo._ -[1/1] resolve -foo.allSourceFiles -foo.allSources -foo.ammoniteReplClasspath -foo.ammoniteVersion -foo.artifactId -foo.artifactName -... ----- - -`resolve` lists the tasks that match a particular query, without running them. -This is useful for "dry running" an `mill` command to see what would be run before you run them, or to explore what modules or tasks are available -from the command line using `+resolve _+`, `+resolve foo._+`, etc. - -[source,bash] ----- -mill resolve foo.{compile,run} -mill resolve "foo.{compile,run}" -mill resolve foo.compile foo.run -mill resolve _.compile # list the compile tasks for every top-level module -mill resolve __.compile # list the compile tasks for every module -mill resolve _ # list every top level module and task -mill resolve foo._ # list every task directly within the foo module -mill resolve __ # list every module and task recursively ----- - -=== inspect - -[source,bash] ----- -$ mill inspect foo.run -[1/1] inspect -foo.run(JavaModule.scala:442) - Runs this module's code in a subprocess and waits for it to finish - -Inputs: - foo.finalMainClass - foo.runClasspath - foo.forkArgs - foo.forkEnv - foo.forkWorkingDir ----- - -`inspect` is a more verbose version of <<_resolve>>. In addition to printing out the name of one-or-more tasks, -it also displays its source location and a list of input tasks. This is very useful for debugging and interactively -exploring the structure of your build from the command line. - -`inspect` also works with the same `+_+`/`+__+` wildcard/query syntaxes that -<<_resolve>> do: - -[source,bash] ----- -mill inspect foo.compile -mill inspect foo.{compile,run} -mill inspect "foo.{compile,run}" -mill inspect foo.compile foo.run -mill inspect _.compile -mill inspect __.compile -mill inspect _ -mill inspect foo._ -mill inspect __ ----- - -=== show - -[source,bash] ----- -$ mill show foo.scalaVersion -[1/1] show -"2.13.1" ----- - -By default, Mill does not print out the metadata from evaluating a task. Most people would not be interested in e.g. -viewing the metadata related to incremental compilation: they just want to compile their code! However, if you want to -inspect the build to debug problems, you can make Mill show you the metadata output for a task using the `show` command: - -`show` is not just for showing configuration values. -All tasks return values that can be shown with `show`. -E.g. `compile` returns the paths to the `classes` folder and `analysisFile` file produced by the compilation: - -[source,bash] ----- -$ mill show foo.compile -[1/1] show -[10/25] foo.resources -{ - "analysisFile": "/Users/lihaoyi/Dropbox/Github/test//out/foo/compile.dest/zinc", - "classes": "ref:07960649:/Users/lihaoyi/Dropbox/Github/test//out/foo/compile.dest/classes" -} ----- - -`show` is generally useful as a debugging tool, to see what is going on in your build: - -[source,bash] ----- -$ mill show foo.sources -[1/1] show -[1/1] foo.sources -[ - "ref:8befb7a8:/Users/lihaoyi/Dropbox/Github/test/foo/src" -] - -$ mill show foo.compileClasspath -[1/1] show -[2/11] foo.resources -[ - "ref:c984eca8:/Users/lihaoyi/Dropbox/Github/test/foo/resources", - ".../org/scala-lang/scala-library/2.13.1/scala-library-2.13.1.jar" -] ----- - -`show` is also useful for interacting with Mill from external tools, since the JSON it outputs is structured and easily -parsed and manipulated. - -When `show` is used with multiple targets, its output will slightly change to a JSON array, containing all the results of the given targets. - -[source,bash] ----- -$ mill show "foo.{sources,compileClasspath}" -[1/1] show -[2/11] foo.resources -[ - [ - "ref:8befb7a8:/Users/lihaoyi/Dropbox/Github/test/foo/src" - ], - [ - "ref:c984eca8:/Users/lihaoyi/Dropbox/Github/test/foo/resources", - ".../org/scala-lang/scala-library/2.13.1/scala-library-2.13.1.jar" - ] -] ----- - -=== showNamed - -Same as `show`, but the output will always be structured in a JSON dictionary, with the task names as key and the task results as JSON values. - -[source,bash] ----- -$ mill showNamed "foo.{sources,compileClasspath}" -[1/1] show -[2/11] foo.resources -{ - "foo.sources": - [ - "ref:8befb7a8:/Users/lihaoyi/Dropbox/Github/test/foo/src" - ], - "foo.compileClasspath": - [ - "ref:c984eca8:/Users/lihaoyi/Dropbox/Github/test/foo/resources", - ".../org/scala-lang/scala-library/2.13.1/scala-library-2.13.1.jar" - ] -} ----- - -=== path - -[source,bash] ----- -$ mill path foo.assembly foo.sources -[1/1] path -foo.sources -foo.allSources -foo.allSourceFiles -foo.compile -foo.localClasspath -foo.assembly ----- - -`mill path` prints out a dependency chain between the first task and the second. -It is very useful for exploring the build graph and trying to figure out how data gets from one task to another. -If there are multiple possible dependency chains, one of them is picked arbitrarily. - -=== plan - -[source,bash] ----- -$ mill plan foo.compileClasspath -[1/1] plan -foo.transitiveLocalClasspath -foo.resources -foo.unmanagedClasspath -foo.scalaVersion -foo.platformSuffix -foo.compileIvyDeps -foo.scalaOrganization -foo.scalaLibraryIvyDeps -foo.ivyDeps -foo.transitiveIvyDeps -foo.compileClasspath ----- - -`mill plan foo` shows which tasks would be evaluated, and in what order, if you ran `mill foo`, but without actually running them. -This is a useful tool for debugging your build: e.g. if you suspect a task `foo` is running things that it -shouldn't be running, a quick `mill plan` will list out all the upstream tasks that `foo` needs to run, and you can then -follow up with `mill path` on any individual upstream task to see exactly how `foo` depends on it. - -=== visualize - -[source,bash] ----- -$ mill show visualize foo._ -[1/1] show -[3/3] visualize -[ - ".../out/visualize.dest/out.txt", - ".../out/visualize.dest/out.dot", - ".../out/visualize.dest/out.json", - ".../out/visualize.dest/out.png", - ".../out/visualize.dest/out.svg" -] ----- - -`mill show visualize` takes a subset of the Mill build graph (e.g. `+core._+` is every task directly under the `core` -module) and draws out their relationships in `.svg` and `.png` form for you to inspect. It also generates `.txt`, `.dot` -and `.json` for easy processing by downstream tools. - -The above command generates the following diagram: - -image::VisualizeFoo.svg[VisualizeFoo.svg] - -=== visualizePlan - -[source,bash] ----- -$ mill show visualizePlan foo.compile -[1/1] show -[3/3] visualizePlan -[ - ".../out/visualizePlan.dest/out.txt", - ".../out/visualizePlan.dest/out.dot", - ".../out/visualizePlan.dest/out.json", - ".../out/visualizePlan.dest/out.png", - ".../out/visualizePlan.dest/out.svg" -] ----- - -`mill show visualizePlan` is similar to `mill show visualize` except that it shows a graph of the entire build plan, -including tasks not directly resolved by the query. Tasks directly resolved are shown with a solid border, and -dependencies are shown with a dotted border. - -The above command generates the following diagram: - -image::VisualizePlan.svg[VisualizePlan.svg] - -Another use case is to view the relationships between modules. For the following two modules: - -.`build.sc` -[source,scala] ----- -import mill._, scalalib._ - -object foo extends ScalaModule { - def scalaVersion = "2.13.1" -} - -object bar extends ScalaModule { - def moduleDeps = Seq(foo) - - def scalaVersion = "2.13.1" -} ----- - -`+mill show visualizePlan _.compile+` diagrams the relationships between the compile tasks of each module, which -illustrates which module depends on which other module's compilation output: - -image::VisualizeCompile.svg[VisualizeCompile.svg] - -=== clean - -[source,bash] ----- -$ mill clean ----- - -`clean` deletes all the cached outputs of previously executed tasks. It can apply to the entire project, entire modules, -or specific tasks. - -[source,bash] ----- -mill clean # clean all outputs -mill clean foo # clean all outputs for module 'foo' (including nested modules) -mill clean foo.compile # only clean outputs for task 'compile' in module 'foo' -mill clean foo.{compile,run} -mill clean "foo.{compile,run}" -mill clean foo.compile foo.run -mill clean _.compile -mill clean __.compile ----- - -=== Search for dependency updates - -[source,bash] ----- -$ mill mill.scalalib.Dependency/showUpdates ----- - -Mill can search for updated versions of your project's dependencies, if available from your project's configured -repositories. Note that it uses heuristics based on common versioning schemes, so it may not work as expected for -dependencies with particularly weird version numbers. - -Current limitations: - -* Only works for `JavaModule` modules (including ``ScalaModule``s, - ``CrossScalaModule``s, etc.) and Maven repositories. -* Always applies to all modules in the build. -* Doesn't apply to `$ivy` dependencies used in the build definition itself. - -[source,bash] ----- -mill mill.scalalib.Dependency/showUpdates -mill mill.scalalib.Dependency/showUpdates --allowPreRelease true # also show pre-release versions ----- - -== IDE Support - -To support various IDEs and Language Servers, Mill supports the https://build-server-protocol.github.io/[Build Server Protocol] in version {bsp-version} and has a <>. - -In addition to BSP, Mill also supports <> directly. - -=== Build Server Protocol (BSP) - -To install a BSP connection file `.bsp/mill-bsp.json`, run: - -[source,bash] ----- -mill mill.bsp.BSP/install ----- - -Working known clients of the BSP server are IntelliJ IDEA and Metals. - -You can fine control some BSP server options by specifying command options: - -|=== -| Option | Description -|`--jobs` `n` | Use `n` threads in parallel to run tasks. A value of `0` means use as much threads as the system has cpu cores. -|=== - -[source] - -[NOTE] --- -*Using Metals* - -When using Metals by default Bloop will be used as your build server unless you explicitly choose Mill. -When in a Mill workspace use the "Switch Build Server" command from Metals which will allow you to switch to using Mill as your build -server. -If no `.bsp/mill-bsp.json` file exists, Metals will automatically create it for you and then connect to Mill. - -Metals is relying on SemanticDB to enable many of its features. -Mill BSP now also supports to provide this SemanticDB data, when the BSP client (like Metals) requests it. - -As of writing this, Metals 0.11.8 is the latest available version, which is not able to detect the fact, that Mill _is_ already providing SemanticDB data. -As a consequence, it reports missing SemanticDB data, although some SemanticDB-based features are already working. -This may be fixed eventually in a future release of Metals. --- - -[CAUTION] --- -*Updating older setups* - -In the past, we provided SemanticDB support via `mill.scalalib.bsp.ScalaMetalsSupport` trait, which had to be mixed-in to your Scala modules. -This is no longer needed and deprecated. -You should remove these mix-ins. -`ScalaMetalsSupport` trait is now deprecated and will be removed in the future. --- - -=== Using Bloop (standalone BSP server) - -If you wish to use Bloop as your build server (it is the default metals BSP implementation) with metals / vscode, consider using the mill bloop plugin. - -xref:Plugin_Bloop.adoc[Bloop Plugin] - - -This is preferred to the instructions (currently) on the bloop website. - - -== IntelliJ Support - -To generate IntelliJ IDEA project files into `.idea/`, run: - -[source,bash] ----- -mill mill.scalalib.GenIdea/idea ----- - -== The Build REPL - -[source,scala] ----- -$ mill --repl -Loading... -@ foo -res0: foo.type = ammonite.predef.build#foo:4 -Commands: - .ideaJavaModuleFacets(ideaConfigVersion: Int)() - .ideaConfigFiles(ideaConfigVersion: Int)() - .ivyDepsTree(inverse: Boolean, withCompile: Boolean, withRuntime: Boolean)() - .runLocal(args: String*)() - .run(args: String*)() - .runBackground(args: String*)() - .runMainBackground(mainClass: String, args: String*)() - .runMainLocal(mainClass: String, args: String*)() - .runMain(mainClass: String, args: String*)() - .console()() - .repl(replOptions: String*)() -Targets: -... - -@ foo.compile -res1: mill.package.T[mill.scalalib.api.CompilationResult] = foo.compile(ScalaModule.scala:143) - Compiles the current module to generate compiled classfiles/bytecode - -Inputs: - foo.upstreamCompileOutput - foo.allSourceFiles - foo.compileClasspath -... - -@ foo.compile() -[25/25] foo.compile -res2: mill.scalalib.api.CompilationResult = CompilationResult( - /Users/lihaoyi/Dropbox/Github/test/out/foo/compile.dest/zinc, - PathRef(/Users/lihaoyi/Dropbox/Github/test/out/foo/compile.dest/classes, false, -61934706) -) ----- - -You can run `mill --repl` to open a build REPL; this is a Scala console with your `build.sc` loaded, which lets you run -tasks interactively. -The task-running syntax is slightly different from the command-line, but more in line with how you -would depend on tasks from within your build file. - -You can use this REPL to interactively explore your build to see what is available. - -== Deploying your code - -The two most common things to do once your code is complete is to make an assembly (e.g. for deployment/installation) or -publishing (e.g. to Maven Central). Mill comes with both capabilities built in. - -Mill comes with the built-in with the ability to make assemblies. Given a simple Mill build: - -.`build.sc` -[source,scala] ----- -import mill._, scalalib._ - -object foo extends ScalaModule { - def scalaVersion = "2.13.1" -} ----- - -You can make a self-contained assembly via: - -[source,bash] ----- -$ mill foo.assembly - -$ ls -lh out/foo/assembly.dest/out.jar --rw-r--r-- 1 lihaoyi staff 5.0M Feb 17 11:14 out/foo/assembly.dest/out.jar ----- - -You can then move the `out.jar` file anywhere you would like, and run it standalone using `java`: - -[source,bash] ----- -$ java -cp out/foo/assembly.dest/out.jar foo.Example -Hello World! ----- - -To publish to Maven Central, you need to make `foo` also extend Mill's -`PublishModule` trait: - -.`build.sc` -[source,scala] ----- -import mill._, scalalib._, publish._ - -object foo extends ScalaModule with PublishModule { - def scalaVersion = "2.13.1" - - def publishVersion = "0.0.1" - - def pomSettings = PomSettings( - description = "Hello", - organization = "com.lihaoyi", - url = "https://github.com/lihaoyi/example", - licenses = Seq(License.MIT), - versionControl = VersionControl.github("lihaoyi", "example"), - developers = Seq( - Developer("lihaoyi", "Li Haoyi", "https://github.com/lihaoyi") - ) - ) -} ----- - -You can change the name of the published artifact (artifactId in the Maven POM) -by overriding `artifactName` in the module you want to publish. - -You can download an example project with this layout here: - -* {mill-github-url}/releases/download/{mill-last-tag}/{mill-last-tag}-example-2.zip[Example 2] - -Which you can then publish using the `mill foo.publish` command, which takes your sonatype credentials ( -e.g. `lihaoyi:foobarbaz`) and GPG password as inputs: - -[source,bash] ----- -$ mill foo.publish -Missing arguments: (--sonatypeCreds: String, --release: Boolean) - -Arguments provided did not match expected signature: - -publish - --sonatypeCreds String (format: "username:password") - --signed Boolean (default true) - --gpgArgs Seq[String] (default Seq("--batch", "--yes", "-a", "-b")) - --readTimeout Int (default 60000) - --release Boolean (default true) - --connectTimeout Int (default 5000) - --awaitTimeout Int (default 120000) - --stagingRelease Boolean (default true) ----- - -You also need to specify `release` as `true` or `false`, depending on whether you just want to stage your module -on `oss.sonatype.org` or you want Mill to complete the release process to Maven Central. - -If you are publishing multiple artifacts, you can also use `mill mill.scalalib.PublishModule/publishAll` as described - -xref:Common_Project_Layouts.adoc#_publishing[here] - -== Structure of the `out/` folder - -The `out/` folder contains all the generated files & metadata for your build. It is structured with one folder -per `Target`/`Command`, that is run, e.g.: - -* `out/core/compile/` -* `out/main/test/compile/` -* `out/main/test/forkTest/` -* `out/scalalib/compile/` - -There are also top-level build-related files in the `out/` folder, prefixed as -`mill-*`. The most useful is `mill-profile.json`, which logs the tasks run and time taken for the last Mill command you -executed. This is very useful if you want to find out exactly what tasks are being run and Mill is being slow. - -Each task currently creates contains the following files: - -* `foo.dest/`: optional, a path for the `Task` to use either as a scratch space, or to place generated files that are returned - using `PathRef` references. A `Task` should only output files within its own given `dest/` folder (available as `T.dest`) to avoid - conflicting with another `Task`, but can name files within `dest/` arbitrarily. - -* `foo.log`: optional, the `stdout`/`stderr` of the `Task`. This is also streamed to the console during evaluation. - -* `foo.json`: the cache-key and JSON-serialized return-value of the - `Target`/`Command`. The return-value can also be retrieved via `mill show foo.compile`. Binary blobs are typically not - included in `foo.json`, and instead stored as separate binary files in `dest/` which are then referenced - by `foo.json` via `PathRef` references. - -The `out/` folder is intentionally kept simple and user-readable. If your build is not behaving as you would expect, -feel free to poke around the various -`foo.dest/` folders to see what files are being created, or the `foo.json` files to see what is being returned by a -particular task. You can also simply delete folders within `out/` if you want to force portions of your project to be -rebuilt, e.g. by deleting the `out/main/` or `out/main/test/compile/` folders. - -== Overriding Mill Versions - -Apart from downloading and installing new versions of Mill globally, there are a few ways of selecting/updating your Mill version: - -* Create a `.mill-version` file to specify the version of Mill you wish to use: -[source,bash] ----- -echo "0.5.0" > .mill-version ----- - -`.mill-version` takes precedence over the version of Mill specified in the -`./mill` script. - -* Pass in a `MILL_VERSION` environment variable, e.g. -[source,bash] ----- -MILL_VERSION=0.5.0-3-4faefb mill __.compile ----- - -or - -[source,bash] ----- -MILL_VERSION=0.5.0-3-4faefb ./mill __.compile ----- - -to override the Mill version manually. This takes precedence over the version specified in `./mill` or `.mill-version` - -Note that both of these overrides only work for versions 0.5.0 and above. - -=== Automatic Mill updates - -If your project is hosted on GitHub, GitLab, or Bitbucket, you can use https://github.com/scala-steward-org/scala-steward[Scala Steward] to automatically open a pull request to update your Mill version (in `.mill-version` file), whenever there is a newer version available. - -TIP: Scala Steward can also xref:Configuring_Mill.adoc#_keeping_up_to_date_with_scala_steward[scan your project dependencies] and keep them up-to-date. - -=== Development Releases - -In case you want to try out the latest features and improvements that are currently in the main branch, unstable versions of Mill -are -https://github.com/com-lihaoyi/mill/releases[available] as binaries named -`+#.#.#-n-hash+` linked to the latest tag. Installing the latest unstable release is recommended for bootstrapping mill. - -The easiest way to use a development release is by updating the <<_bootstrap_scripts_linuxos_x_only>>, -or -<<_overriding_mill_versions>> via an environment variable or `.mill-version` file. - - -== Running Mill with custom JVM options - -It's possible to pass JVM options to the Mill launcher. To do this you need to create a `.mill-jvm-opts` file in your -project's root. This file should contain JVM options, one per line. - -For example, if your build requires a lot of memory and bigger stack size, your `.mill-jvm-opts` could look like this: - ----- --Xss10m --Xmx10G ----- - -The file name for passing JVM options to the Mill launcher is configurable. If for some reason you don't want to -use `.mill-jvm-opts` file name, add `MILL_JVM_OPTS_PATH` environment variable with any other file name. - - ---- - -Come by our https://gitter.im/lihaoyi/mill[Gitter Channel] if you want to ask questions or say hi! diff --git a/docs/antora/modules/ROOT/pages/Usage_Basics.adoc b/docs/antora/modules/ROOT/pages/Usage_Basics.adoc new file mode 100644 index 00000000000..db316032350 --- /dev/null +++ b/docs/antora/modules/ROOT/pages/Usage_Basics.adoc @@ -0,0 +1,858 @@ += Basics + +== Getting Started + +The simplest Mill build for a Java project looks as follows: + +.`build.sc` +[source,scala] +---- +import mill._, scalalib._ + +object foo extends JavaModule {} +---- + +The simplest Mill build for a Scala project looks as follows: + +.`build.sc` +[source,scala,subs="attributes,verbatim"] +---- +import mill._, scalalib._ + +object foo extends ScalaModule { + def scalaVersion = "{example-scala-version}" +} +---- + +Both of these would build a project laid out as follows: + +---- +build.sc +foo/ + src/ + FileA.java + FileB.scala + resources/ + ... +out/ + foo/ + ... +---- + +You can download an example project with this layout here: + +* {mill-github-url}/releases/download/{mill-last-tag}/{mill-last-tag}-example-1.zip[Example 1] + +The source code for this module would live in the `foo/src/` folder, matching the name you assigned to the module. +Output for this module (compiled files, resolved dependency lists, …) would live in `out/foo/`. + +This can be run from the Bash shell via: + +[source,bash] +---- +$ mill foo.compile # compile sources into classfiles + +$ mill foo.run # run the main method, if any + +$ mill foo.runBackground # run the main method in the background + +$ mill foo.launcher # prepares a foo/launcher.dest/run you can run later + +$ mill foo.jar # bundle the classfiles into a jar + +$ mill foo.assembly # bundle classfiles and all dependencies into a jar + +$ mill -i foo.console # start a Scala console within your project (in interactive mode: "-i") + +$ mill -i foo.repl # start an Ammonite REPL within your project (in interactive mode: "-i") +---- + +You can run `+mill resolve __+` to see a full list of the different tasks that are available, `+mill resolve foo._+` to see +the tasks within `foo`, `mill inspect foo.compile` to inspect a task's doc-comment documentation or what it depends on, +or `mill show foo.scalaVersion` to show the output of any task. + +The most common *tasks* that Mill can run are cached *targets*, such as +`compile`, and un-cached *commands* such as `foo.run`. Targets do not re-evaluate unless one of their inputs changes, +whereas commands re-run every time. + + + +== Multi-module Projects + +=== Java Example + +.`build.sc` +[source,scala] +---- +import mill._, scalalib._ + +object foo extends JavaModule + +object bar extends JavaModule { + def moduleDeps = Seq(foo) +} +---- + +=== Scala Example + +.`build.sc` +[source,scala,subs="attributes,verbatim"] +---- +import mill._, scalalib._ + +object foo extends ScalaModule { + def scalaVersion = "{example-scala-version}" +} + +object bar extends ScalaModule { + def moduleDeps = Seq(foo) + + def scalaVersion = "{example-scala-version}" +} +---- + +You can define multiple modules the same way you define a single module, using +`def moduleDeps` to define the relationship between them. +The above builds expect the following project layout: + +---- +build.sc +foo/ + src/ + Main.scala + resources/ + ... +bar/ + src/ + Main2.scala + resources/ + ... +out/ + foo/ + ... + bar/ + ... +---- + +And can be built/run using: + +[source,bash] +---- +$ mill foo.compile +$ mill bar.compile + +$ mill foo.run +$ mill bar.run + +$ mill foo.jar +$ mill bar.jar + +$ mill foo.assembly +$ mill bar.assembly +---- + +Mill's evaluator will ensure that the modules are compiled in the right order, and recompiled as necessary when source +code in each module changes. + +Modules can also be nested: + +.`build.sc` +[source,scala,subs="attributes,verbatim"] +---- +import mill._, scalalib._ + +object foo extends ScalaModule { + def scalaVersion = "{example-scala-version}" + + object bar extends ScalaModule { + def moduleDeps = Seq(foo) + + def scalaVersion = "{example-scala-version}" + } +} +---- + +Which would result in a similarly nested project layout: + +---- +build.sc +foo/ + src/ + Main.scala + resources/ + ... + bar/ + src/ + Main2.scala + resources/ + ... +out/ + foo/ + ... + bar/ + ... +---- + +Where the nested modules can be run via: + +[source,bash] +---- +$ mill foo.compile +$ mill foo.bar.compile + +$ mill foo.run +$ mill foo.bar.run + +$ mill foo.jar +$ mill foo.bar.jar + +$ mill foo.assembly +$ mill foo.bar.assembly +---- + + +== Watch and Re-evaluate + +You can use the `--watch` flag to make Mill watch a task's inputs, re-evaluating the task as necessary when the inputs +change: + +[source,bash] +---- +$ mill --watch foo.compile +$ mill --watch foo.run +$ mill -w foo.compile +$ mill -w foo.run +---- + +Mill's `--watch` flag watches both the files you are building using Mill, as well as Mill's own `build.sc` file and +anything it imports, so any changes to your `build.sc` will automatically get picked up. + +For long-running processes like web servers, you can use `runBackground` to make sure they recompile and restart when code changes, +forcefully terminating the previous process even though it may be still alive: + +[source,bash] +---- +$ mill -w foo.compile +$ mill -w foo.runBackground +---- + + +== Parallel Task Execution (Experimental) + +By default, mill will evaluate all tasks in sequence. +But mill also supports processing tasks in parallel. +This feature is currently experimental and we encourage you to report any issues you find on our bug tracker. + +To enable parallel task execution, use the `--jobs` (`-j`) option followed by a number of maximal parallel threads. + +Example: Use up to 4 parallel threads to compile all modules: + +[source,bash] +---- +mill -j 4 __.compile +---- + +To use as many threads as your machine has (logical) processor cores use `--jobs 0`. +To disable parallel execution use `--jobs 1`. +This is currently the default. + +Please note that the maximal possible parallelism depends on your project. +Tasks that depend on each other can't be processed in parallel. + + +== Command-line usage + +Mill is a command-line tool and supports various options. + +Run `mill --help` for a complete list of options + +.Output of `mill --help` +---- +Mill Build Tool +usage: mill [options] [[target [target-options]] [+ [target ...]]] + --no-default-predef Disable the default predef and run Ammonite with the minimal predef possible + -s --silent Make ivy logs go silent instead of printing though failures will still throw + exception + -w --watch Watch and re-run your scripts when they change + --bsp Run a BSP server against the passed scripts + -c --code Pass in code to be run immediately in the REPL + -h --home The home directory of the REPL; where it looks for config and caches + -p --predef Lets you load your predef from a custom location, rather than the "default + location in your Ammonite home + --color Enable or disable colored output; by default colors are enabled in both REPL + and scripts if the console is interactive, and disabled otherwise + --thin Hide parts of the core of Ammonite and some of its dependencies. By default, + the core of Ammonite and all of its dependencies can be seen by users from + the Ammonite session. This option mitigates that via class loader isolation. + --help Print this message + -h --home The home directory of the REPL; where it looks for config and caches + --repl Run Mill in interactive mode and start a build REPL. In this mode, no mill + server will be used. Must be the first argument. + --no-server Run Mill in interactive mode, suitable for opening REPLs and taking user + input. In this mode, no mill server will be used. Must be the first argument. + -i --interactive Run Mill in interactive mode, suitable for opening REPLs and taking user + input. In this mode, no mill server will be used. Must be the first argument. + -v --version Show mill version and exit. + -b --bell Ring the bell once if the run completes successfully, twice if it fails. + --disable-ticker Disable ticker log (e.g. short-lived prints of stages and progress bars) + -d --debug Show debug output on STDOUT + -k --keep-going Continue build, even after build failures + -D --define Define (or overwrite) a system property + -j --jobs Allow processing N targets in parallel. Use 1 to disable parallel and 0 to + use as much threads as available processors. + rest ... The name of the targets you want to build, followed by any parameters you + wish to pass to those targets. +---- + +All _options_ must be given before the first target. + +A _target_ is a fully qualified task or command optionally followed by target specific arguments. +You can use wildcards and brace-expansion to select multiple targets at once or to shorten the path to deeply nested targets. +If you provide optional target arguments and your wildcard or brace-expansion is resolved to multiple targets, the arguments will be applied to each of the targets. + +.Wildcards and brace-expansion +|=== +| Wildcard | Function +|`_` | matches a single segment of the target path +| `__` | matches arbitrary segments of the target path +| `{a,b}` | is equal to specifying two targets `a` and `b` +|=== + +You can use the `+` symbol to add another target with optional arguments. +If you need to feed a `+` as argument to your target, you can mask it by preceding it with a backslash (`\`). + +=== Examples + +`+mill foo._.compile+`:: Runs `compile` for all direct sub-modules of `foo` +`+mill foo.__.test+` :: Runs `test` for all sub-modules of `foo` +`+mill {foo,bar}.__.testCached+` :: Runs `testCached` for all sub-modules of `foo` and `bar` +`+mill __.compile + foo.__.test+` :: Runs all `compile` targets and all tests under `foo`. + + +== Built-in commands + +Mill comes with a number of useful commands out of the box. + +=== init + +[source,bash] +---- +$ mill -i init com-lihaoyi/mill-scala-hello.g8 +.... +A minimal Scala project. + +name [Scala Seed Project]: hello + +Template applied in ./hello +---- + +The `init` command generates a project based on a Giter8 template. +It prompts you to enter project name and creates a folder with that name. +You can use it to quickly generate a starter project. +There are lots of templates out there for many frameworks and tools! + + +=== resolve + +[source,bash] +---- +$ mill resolve _ +[1/1] resolve +clean +foo +inspect +par +path +plan +resolve +show +shutdown +version +visualize +visualizePlan + +$ mill resolve _.compile +[1/1] resolve +foo.compile + +$ mill resolve foo._ +[1/1] resolve +foo.allSourceFiles +foo.allSources +foo.ammoniteReplClasspath +foo.ammoniteVersion +foo.artifactId +foo.artifactName +... +---- + +`resolve` lists the tasks that match a particular query, without running them. +This is useful for "dry running" an `mill` command to see what would be run before you run them, or to explore what modules or tasks are available +from the command line using `+resolve _+`, `+resolve foo._+`, etc. + +[source,bash] +---- +mill resolve foo.{compile,run} +mill resolve "foo.{compile,run}" +mill resolve foo.compile foo.run +mill resolve _.compile # list the compile tasks for every top-level module +mill resolve __.compile # list the compile tasks for every module +mill resolve _ # list every top level module and task +mill resolve foo._ # list every task directly within the foo module +mill resolve __ # list every module and task recursively +---- + +=== inspect + +[source,bash] +---- +$ mill inspect foo.run +[1/1] inspect +foo.run(JavaModule.scala:442) + Runs this module's code in a subprocess and waits for it to finish + +Inputs: + foo.finalMainClass + foo.runClasspath + foo.forkArgs + foo.forkEnv + foo.forkWorkingDir +---- + +`inspect` is a more verbose version of <<_resolve>>. In addition to printing out the name of one-or-more tasks, +it also displays its source location and a list of input tasks. This is very useful for debugging and interactively +exploring the structure of your build from the command line. + +`inspect` also works with the same `+_+`/`+__+` wildcard/query syntaxes that +<<_resolve>> do: + +[source,bash] +---- +mill inspect foo.compile +mill inspect foo.{compile,run} +mill inspect "foo.{compile,run}" +mill inspect foo.compile foo.run +mill inspect _.compile +mill inspect __.compile +mill inspect _ +mill inspect foo._ +mill inspect __ +---- + +=== show + +[source,bash] +---- +$ mill show foo.scalaVersion +[1/1] show +"2.13.1" +---- + +By default, Mill does not print out the metadata from evaluating a task. Most people would not be interested in e.g. +viewing the metadata related to incremental compilation: they just want to compile their code! However, if you want to +inspect the build to debug problems, you can make Mill show you the metadata output for a task using the `show` command: + +`show` is not just for showing configuration values. +All tasks return values that can be shown with `show`. +E.g. `compile` returns the paths to the `classes` folder and `analysisFile` file produced by the compilation: + +[source,bash] +---- +$ mill show foo.compile +[1/1] show +[10/25] foo.resources +{ + "analysisFile": "/Users/lihaoyi/Dropbox/Github/test//out/foo/compile.dest/zinc", + "classes": "ref:07960649:/Users/lihaoyi/Dropbox/Github/test//out/foo/compile.dest/classes" +} +---- + +`show` is generally useful as a debugging tool, to see what is going on in your build: + +[source,bash] +---- +$ mill show foo.sources +[1/1] show +[1/1] foo.sources +[ + "ref:8befb7a8:/Users/lihaoyi/Dropbox/Github/test/foo/src" +] + +$ mill show foo.compileClasspath +[1/1] show +[2/11] foo.resources +[ + "ref:c984eca8:/Users/lihaoyi/Dropbox/Github/test/foo/resources", + ".../org/scala-lang/scala-library/2.13.1/scala-library-2.13.1.jar" +] +---- + +`show` is also useful for interacting with Mill from external tools, since the JSON it outputs is structured and easily +parsed and manipulated. + +When `show` is used with multiple targets, its output will slightly change to a JSON array, containing all the results of the given targets. + +[source,bash] +---- +$ mill show "foo.{sources,compileClasspath}" +[1/1] show +[2/11] foo.resources +[ + [ + "ref:8befb7a8:/Users/lihaoyi/Dropbox/Github/test/foo/src" + ], + [ + "ref:c984eca8:/Users/lihaoyi/Dropbox/Github/test/foo/resources", + ".../org/scala-lang/scala-library/2.13.1/scala-library-2.13.1.jar" + ] +] +---- + +=== showNamed + +Same as `show`, but the output will always be structured in a JSON dictionary, with the task names as key and the task results as JSON values. + +[source,bash] +---- +$ mill showNamed "foo.{sources,compileClasspath}" +[1/1] show +[2/11] foo.resources +{ + "foo.sources": + [ + "ref:8befb7a8:/Users/lihaoyi/Dropbox/Github/test/foo/src" + ], + "foo.compileClasspath": + [ + "ref:c984eca8:/Users/lihaoyi/Dropbox/Github/test/foo/resources", + ".../org/scala-lang/scala-library/2.13.1/scala-library-2.13.1.jar" + ] +} +---- + +=== path + +[source,bash] +---- +$ mill path foo.assembly foo.sources +[1/1] path +foo.sources +foo.allSources +foo.allSourceFiles +foo.compile +foo.localClasspath +foo.assembly +---- + +`mill path` prints out a dependency chain between the first task and the second. +It is very useful for exploring the build graph and trying to figure out how data gets from one task to another. +If there are multiple possible dependency chains, one of them is picked arbitrarily. + +=== plan + +[source,bash] +---- +$ mill plan foo.compileClasspath +[1/1] plan +foo.transitiveLocalClasspath +foo.resources +foo.unmanagedClasspath +foo.scalaVersion +foo.platformSuffix +foo.compileIvyDeps +foo.scalaOrganization +foo.scalaLibraryIvyDeps +foo.ivyDeps +foo.transitiveIvyDeps +foo.compileClasspath +---- + +`mill plan foo` shows which tasks would be evaluated, and in what order, if you ran `mill foo`, but without actually running them. +This is a useful tool for debugging your build: e.g. if you suspect a task `foo` is running things that it +shouldn't be running, a quick `mill plan` will list out all the upstream tasks that `foo` needs to run, and you can then +follow up with `mill path` on any individual upstream task to see exactly how `foo` depends on it. + +=== visualize + +[source,bash] +---- +$ mill show visualize foo._ +[1/1] show +[3/3] visualize +[ + ".../out/visualize.dest/out.txt", + ".../out/visualize.dest/out.dot", + ".../out/visualize.dest/out.json", + ".../out/visualize.dest/out.png", + ".../out/visualize.dest/out.svg" +] +---- + +`mill show visualize` takes a subset of the Mill build graph (e.g. `+core._+` is every task directly under the `core` +module) and draws out their relationships in `.svg` and `.png` form for you to inspect. It also generates `.txt`, `.dot` +and `.json` for easy processing by downstream tools. + +The above command generates the following diagram: + +image::VisualizeFoo.svg[VisualizeFoo.svg] + +=== visualizePlan + +[source,bash] +---- +$ mill show visualizePlan foo.compile +[1/1] show +[3/3] visualizePlan +[ + ".../out/visualizePlan.dest/out.txt", + ".../out/visualizePlan.dest/out.dot", + ".../out/visualizePlan.dest/out.json", + ".../out/visualizePlan.dest/out.png", + ".../out/visualizePlan.dest/out.svg" +] +---- + +`mill show visualizePlan` is similar to `mill show visualize` except that it shows a graph of the entire build plan, +including tasks not directly resolved by the query. Tasks directly resolved are shown with a solid border, and +dependencies are shown with a dotted border. + +The above command generates the following diagram: + +image::VisualizePlan.svg[VisualizePlan.svg] + +Another use case is to view the relationships between modules. For the following two modules: + +.`build.sc` +[source,scala] +---- +import mill._, scalalib._ + +object foo extends ScalaModule { + def scalaVersion = "2.13.1" +} + +object bar extends ScalaModule { + def moduleDeps = Seq(foo) + + def scalaVersion = "2.13.1" +} +---- + +`+mill show visualizePlan _.compile+` diagrams the relationships between the compile tasks of each module, which +illustrates which module depends on which other module's compilation output: + +image::VisualizeCompile.svg[VisualizeCompile.svg] + +=== clean + +[source,bash] +---- +$ mill clean +---- + +`clean` deletes all the cached outputs of previously executed tasks. It can apply to the entire project, entire modules, +or specific tasks. + +[source,bash] +---- +mill clean # clean all outputs +mill clean foo # clean all outputs for module 'foo' (including nested modules) +mill clean foo.compile # only clean outputs for task 'compile' in module 'foo' +mill clean foo.{compile,run} +mill clean "foo.{compile,run}" +mill clean foo.compile foo.run +mill clean _.compile +mill clean __.compile +---- + +=== Search for dependency updates + +[source,bash] +---- +$ mill mill.scalalib.Dependency/showUpdates +---- + +Mill can search for updated versions of your project's dependencies, if available from your project's configured +repositories. Note that it uses heuristics based on common versioning schemes, so it may not work as expected for +dependencies with particularly weird version numbers. + +Current limitations: + +* Only works for `JavaModule` modules (including ``ScalaModule``s, +``CrossScalaModule``s, etc.) and Maven repositories. +* Always applies to all modules in the build. +* Doesn't apply to `$ivy` dependencies used in the build definition itself. + +[source,bash] +---- +mill mill.scalalib.Dependency/showUpdates +mill mill.scalalib.Dependency/showUpdates --allowPreRelease true # also show pre-release versions +---- + + +== The Build REPL + +[source,scala] +---- +$ mill --repl +Loading... +@ foo +res0: foo.type = ammonite.predef.build#foo:4 +Commands: + .ideaJavaModuleFacets(ideaConfigVersion: Int)() + .ideaConfigFiles(ideaConfigVersion: Int)() + .ivyDepsTree(inverse: Boolean, withCompile: Boolean, withRuntime: Boolean)() + .runLocal(args: String*)() + .run(args: String*)() + .runBackground(args: String*)() + .runMainBackground(mainClass: String, args: String*)() + .runMainLocal(mainClass: String, args: String*)() + .runMain(mainClass: String, args: String*)() + .console()() + .repl(replOptions: String*)() +Targets: +... + +@ foo.compile +res1: mill.package.T[mill.scalalib.api.CompilationResult] = foo.compile(ScalaModule.scala:143) + Compiles the current module to generate compiled classfiles/bytecode + +Inputs: + foo.upstreamCompileOutput + foo.allSourceFiles + foo.compileClasspath +... + +@ foo.compile() +[25/25] foo.compile +res2: mill.scalalib.api.CompilationResult = CompilationResult( + /Users/lihaoyi/Dropbox/Github/test/out/foo/compile.dest/zinc, + PathRef(/Users/lihaoyi/Dropbox/Github/test/out/foo/compile.dest/classes, false, -61934706) +) +---- + +You can run `mill --repl` to open a build REPL; this is a Scala console with your `build.sc` loaded, which lets you run +tasks interactively. +The task-running syntax is slightly different from the command-line, but more in line with how you +would depend on tasks from within your build file. + +You can use this REPL to interactively explore your build to see what is available. + + +== Deploying your code + +The two most common things to do once your code is complete is to make an assembly (e.g. for deployment/installation) or +publishing (e.g. to Maven Central). Mill comes with both capabilities built in. + +Mill comes with the built-in with the ability to make assemblies. Given a simple Mill build: + +.`build.sc` +[source,scala] +---- +import mill._, scalalib._ + +object foo extends ScalaModule { + def scalaVersion = "2.13.1" +} +---- + +You can make a self-contained assembly via: + +[source,bash] +---- +$ mill foo.assembly + +$ ls -lh out/foo/assembly.dest/out.jar +-rw-r--r-- 1 lihaoyi staff 5.0M Feb 17 11:14 out/foo/assembly.dest/out.jar +---- + +You can then move the `out.jar` file anywhere you would like, and run it standalone using `java`: + +[source,bash] +---- +$ java -cp out/foo/assembly.dest/out.jar foo.Example +Hello World! +---- + +To publish to Maven Central, you need to make `foo` also extend Mill's +`PublishModule` trait: + +.`build.sc` +[source,scala] +---- +import mill._, scalalib._, publish._ + +object foo extends ScalaModule with PublishModule { + def scalaVersion = "2.13.1" + + def publishVersion = "0.0.1" + + def pomSettings = PomSettings( + description = "Hello", + organization = "com.lihaoyi", + url = "https://github.com/lihaoyi/example", + licenses = Seq(License.MIT), + versionControl = VersionControl.github("lihaoyi", "example"), + developers = Seq( + Developer("lihaoyi", "Li Haoyi", "https://github.com/lihaoyi") + ) + ) +} +---- + +You can change the name of the published artifact (artifactId in the Maven POM) +by overriding `artifactName` in the module you want to publish. + +You can download an example project with this layout here: + +* {mill-github-url}/releases/download/{mill-last-tag}/{mill-last-tag}-example-2.zip[Example 2] + +Which you can then publish using the `mill foo.publish` command, which takes your sonatype credentials ( +e.g. `lihaoyi:foobarbaz`) and GPG password as inputs: + +[source,bash] +---- +$ mill foo.publish +Missing arguments: (--sonatypeCreds: String, --release: Boolean) + +Arguments provided did not match expected signature: + +publish + --sonatypeCreds String (format: "username:password") + --signed Boolean (default true) + --gpgArgs Seq[String] (default Seq("--batch", "--yes", "-a", "-b")) + --readTimeout Int (default 60000) + --release Boolean (default true) + --connectTimeout Int (default 5000) + --awaitTimeout Int (default 120000) + --stagingRelease Boolean (default true) +---- + +You also need to specify `release` as `true` or `false`, depending on whether you just want to stage your module +on `oss.sonatype.org` or you want Mill to complete the release process to Maven Central. + +If you are publishing multiple artifacts, you can also use `mill mill.scalalib.PublishModule/publishAll` as described + +xref:Common_Project_Layouts.adoc#_publishing[here] + + + +== Running Mill with custom JVM options + +It's possible to pass JVM options to the Mill launcher. To do this you need to create a `.mill-jvm-opts` file in your +project's root. This file should contain JVM options, one per line. + +For example, if your build requires a lot of memory and bigger stack size, your `.mill-jvm-opts` could look like this: + +---- +-Xss10m +-Xmx10G +---- + +The file name for passing JVM options to the Mill launcher is configurable. If for some reason you don't want to +use `.mill-jvm-opts` file name, add `MILL_JVM_OPTS_PATH` environment variable with any other file name. + + +--- + +Come by our https://gitter.im/lihaoyi/mill[Gitter Channel] if you want to ask questions or say hi! diff --git a/docs/antora/modules/ROOT/pages/Usage_Installation.adoc b/docs/antora/modules/ROOT/pages/Usage_Installation.adoc new file mode 100644 index 00000000000..9135331d5e7 --- /dev/null +++ b/docs/antora/modules/ROOT/pages/Usage_Installation.adoc @@ -0,0 +1,261 @@ += Installation + +== Downloading Mill + +=== OS X + +Installation via https://github.com/Homebrew/homebrew-core/blob/master/Formula/mill.rb[homebrew]: + +[source,sh] +---- +brew install mill + +---- + +=== Arch Linux + +Arch Linux has a https://www.archlinux.org/packages/community/any/mill/[Community package for mill]: + +[source,bash] +---- +pacman -S mill + +---- + +=== FreeBSD + +Installation via http://man.freebsd.org/pkg/8[pkg(8)]: + +[source,sh] +---- +pkg install mill + +---- + +=== Gentoo Linux + +[source,sh] +---- +emerge dev-java/mill-bin + +---- + +=== Windows + +To get started, download Mill from +{mill-github-url}/releases/download/{mill-last-tag}/{mill-last-tag}-assembly[Github releases], and save it as `mill.bat`. + +If you're using https://scoop.sh[Scoop] you can install Mill via + +[source,bash] +---- +scoop install mill +---- + +Mill also works on "sh" environments on Windows (e.g., +https://www.msys2.org[MSYS2], +https://www.cygwin.com[Cygwin], +https://gitforwindows.org[Git-Bash], +https://docs.microsoft.com/en-us/windows/wsl[WSL]); to get started, follow the instructions in the <<_manual>> +section below. Note that: + +* In some environments (such as WSL), Mill might have to be run without a server (using `-i`, `--interactive` +, `--no-server`, or +`--repl`.) + +* On Cygwin, run the following after downloading mill: + +[source,bash] +---- +sed -i '0,/-cp "\$0"/{s/-cp "\$0"/-cp `cygpath -w "\$0"`/}; 0,/-cp "\$0"/{s/-cp "\$0"/-cp `cygpath -w "\$0"`/}' /usr/local/bin/mill +---- + +=== Docker + +You can download and run +a https://hub.docker.com/r/nightscape/scala-mill/["Docker image containing OpenJDK, Scala and Mill"] using + +[source,bash] +---- +docker pull nightscape/scala-mill +docker run -it nightscape/scala-mill +---- + +=== Manual + +To get started, download Mill and install it into your HOME ".local/bin" via the following +`curl`/`chmod` command: + +[source,bash,subs="verbatim,attributes"] +---- +sh -c "curl -L {mill-github-url}/releases/download/{mill-last-tag}/{mill-last-tag} > ~/.local/bin/mill && chmod +x ~/.local/bin/mill" +---- + +=== Bootstrap Scripts (Linux/OS-X Only) + +If you are using Mill in a codebase, you can commit the bootstrap launcher as a +`./mill` script in the project folder: + +[source,bash,subs="verbatim,attributes"] +---- +curl -L {mill-github-url}/releases/download/{mill-last-tag}/{mill-last-tag} > mill && chmod +x mill +---- + +Now, anyone who wants to work with the project can simply use the `./mill` +script directly: + +[source,bash] +---- +./mill version +./mill __.compile # double underscore +---- + +The `mill` command will automatically use the version specified by the bootstrap script, even if you installed it via +other means. The `./mill` file has a version number embedded within it, which you can update simply by editing the +script. Note this only works for versions 0.5.0 and above. + +Bootstrap scripts are also useful for running Mill in CI, ensuring that your Jenkins/Travis/etc. box has the correct +version of Mill present to build/compile/test your code. + +=== millw + +Instead of installing Mill directly, you can also use https://github.com/lefou/millw[lefou/millw] as drop-in +replacement for `mill`. It provides a small shell script and also a Windows batch file, that transparently downloads `mill` +and executes it on your behalf. It respects various ways to configure the preferred Mill version (`MILL_VERSION` env +var, `.mill-version` file, `--mill-version` option) and can also be used as a bootstrap script in your project. + +=== Coursier (unsupported) + +Installing mill via `coursier` or `cs` is currently not officially supported. There are various issues, especially with +interactive mode. + + +== Updating Mill + +Once installed mill is able to use newer or different versions for each project automatically. You don't need to install +multiple versions of mill yourself. + +See section <<_overriding_mill_versions>> how to do it. + + +== Overriding Mill Versions + +Apart from downloading and installing new versions of Mill globally, there are a few ways of selecting/updating your Mill version: + +* Create a `.mill-version` file to specify the version of Mill you wish to use: +[source,bash] +---- +echo "0.5.0" > .mill-version +---- + +`.mill-version` takes precedence over the version of Mill specified in the +`./mill` script. + +* Pass in a `MILL_VERSION` environment variable, e.g. +[source,bash] +---- +MILL_VERSION=0.5.0-3-4faefb mill __.compile +---- + +or + +[source,bash] +---- +MILL_VERSION=0.5.0-3-4faefb ./mill __.compile +---- + +to override the Mill version manually. This takes precedence over the version specified in `./mill` or `.mill-version` + +Note that both of these overrides only work for versions 0.5.0 and above. + +=== Automatic Mill updates + +If your project is hosted on GitHub, GitLab, or Bitbucket, you can use https://github.com/scala-steward-org/scala-steward[Scala Steward] to automatically open a pull request to update your Mill version (in `.mill-version` file), whenever there is a newer version available. + +TIP: Scala Steward can also xref:Configuring_Mill.adoc#_keeping_up_to_date_with_scala_steward[scan your project dependencies] and keep them up-to-date. + +=== Development Releases + +In case you want to try out the latest features and improvements that are currently in the main branch, unstable versions of Mill +are +https://github.com/com-lihaoyi/mill/releases[available] as binaries named +`+#.#.#-n-hash+` linked to the latest tag. Installing the latest unstable release is recommended for bootstrapping mill. + +The easiest way to use a development release is by updating the <<_bootstrap_scripts_linuxos_x_only>>, +or +<<_overriding_mill_versions>> via an environment variable or `.mill-version` file. + + + +== IDE Support + +To support various IDEs and Language Servers, Mill supports the https://build-server-protocol.github.io/[Build Server Protocol] in version {bsp-version} and has a <>. + +In addition to BSP, Mill also supports <> directly. + +=== Build Server Protocol (BSP) + +To install a BSP connection file `.bsp/mill-bsp.json`, run: + +[source,bash] +---- +mill mill.bsp.BSP/install +---- + +Working known clients of the BSP server are IntelliJ IDEA and Metals. + +You can fine control some BSP server options by specifying command options: + +|=== +| Option | Description +|`--jobs` `n` | Use `n` threads in parallel to run tasks. A value of `0` means use as much threads as the system has cpu cores. +|=== + +[source] + +[NOTE] +-- +*Using Metals* + +When using Metals by default Bloop will be used as your build server unless you explicitly choose Mill. +When in a Mill workspace use the "Switch Build Server" command from Metals which will allow you to switch to using Mill as your build +server. +If no `.bsp/mill-bsp.json` file exists, Metals will automatically create it for you and then connect to Mill. + +Metals is relying on SemanticDB to enable many of its features. +Mill BSP now also supports to provide this SemanticDB data, when the BSP client (like Metals) requests it. + +As of writing this, Metals 0.11.8 is the latest available version, which is not able to detect the fact, that Mill _is_ already providing SemanticDB data. +As a consequence, it reports missing SemanticDB data, although some SemanticDB-based features are already working. +This may be fixed eventually in a future release of Metals. +-- + +[CAUTION] +-- +*Updating older setups* + +In the past, we provided SemanticDB support via `mill.scalalib.bsp.ScalaMetalsSupport` trait, which had to be mixed-in to your Scala modules. +This is no longer needed and deprecated. +You should remove these mix-ins. +`ScalaMetalsSupport` trait is now deprecated and will be removed in the future. +-- + +=== Using Bloop (standalone BSP server) + +If you wish to use Bloop as your build server (it is the default metals BSP implementation) with metals / vscode, consider using the mill bloop plugin. + +xref:Plugin_Bloop.adoc[Bloop Plugin] + + +This is preferred to the instructions (currently) on the bloop website. + + + +== IntelliJ Support + +To generate IntelliJ IDEA project files into `.idea/`, run: + +[source,bash] +---- +mill mill.scalalib.GenIdea/idea +---- diff --git a/docs/antora/modules/ROOT/pages/Usage_OutDir.adoc b/docs/antora/modules/ROOT/pages/Usage_OutDir.adoc new file mode 100644 index 00000000000..5dccb3bea1d --- /dev/null +++ b/docs/antora/modules/ROOT/pages/Usage_OutDir.adoc @@ -0,0 +1,75 @@ += Files Generated By Mill + +== The Output Directory + +Mill puts all its output in the top-level `out/` folder. The above commands would end up in: + +[source,text] +---- +out/ + foo/ + compile.dest + compile.log + compile.json + + run.dest + run.log + run.json + + runBackground.dest + runBackground.log + runBackground.json + + launcher.dest + launcher.log + launcher.json + + jar.dest + jar.log + jar.json + + assembly.dest + assembly.log + assembly.json +---- + +For each task there's a `foo.json` file containing the metadata returned by that task, and +two optional paths: a `foo.dest/` folder containing any files that the task generates and a `foo.log` file containing the the logs of running that task. For example, `out/foo/compile.dest/` contains the +compiled classfiles, while `out/foo/assembly.dest/` contains the self-contained assembly with the project's classfiles +jar-ed up with all its dependencies. + +Given a task `foo.bar`, all its output and results are inside its respective `out/foo/bar/` folder. + + +== Structure of the `out/` Directory + +The `out/` folder contains all the generated files & metadata for your build. It is structured with one folder +per `Target`/`Command`, that is run, e.g.: + +* `out/core/compile/` +* `out/main/test/compile/` +* `out/main/test/forkTest/` +* `out/scalalib/compile/` + +There are also top-level build-related files in the `out/` folder, prefixed as +`mill-*`. The most useful is `mill-profile.json`, which logs the tasks run and time taken for the last Mill command you +executed. This is very useful if you want to find out exactly what tasks are being run and Mill is being slow. + +Each task currently creates contains the following files: + +* `foo.dest/`: optional, a path for the `Task` to use either as a scratch space, or to place generated files that are returned +using `PathRef` references. A `Task` should only output files within its own given `dest/` folder (available as `T.dest`) to avoid +conflicting with another `Task`, but can name files within `dest/` arbitrarily. + +* `foo.log`: optional, the `stdout`/`stderr` of the `Task`. This is also streamed to the console during evaluation. + +* `foo.json`: the cache-key and JSON-serialized return-value of the +`Target`/`Command`. The return-value can also be retrieved via `mill show foo.compile`. Binary blobs are typically not +included in `foo.json`, and instead stored as separate binary files in `dest/` which are then referenced +by `foo.json` via `PathRef` references. + +The `out/` folder is intentionally kept simple and user-readable. If your build is not behaving as you would expect, +feel free to poke around the various +`foo.dest/` folders to see what files are being created, or the `foo.json` files to see what is being returned by a +particular task. You can also simply delete folders within `out/` if you want to force portions of your project to be +rebuilt, e.g. by deleting the `out/main/` or `out/main/test/compile/` folders. From b88a6048621423b1b382ac9e36dfb848881b699c Mon Sep 17 00:00:00 2001 From: Naftoli Gugenheim <98384+nafg@users.noreply.github.com> Date: Mon, 28 Nov 2022 22:46:28 -0500 Subject: [PATCH 2/2] docs: Rename Configuring Mill to Configuring your Project --- docs/antora/modules/ROOT/nav.adoc | 2 +- .../ROOT/pages/{Configuring_Mill.adoc => Configuration.adoc} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename docs/antora/modules/ROOT/pages/{Configuring_Mill.adoc => Configuration.adoc} (99%) diff --git a/docs/antora/modules/ROOT/nav.adoc b/docs/antora/modules/ROOT/nav.adoc index 405a1966521..4731b5fd22f 100644 --- a/docs/antora/modules/ROOT/nav.adoc +++ b/docs/antora/modules/ROOT/nav.adoc @@ -5,7 +5,7 @@ ** xref:Usage_Basics.adoc[] ** xref:Usage_OutDir.adoc[] -* xref:Configuring_Mill.adoc[] +* xref:Configuration.adoc[] * xref:Common_Project_Layouts.adoc[] * xref:Tasks.adoc[] ** xref:Task_Context_API.adoc[] diff --git a/docs/antora/modules/ROOT/pages/Configuring_Mill.adoc b/docs/antora/modules/ROOT/pages/Configuration.adoc similarity index 99% rename from docs/antora/modules/ROOT/pages/Configuring_Mill.adoc rename to docs/antora/modules/ROOT/pages/Configuration.adoc index 698d3983ccd..3af0f5a06ec 100644 --- a/docs/antora/modules/ROOT/pages/Configuring_Mill.adoc +++ b/docs/antora/modules/ROOT/pages/Configuration.adoc @@ -1,4 +1,4 @@ -= Configuring Mill += Configuring your Project You can configure your Mill build in a number of ways: