diff options
author | Li Haoyi <haoyi.sg@gmail.com> | 2018-02-10 09:49:37 -0800 |
---|---|---|
committer | Li Haoyi <haoyi.sg@gmail.com> | 2018-02-10 09:57:44 -0800 |
commit | 3075356a2b6f6a10c43a32e6413fcbd41b4d0822 (patch) | |
tree | 6c62c724ce72477ee2174688eefb8dab5b250342 /docs/intro.md | |
parent | d7c05de2a43611ab25597b8fc299a67dd47c8a9e (diff) | |
download | mill-3075356a2b6f6a10c43a32e6413fcbd41b4d0822.tar.gz mill-3075356a2b6f6a10c43a32e6413fcbd41b4d0822.tar.bz2 mill-3075356a2b6f6a10c43a32e6413fcbd41b4d0822.zip |
Set theme jekyll-theme-leap-day
Diffstat (limited to 'docs/intro.md')
-rw-r--r-- | docs/intro.md | 517 |
1 files changed, 9 insertions, 508 deletions
diff --git a/docs/intro.md b/docs/intro.md index 30b455e9..a351c55b 100644 --- a/docs/intro.md +++ b/docs/intro.md @@ -1,4 +1,3 @@ -## Hello Mill The simplest Mill build for a Scala project looks as follows: @@ -47,7 +46,7 @@ re-evaluate unless one of their inputs changes, where-as commands re-run every time. -### Multiple Modules +## Multiple Modules ```scala import mill._ @@ -154,7 +153,7 @@ $ mill foo.assembly $ mill foo.bar.assembly ``` -### Watch and Re-evaluate +## 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: @@ -164,11 +163,11 @@ $ mill --watch foo.compile $ mill --watch foo.run ``` -### Command-line Tools +## Command-line Tools Mill comes built in with a small number of useful command-line utilities: -#### all +### all ```bash mill all foo.{compile,run} @@ -180,7 +179,7 @@ mill all __.compile # run compile for every module `all` runs multiple tasks in a single command -#### resolve +### resolve ```bash mill resolve foo.{compile,run} @@ -200,7 +199,7 @@ before you run them, or to explore what modules or tasks are available from the command line using `resolve _`, `resolve foo._`, etc. -#### describe +### describe ```bash $ mill describe core.run @@ -235,7 +234,7 @@ mill describe __ mill describe foo._ ``` -#### show +### show 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 @@ -275,7 +274,7 @@ $ mill show foo.compileDepClasspath `show` is also useful for interacting with Mill from external tools, since the JSON it outputs is structured and easily parsed & manipulated. -### IntelliJ Support +## IntelliJ Support Mill supports IntelliJ by default. Use `mill mill.scalalib.GenIdea/idea` to generate an IntelliJ project config for your build. @@ -288,7 +287,7 @@ Any flags passed *before* the name of the task (e.g. `foo.compile`) are given to Mill, while any arguments passed *after* the task are given to the task itself. For example: -### The Build Repl +## The Build Repl ```bash $ mill @@ -331,502 +330,4 @@ You can use this REPL to run build commands quicker, due to keeping the JVM warm between runs, or to interactively explore your build to see what is available. -## Configuring Mill -You can configure your Mill build in a number of ways: - -### Compilation & Execution Flags - -```scala -import mill._ -import mill.scalalib._ -object foo extends ScalaModule { - def scalaVersion = "2.12.4" - - def scalacOptions = Seq("-Ydelambdafy:inline") - - def forkArgs = Seq("-Xmx4g") - - def forkEnv = Map("HELLO_MY_ENV_VAR" -> "WORLD") -} -``` - -You can pass flags to the Scala compiler via `scalacOptions`. By default, -`foo.run` runs the compiled code in a subprocess, and you can pass in JVM flags -via `forkArgs` or environment-variables via `forkEnv`. - -You can also run your code via - -```bash -mill foo.runLocal -``` - -Which runs it in-process within an isolated classloader. This may be faster -since you avoid the JVM startup, but does not support `forkArgs` or `forkEnv`. - -### Adding Ivy Dependencies - -```scala -import mill._ -import mill.scalalib._ -object foo extends ScalaModule { - def scalaVersion = "2.12.4" - def ivyDeps = Agg( - ivy"com.lihaoyi::upickle:0.5.1", - ivy"com.lihaoyi::pprint:0.5.2", - ivy"com.lihaoyi::fansi:0.2.4" - ) -} -``` - -You can define the `ivyDeps` field to add ivy dependencies to your module. The -`ivy"com.lihaoyi::upickle:0.5.1"` syntax (with `::`) represents Scala -dependencies; for Java dependencies you would use a single `:` e.g. -`ivy"com.lihaoyi:upickle:0.5.1"`. - -By default these are resolved from maven central, but you can add your own -resolvers by overriding the `repositories` definition in the module: - -```scala -def repositories = super.repositories ++ Seq( - MavenRepository("https://oss.sonatype.org/content/repositories/releases") -) -``` - -### Adding a Test Suite - -```scala -import mill._ -import mill.scalalib._ -object foo extends ScalaModule { - def scalaVersion = "2.12.4" - - object test extends Tests{ - def ivyDeps = Agg(ivy"com.lihaoyi::utest:0.6.0") - def testFramework = "mill.UTestFramework" - } -} -``` - -You can define a test suite by creating a nested module extending `Tests`, and -specifying the ivy coordinates and name of your test framework. This expects the -tests to be laid out as follows: - -``` -build.sc -foo/ - src/ - Main.scala - resources/ - ... - test/ - src/ - MainTest.scala - resources/ - ... -out/ - foo/ - ... - test/ - ... -``` - -The above example can be run via - -```bash -mill foo.test -``` - -By default, tests are run in a subprocess, and `forkArg` and `forkEnv` can be -overriden to pass JVM flags & environment variables. You can also use - -```bash -mill foo.test.testLocal -``` - -To run tests in-process in an isolated classloader. - -You can define multiple test suites if you want, e.g.: - -```scala -import mill._ -import mill.scalalib._ -object foo extends ScalaModule { - def scalaVersion = "2.12.4" - - object test extends Tests{ - def ivyDeps = Agg(ivy"com.lihaoyi::utest:0.6.0") - def testFramework = "mill.UTestFramework" - } - object integration extends Tests{ - def ivyDeps = Agg(ivy"com.lihaoyi::utest:0.6.0") - def testFramework = "mill.UTestFramework" - } -} -``` - -Each of which will expect their sources to be in their respective `foo/test` and -`foo/integration` folder. - -`Tests` modules are `ScalaModule`s like any other, and all the same -configuration options apply. - - -### Scala Compiler Plugins - -```scala -import mill._ -import mill.scalalib._ -object foo extends ScalaModule { - def scalaVersion = "2.12.4" - - def compileIvyDeps = Agg(ivy"com.lihaoyi::acyclic:0.1.7") - def scalacOptions = Seq("-P:acyclic:force") - def scalacPluginIvyDeps = Agg(ivy"com.lihaoyi::acyclic:0.1.7") -} -``` - -You can use Scala compiler plugins by setting `scalacPluginIvyDeps`. The above -example also adds the plugin to `compileIvyDeps`, since that plugin's artifact -is needed on the compilation classpath (though not at runtime). - -### Common Configuration - -```scala -import mill._ -import mill.scalalib._ -trait CommonModule extends ScalaModule{ - def scalaVersion = "2.12.4" -} - -object foo extends CommonModule -object bar extends CommonModule { - def moduleDeps = Seq(foo) -} -``` - -You can extract out configuration common to multiple modules into a `trait` that -those modules extend. This is useful for providing convenience & ensuring -consistent configuration: every module often has the same scala-version, uses -the same testing framework, etc. and all that can be extracted out into the -`trait`. - -### Custom Tasks - -```scala -import mill._ -import mill.scalalib._ -object foo extends ScalaModule { - def scalaVersion = "2.12.4" -} - -def lineCount = T{ - import ammonite.ops._ - foo.sources().flatMap(ref => ls.rec(ref.path)).flatMap(read.lines).size -} - -def printLineCount() = T.command{ - println(lineCount()) -} -``` - -You can define new cached Targets using the `T{...}` syntax, depending on -existing Targets e.g. `foo.sources` via the `foo.sources()` syntax to extract -their current value, as shown in `lineCount` above. The return-type of a Target -has to be JSON-serializable (using -[uPickle](https://github.com/lihaoyi/upickle)) and the Target is cached when -first run until it's inputs change (in this case, if someone edits the -`foo.sources` files which live in `foo/src`. Cached Targets cannot take -parameters. - -You can print the value of your custom target using `show`, e.g. - -```bash -mill run show lineCount -``` - -You can define new un-cached Commands using the `T.command{...}` syntax. These -are un-cached and re-evaluate every time you run them, but can take parameters. -Their return type needs to be JSON-writable as well, or `(): Unit` if you want -to return nothing. - -### Custom Modules - -```scala -import mill._ -import mill.scalalib._ -object qux extends Module{ - object foo extends ScalaModule { - def scalaVersion = "2.12.4" - } - object bar extends ScalaModule { - def moduleDeps = Seq(foo) - def scalaVersion = "2.12.4" - } -} -``` - -Not every Module needs to be a `ScalaModule`; sometimes you just want to group -things together for neatness. In the above example, you can run `foo` and `bar` -namespaced inside `qux`: - -```bash -mill qux.foo.compile -mill qux.bar.run -``` - -You can also define your own module traits, with their own set of custom tasks, -to represent other things e.g. Javascript bundles, docker image building,: - -```scala -trait MySpecialModule extends Module{ - ... -} -object foo extends MySpecialModule -object bar extends MySpecialModule -``` - -### Overriding Tasks - -```scala -import mill._ -import mill.scalalib._ - -object foo extends ScalaModule { - def scalaVersion = "2.12.4" - def compile = T{ - println("Compiling...") - super.compile() - } - def run(args: String*) = T.command{ - println("Running... + args.mkString(" ")) - super.run(args:_*) - } -} -``` - -You can re-define targets and commands to override them, and use `super` if you -want to refer to the originally defined task. The above example shows how to -override `compile` and `run` to add additional logging messages. - -In Mill builds the `override` keyword is optional. - -## Common Project Layouts - -Above, we have shown how to work with the Mill default Scala module layout. Here -we will explore some other common project layouts that you may want in your -Scala build: - -### Cross Scala-Version Modules - -```scala -import mill._ -import mill.scalalib._ -object foo extends Cross[FooModule]("2.10.6", "2.11.11", "2.12.4") -class FooModule(val crossScalaVersion: String) extends CrossScalaModule{ - ... -} -``` - -Mill provides a `CrossScalaModule` template, which can be used with `Cross` to -cross-build Scala modules across different versions of Scala. The default -configuration for `CrossScalaModule` expects a filesystem layout as follows: - -```text -build.sc -foo/ - src/ - src-2.10/ - src-2.11/ - src-2.12/ - test/ - src/ - src-2.10/ - src-2.11/ - src-2.12/ -``` - -Code common to all Scala versions lives in `src`, while code specific to one -version lives in `src-x.y`. - -### Scala.js Modules - -```scala -import mill._ -import mill.scalajslib._ - -object foo extends ScalaJSModule { - def scalaVersion = "2.12.4" - def scalaJSVersion = "0.6.22" -} -``` - -`ScalaJSModule` is a variant of `ScalaModule` that builds your code using -Scala.js. In addition to the standard `foo.compile` and `foo.run` commands (the -latter of which runs your code on Node.js, which must be pre-installed) -`ScalaJSModule` also exposes the `foo.fastOpt` and `foo.fullOpt` tasks for -generating the optimized Javascript file. - -### SBT-Compatible Modules - -```scala -import mill._ -import mill.scalalib._ - -object foo extends SbtModule { - def scalaVersion = "2.12.4" -} -``` - -These are basically the same as normal `ScalaModule`s, but configured to follow -the SBT project layout: - -```text -build.sc -foo/ - src/ - main/ - scala/ - test/ - scala/ -``` - -Useful if you want to migrate an existing project built with SBT without having -to re-organize all your files - - -### SBT-Compatible Cross Scala-Version Modules - -```scala -import mill._ -import mill.scalalib._ -object foo extends Cross[FooModule]("2.10.6", "2.11.11", "2.12.4") -class FooModule(val crossScalaVersion: String) extends CrossSbtModule{ - ... -} -``` - -A `CrossSbtModule` is a version of `CrossScalaModule` configured with the SBT -project layout: - -```text -build.sc -foo/ - src/ - main/ - scala/ - scala-2.10/ - scala-2.11/ - scala-2.12/ - test/ - scala/ - scala-2.10/ - scala-2.11/ - scala-2.12/ -``` - -### Publishing -```scala -import mill._ -import mill.scalalib._ -object foo extends ScalaModule with PublishModule{ - def scalaVersion = "2.12.4" - def publishVersion = "0.0.1 - def pomSettings = PomSettings( - description = "My first library", - organization = "com.lihaoyi", - url = "https://github.com/lihaoyi/mill", - licenses = Seq( - License("MIT license", "http://www.opensource.org/licenses/mit-license.php") - ), - scm = SCM( - "git://github.com/lihaoyi/mill.git", - "scm:git://github.com/lihaoyi/mill.git" - ), - developers = Seq( - Developer("lihaoyi", "Li Haoyi","https://github.com/lihaoyi") - ) - ) -} -``` - -You can make a module publishable by extending `PublishModule`. - -`PublishModule` then needs you to define a `publishVersion` and `pomSettings`. -The `artifactName` defaults to the name of your module (in this case `foo`) but -can be overriden. The `organization` is defined in `pomSettings`. - -Once you've mixed in `PublishModule`, you can publish your libraries to maven -central via: - -```bash -target/bin/mill mill.scalalib.PublishModule/publishAll \ - lihaoyi:$SONATYPE_PASSWORD \ - $GPG_PASSWORD \ - foo.publishArtifacts -``` - -This uploads them to `oss.sonatype.org` where you can log-in and stage/release -them manually. You can also pass in the `--release true` flag to perform the -staging/release automatically: - -```bash -target/bin/mill mill.scalalib.PublishModule/publishAll \ - lihaoyi:$SONATYPE_PASSWORD \ - $GPG_PASSWORD \ - foo.publishArtifacts \ - --release true -``` - -If you want to publish/release multiple modules, you can use the `_` or `__` -wildcard syntax: - -```bash -target/bin/mill mill.scalalib.PublishModule/publishAll \ - lihaoyi:$SONATYPE_PASSWORD \ - $GPG_PASSWORD \ - __.publishArtifacts \ - --release true -``` - - -## Example Builds - -Mill comes bundled with example builds for existing open-source projects, as -integration tests and examples: - - -### Acyclic - -- [Mill Build](https://github.com/lihaoyi/mill/blob/master/integration/test/resources/acyclic/build.sc#L1) - -A small single-module cross-build, with few sources minimal dependencies, and -wired up for publishing to Maven Central - - -### Better-Files - -- [Mill Build](https://github.com/lihaoyi/mill/blob/master/integration/test/resources/better-files/build.sc#L1) - -A collection of small modules compiled for a single Scala version. - -Also demonstrates how to define shared configuration in a `trait`, enable Scala -compiler flags, and download artifacts as part of the build. - -### Jawn - -- [Mill Build](https://github.com/lihaoyi/mill/blob/master/integration/test/resources/jawn/build.sc#L1) - -A collection of relatively small modules, all cross-built across the same few -versions of Scala. - - -### Ammonite - -- [Mill Build](https://github.com/lihaoyi/mill/blob/master/integration/test/resources/ammonite/build.sc#L1) - -A relatively complex build with numerous submodules, some cross-built across -Scala major versions while others are cross-built against Scala minor versions. - -Also demonstrates how to pass one module's compiled artifacts to the -`run`/`test` commands of another, via their `forkEnv`. |