summaryrefslogtreecommitdiff
path: root/readme.md
blob: 5f51c285512c93ca9c644a46e5299ec368ea2b49 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
# ![Mill Logo](docs/logo.svg) Mill [![Build Status][travis-badge]][travis-link] [![Build (Windows)][appveyor-badge]][appveyor-link] [![Gitter Chat][gitter-badge]][gitter-link] [![Patreon][patreon-badge]][patreon-link]

[appveyor-badge]: https://ci.appveyor.com/api/projects/status/github/lihaoyi/mill
[appveyor-link]: https://ci.appveyor.com/project/lihaoyi/mill
[travis-badge]: https://travis-ci.org/lihaoyi/mill.svg
[travis-link]: https://travis-ci.org/lihaoyi/mill
[gitter-badge]: https://badges.gitter.im/Join%20Chat.svg
[gitter-link]: https://gitter.im/lihaoyi/mill?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
[patreon-badge]: https://img.shields.io/badge/patreon-sponsor-ff69b4.svg
[patreon-link]: https://www.patreon.com/lihaoyi

Your shiny new Scala build tool! Confused by SBT? Frustrated by Maven? Perplexed
by Gradle? Give Mill a try!

If you want to use Mill in your own projects, check out our documentation:

- [Documentation](http://www.lihaoyi.com/mill/)

The remainder of this readme is targeted at people who wish to work on Mill's
own codebase.

## How to build and test

Mill is built using Mill. To begin, first download & install Mill as described
in the documentation above.
As Mill is under active development, stable releases may not be able to build 
the current development branch of Mill.
It is recommended to install the latest unstable release manually.

To run unit test suite:

```bash
mill main.test
```

Build a standalone executable jar:

```bash
mill dev.assembly
```

Now you can re-build this very same project using the build.sc file, e.g. re-run
core unit tests

e.g.:   
```bash
./out/dev/assembly/dest/mill core.compile
./out/dev/assembly/dest/mill main.test.compile
./out/dev/assembly/dest/mill main.test
./out/dev/assembly/dest/mill scalalib.assembly
```

There is already a `watch` option that looks for changes on files, e.g.:

```bash
./out/dev/assembly/dest/mill --watch core.compile
```

You can get Mill to show the JSON-structured output for a particular `Target` or
`Command` using the `show` flag:

```bash
./out/dev/assembly/dest/mill show core.scalaVersion
./out/dev/assembly/dest/mill show core.compile
./out/dev/assembly/dest/mill show core.assemblyClasspath
./out/dev/assembly/dest/mill show main.test
```

Output will be generated into a the `./out` folder.

You can clean the project using `clean`:

```bash
# Clean entire project.
mill clean
# Clean a single target.
mill clean main
# Clean multiple targets.
mill clean main core
```

If you are repeatedly testing Mill manually by running it against the `build.sc`
file in the repository root, you can skip the assembly process and directly run
it via:

```bash
mill --watch dev.run . main.test
mill --watch dev.run .
```

You can also test out your current Mill code with one of the hello-world example
repos via:

```bash
mill dev.run docs/example-1 foo.run
```

Lastly, you can generate IntelliJ Scala project files using Mill via

```bash
./out/dev/assembly/dest/mill mill.scalalib.GenIdea/idea
```

Allowing you to import a Mill project into Intellij without using SBT

### Command line

There is a number of ways to run targets and commands via command line:

* Run single target:
```bash
mill core.compile
```

* Run single command with arguments:
```bash
mill bridges[2.12.4].publish --credentials foo --gpgPassphrase bar
```

* Run multiple targets:
```bash
mill all main.test scalalib.test 
```

**Note**: don't forget to put `all` flag when you run multiple commands, otherwise the only first command will be run, and subsequent commands will be passed as arguments to the first one.

* Run multiple commands with arguments:
```bash
mill all bridges[2.11.11].publish bridges[2.12.4].publish -- --credentials foo --gpgPassphrase bar 
```

Here `--credentials foo --gpgPassphrase bar` arguments will be passed to both `bridges[2.11.11].publish` and `bridges[2.12.4].publish` command. 

**Note**: arguments list should be separated with `--` from command list.


Sometimes it is tedious to write multiple targets when you want to run same target in multiple modules, or multiple targets in one module.
Here brace expansion from bash(or another shell that support brace expansion) comes to rescue. It allows you to make some "shortcuts" for multiple commands.

* Run same targets in multiple modules with brace expansion:
```bash
mill all {core,scalalib,scalajslib,integration}.test
```

will run `test` target in `core`, `scalalib`, `scalajslib` and `integration` modules.

* Run multiple targets in one module with brace expansion:
```bash
mill all scalalib.{compile,test}
```

will run `compile` and `test` targets in `scalalib` module.

* Run multiple targets in multiple modules:
```bash
mill all {core,scalalib}.{scalaVersion,scalaBinaryVersion}
```

will run `scalaVersion` and `scalaBinaryVersion` targets in both `core` and `scalalib` modules. 

* Run targets in different cross build modules

```bash
mill all bridges[{2.11.11,2.12.4}].publish --  --credentials foo --gpgPassphrase bar
```

will run `publish` command in both `brides[2.11.11]` and `bridges[2.12.4]` modules

You can also use the `_` wildcard and `__` recursive-wildcard to run groups of
tasks:

```bash
# Run the `test` command of all top-level modules
mill all _.test

# Run the `test` command of all modules, top-level or nested
mill all __.test

# Run `compile` in every cross-module of `bridges`
mill all bridges[_].compile
```

**Note**: When you run multiple targets with `all` command, they are not
guaranteed to run in that exact order. Mill will build task evaluation graph and
run targets in correct order.

### REPL

Mill provides a build REPL, which lets you explore the build interactively and
run `Target`s from Scala code:

```scala
$ mill -i

Loading...
Compiling (synthetic)/ammonite/predef/interpBridge.sc
Compiling (synthetic)/ammonite/predef/replBridge.sc
Compiling (synthetic)/ammonite/predef/DefaultPredef.sc
Compiling /Users/lihaoyi/Dropbox/Workspace/mill/build.sc
Compiling /Users/lihaoyi/Dropbox/Workspace/mill/out/run.sc
Compiling (synthetic)/ammonite/predef/CodePredef.sc

@ build
res0: build.type = build

@ build.
!=            core          scalalib   bridges       getClass      isInstanceOf  |>
==            MillModule    asInstanceOf  equals        hashCode      toString
@ build.core
res1: core = ammonite.predef.build#core:45
Children:
    .test
Commands:
    .console()()
    .run(args: String*)()
    .runMain(mainClass: String, args: String*)()
Targets:
    .allSources()
    .artifactId()
    .artifactName()
    .artifactScalaVersion()
    .assembly()
    .assemblyClasspath()
    .classpath()
    .compile()
    .compileDepClasspath()
    .compileIvyDeps()
    .compilerBridge()
    .crossFullScalaVersion()
    .depClasspath()
    .docJar()
    .externalCompileDepClasspath()
    .externalCompileDepSources()
...

@ core
res2: core.type = ammonite.predef.build#core:45
Children:
    .test
Commands:
    .console()()
    .run(args: String*)()
    .runMain(mainClass: String, args: String*)()
Targets:
    .allSources()
    .artifactId()
    .artifactName()
    .artifactScalaVersion()
    .assembly()
    .assemblyClasspath()
    .classpath()
    .compile()
    .compileDepClasspath()
    .compileIvyDeps()
    .compilerBridge()
    .crossFullScalaVersion()
    .depClasspath()
    .docJar()
    .externalCompileDepClasspath()
    .externalCompileDepSources()
...

@ core.scalaV
scalaVersion
@ core.scalaVersion
res3: mill.define.Target[String] = ammonite.predef.build#MillModule#scalaVersion:20
Inputs:

@ core.scalaVersion()
[1/1] core.scalaVersion
res4: String = "2.12.4"

@ core.ivyDeps()
Running core.ivyDeps
[1/1] core.ivyDeps
res5: Seq[mill.scalalib.Dep] = List(
  Scala(Dependency(Module("com.lihaoyi", "sourcecode", Map()),
   "0.1.4",
...

@ core.ivyDeps().foreach(println)
Scala(Dependency(com.lihaoyi:sourcecode,0.1.4,,Set(),Attributes(,),false,true))
Scala(Dependency(com.lihaoyi:pprint,0.5.3,,Set(),Attributes(,),false,true))
Point(Dependency(com.lihaoyi:ammonite,1.0.3,,Set(),Attributes(,),false,true))
Scala(Dependency(com.typesafe.play:play-json,2.6.6,,Set(),Attributes(,),false,true))
Scala(Dependency(org.scala-sbt:zinc,1.0.5,,Set(),Attributes(,),false,true))
Java(Dependency(org.scala-sbt:test-interface,1.0,,Set(),Attributes(,),false,true))

// run multiple tasks with `eval` function.
@ val (coreScala, bridge2106Scala) = eval(core.scalaVersion, bridges("2.10.6").scalaVersion)
coreScala: String = "2.12.4"
bridge2106Scala: String = "2.10.6"
```

### build.sc

Into a `build.sc` file you can define separate `Module`s (e.g. `ScalaModule`).
Within each `Module` you can define 3 type of task:

- `Target`: take no argument, output is cached and should be serializable; run
  from `bash` (e.g. `def foo = T{...}`)
- `Command`: take serializable arguments, output is not cached; run from `bash`
  (arguments with `scopt`) (e.g. `def foo = T.command{...}`)
- `Task`: take arguments, output is not cached; do not run from `bash` (e.g.
  `def foo = T.task{...}` )


### 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/`

Each folder currently contains the following files:

- `dest/`: a path for the `Task` to use either as a scratch space, or to place
  generated files that are returned using `PathRef`s. `Task`s should only output
  files within their given `dest/` folder (available as `T.ctx().dest`) to avoid
  conflicting with other `Task`s, but files within `dest/` can be named
  arbitrarily.

- `log`: the `stdout`/`stderr` of the `Task`. This is also streamed to the
  console during evaluation.

- `meta.json`: the cache-key and JSON-serialized return-value of the
  `Target`/`Command`. The return-value can also be retrieved via `mill show
  core.compile`. Binary blobs are typically not included in `meta.json`, and
  instead stored as separate binary files in `dest/` which are then referenced
  by `meta.json` via `PathRef`s

### Troubleshooting

In case of troubles with caching and/or incremental compilation, you can always
restart from scratch removing the `out` directory:

```bash
rm -rf out/
```

## Changelog

### 0.2.0

- Universal (combined batch/sh) script generation for launcher, assembly, and
  release ([#264](https://github.com/lihaoyi/mill/issues/264))

- Windows client/server improvements ([#262](https://github.com/lihaoyi/mill/issues/262))

- Windows repl support (note: MSYS2 subsystem/shell will be supported when jline3
  v3.6.3 is released)
  
- Fixed Java 9 support

- Remove need for running `publishAll` using `--interactive` when on OSX and
  your GPG key has a passphrase

- First-class support for `JavaModule`s

- Properly pass compiler plugins to Scaladoc ([#282](https://github.com/lihaoyi/mill/issues/282))

- Support for ivy version-pinning via `ivy"...".forceVersion()`

- Support for ivy excludes via `ivy"...".exclude()` ([#254](https://github.com/lihaoyi/mill/pull/254))

- Make `ivyDepsTree` properly handle transitive dependencies ([#226](https://github.com/lihaoyi/mill/issues/226))

- Fix handling of `runtime`-scoped ivy dependencies ([#173](https://github.com/lihaoyi/mill/issues/173))

- Make environment variables available to Mill builds ([#257](https://github.com/lihaoyi/mill/issues/257))

- Support ScalaCheck test runner ([#286](https://github.com/lihaoyi/mill/issues/286))

- Support for using Typelevel Scala ([#275](https://github.com/lihaoyi/mill/issues/275))

- If a module depends on multiple submodules with different versions of an
  ivy dependency, only one version is resolved ([#273](https://github.com/lihaoyi/mill/issues/273))



### 0.1.7
 
- Support for non-interactive (client/server) mode on Windows.

- More fixes for Java 9

- Bumped the Mill daemon timeout from 1 minute to 5 minutes of inactivity before
  it shuts down.

- Avoid leaking Node.js subprocesses when running `ScalaJSModule` tests

- Passing command-line arguments with spaces in them to tests no longer parses
  wrongly

- `ScalaModule#repositories`, `scalacPluginIvyDeps`, `scalacOptions`,
  `javacOptions` are now automatically propagated to `Tests` modules

- `ScalaJSModule` linking errors no longer show a useless stack trace

- `ScalaModule#docJar` now properly uses the compileClasspath rather than
  runClasspath

- Bumped underlying Ammonite version to [1.1.0](http://ammonite.io/#1.1.0),
  which provides the improved Windows and Java 9 support

### 0.1.6

- Fixes for non-interactive (client/server) mode on Java 9

- Windows batch (.bat) generation for launcher, assembly, and release

### 0.1.5

- Introduced the `mill plan foo.bar` command, which shows you what the execution
  plan of running the `foo.bar` task looks like without actually evaluating it.

- Mill now generates an `out/mill-profile.json` file containing task-timings, to
  make it easier to see where your mill evaluation time is going
  
- Introduced `ScalaModule#ivyDepsTree` command to show dependencies tree
  
- Rename `describe` to `inspect` for consistency with SBT

- `mill resolve` now prints results sorted alphabetically

- Node.js configuration can be customised with `ScalaJSModule#nodeJSConfig`

- Scala.js `fullOpt` now uses Google Closure Compiler after generating the optimized Javascript output

- Scala.js now supports `NoModule` and `CommonJSModule` module kinds

- Include `compileIvyDeps` when generating IntelliJ projects

- Fixed invalid POM generation

- Support for Java 9 (and 10)

- Fixes for Windows support

- Fixed test classes discovery by skipping interfaces

- Include "optional" artifacts in dependency resolution if they exist

- `out/{module_name}` now added as a content root in generated IntelliJ project

### 0.1.4

- Speed up Mill client initialization by another 50-100ms

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

- Make `ScalaJSModule#run` work with main-method discovery

- Make `ScalaWorkerModule` user-defineable, so you can use your own custom
  coursier resolvers when resolving Mill's own jars

- Simplify definitions of `SCM` strings

- Make the build REPL explicitly require `-i`/`--interactive` to run

- Log a message when Mill is initializing the Zinc compiler interface

### 0.1.3

- Greatly reduced the overhead of evaluating Mill tasks, with a warm
  already-cached `mill dev.launcher` now taking ~450ms instead of ~1000ms

- Mill now saves compiled build files in `~/.mill/ammonite`, which is
  configurable via the `--home` CLI arg.

- Fixed linking of multi-module Scala.js projects

### 0.1.2

- Mill now keeps a long-lived work-daemon around in between commands; this
  should improve performance of things like `compile` which benefit from the
  warm JVM. You can use `-i`/`--interactive` for interactive consoles/REPLs and
  for running commands without the daemon

- Implemented the `ScalaModule#launcher` target for easily creating command-line
  launchers you can run outside of Mill

- `ScalaModule#docJar` no longer fails if you don't have `scala-compiler` on
  classpath

- Support for multiple `testFrameworks` in a test module.

### 0.1.1

- Fixes for `foo.console`
- Enable Ammonite REPL integration via `foo.repl`

### 0.1.0

- First public release