summaryrefslogtreecommitdiff
path: root/docs/pages/10 - Thirdparty Modules.md
blob: a6b87b812a92aca98d8db51191290517043eee25 (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
The modules (aka plugins) in this section are developed/maintained outside the mill git tree.

Besides the documentation provided here, we urge you to consult the respective linked plugin documentation pages.
The usage examples given here are most probably incomplete and sometimes outdated.

If you develop or maintain a mill plugin, please create a [pull request](https://github.com/lihaoyi/mill/pulls) to get your plugin listed here.

[comment]: # (Please keep list of plugins in alphabetical order)

## AspectJ

[AspectJ compiler](https://projects.eclipse.org/projects/tools.aspectj) support for mill.

Project home: https://github.com/lefou/mill-aspectj

### Quickstart

```scala
import mill._
import mill.scalalib._
import mill.define._

// Load the plugin from Maven Central via ivy/coursier
import $ivy.`de.tototec::de.tobiasroeser.mill.aspectj:0.1.0`, de.tobiasroeser.mill.aspectj._

object main extends AspectjModule {

  // Select the AspectJ version
  def aspectjVersion = T{ "{aspectjVersion}" }

  // Set AspectJ options, e.g. the language level and annotation processor
  // Run `mill main.ajcHelp` to get a list of supported options
  def ajcOptions = Seq("-8", "-proc:none")

}
```

### Configuration

Your module needs to extend `de.tobiasroeser.mill.aspectj.AspectjModule` which itself extends `mill.scalalib.JavaModule`.

The module trait `de.tobiasroeser.mill.aspectj.AspectjModule` has various configuration options (over those from `mill.scalalib.JavaModule`).

The most essential targets are:

* `def aspectjVersion: T[String]` - The AspectJ version. _Required_.
For a list of available releases refer to the [AspectJ Download Page](https://www.eclipse.org/aspectj/downloads.php).

* `def ajcOptions: T[Seq[String]]` - Additional options to be used by `ajc` in the `compile` target.

* `def compile: T[CompilationResult]` - Compiles the source code with the ajc compiler.

For a complete list of configuration options and more documentation, please refer to the [project home page](https://github.com/lefou/mill-aspectj).

## Bash Completion

Limited bash completion support.

Project home: https://github.com/lefou/mill-bash-completion


## DGraph

Show transitive dependencies of your build in your browser.

Project home: https://github.com/ajrnz/mill-dgraph

### Quickstart

```scala
import $ivy.`com.github.ajrnz::mill-dgraph:0.2.0`
```

```sh
sh> mill plugin.dgraph.browseDeps(proj)()
```

## Ensime

Create an [.ensime](http://ensime.github.io/ "ensime") file for your build.

Project home: https://github.com/yyadavalli/mill-ensime

### Quickstart

```scala
import $ivy.`fun.valycorp::mill-ensime:0.0.1`
```

```sh
sh> mill fun.valycorp.mill.GenEnsime/ensimeConfig
```

## Integration Testing Mill Plugins

Integration testing for mill plugins.

### Quickstart

We assume, you have a mill plugin named `mill-demo`

```scala
// build.sc
import mill._, mill.scalalib._
object demo extends ScalaModule with PublishModule {
  // ...
}
```

Add an new test sub-project, e.g. `it`.

```scala
import $ivy.`de.tototec::de.tobiasroeser.mill.integrationtest:0.1.0`
import de.tobiasroeser.mill.integrationtest._

object it extends MillIntegrationTest {

  def millTestVersion = "{exampleMillVersion}"

  def pluginsUnderTest = Seq(demo)

}
```

Your project should now look similar to this:

```text
.
+-- demo/
|   +-- src/
|
+-- it/
    +-- src/
        +-- 01-first-test/
        |   +-- build.sc
        |   +-- src/
        |
        +-- 02-second-test/
            +-- build.sc
```

As the buildfiles `build.sc` in your test cases typically want to access the locally built plugin(s),
the plugins publishes all plugins referenced under `pluginsUnderTest` to a temporary ivy repository, just before the test is executed.
The mill version used in the integration test then used that temporary ivy repository.

Instead of referring to your plugin with `import $ivy.'your::plugin:version'`,
you can use the following line instead, which ensures you will use the correct locally build plugins.

```scala
// build.sc
import $exec.plugins
```

Effectively, at execution time, this line gets replaced by the content of `plugins.sc`, a file which was generated just before the test started to execute.

### Configuration and Targets

The mill-integrationtest plugin provides the following targets.

#### Mandatory configuration

* `def millTestVersion: T[String]`
  The mill version used for executing the test cases.
  Used by `downloadMillTestVersion` to automatically download.

* `def pluginsUnderTest: Seq[PublishModule]` -
  The plugins used in the integration test.
  You should at least add your plugin under test here.
  You can also add additional libraries, e.g. those that assist you in the test result validation (e.g. a local test support project).
  The defined modules will be published into a temporary ivy repository before the tests are executed.
  In your test `build.sc` file, instead of the typical `import $ivy.` line,
  you should use `import $exec.plugins` to include all plugins that are defined here.

#### Optional configuration

* `def sources: Sources` -
  Locations where integration tests are located.
  Each integration test is a sub-directory, containing a complete test mill project.

* `def testCases: T[Seq[PathRef]]` -
  The directories each representing a mill test case.
  Derived from `sources`.

* `def testTargets: T[Seq[String]]` -
  The targets which are called to test the project.
  Defaults to `verify`, which should implement test result validation.

* `def downloadMillTestVersion: T[PathRef]` -
  Download the mill version as defined by `millTestVersion`.
  Override this, if you need to use a custom built mill version.
  Returns the `PathRef` to the mill executable (must have the executable flag).

#### Commands

* `def test(): Command[Unit]` -
  Run the integration tests.


## JBake

Create static sites/blogs with JBake.

Plugin home: https://github.com/lefou/mill-jbake

JBake home: https://jbake.org

### Quickstart

```scala
// build.sc
import mill._
import $ivy.`de.tototec::de.tobiasroeser.mill.jbake:0.1.0`
import de.tobiasroeser.mill.jbake._

object site extends JBakeModule {

  def jbakeVersion = "2.6.4"

}
```

Generate the site:

```sh
bash> mill site.jbake
```

Start a local Web-Server on Port 8820 with the generated site:

```sh
bash> mill site.jbakeServe
```

## Mill Wrapper Scripts

Small script to automatically fetch and execute mill build tool.

Project home: https://github.com/lefou/millw

### How it works

`millw` is a small wrapper script around mill and works almost identical to mill. It automatically downloads a mill release into `$HOME/.mill/download`.

The mill version to be used will be determined by the following steps. The search ends, after the first step that results in a version.

* If the first parameter is `--mill-version`, the second parameter will be used as the mill version.
  Example

  ```
  sh $ mill --mill-version 0.3.6 --disable-ticker version
  0.3.6
  ```

* If there is a file `.mill-version` in the working directory, it’s content will be used as mill version. The file must have only a mill version as content, no additional content or comments are supported.
  Example

  ```
  sh $ echo -n "0.3.6" > .mill-version
  sh $ mill --disable-ticker version
  0.3.6
  ```

  The values of the `DEFAULT_MILL_VERSION` variable inside the script will be used.



### Use cases

#### As mill executable

Istead of installing mill, you can just place the script into you local `$HOME/bin` directory and rename it to `mill`.

If you need a special mill version in a project directory, just place a `.mill-version` file with the best mill version.
Example: setting mill 0.3.6 as best local mill version

```
sh $ echo -n "0.3.6" > .mill-version
```

#### As a wrapper script in your project

To make the start for others easier or to always have the correct mill version in your CI environment, you can just place a copy of the script as `millw` in your project root directory.

You should change the `DEFAULT_MILL_VERSION` variable in that script to the correct version you want to use and add the file under version control.


## OSGi

Produce OSGi Bundles with mill.

Project home: https://github.com/lefou/mill-osgi

### Quickstart

```scala
import mill._, mill.scalalib._
import $ivy.`de.tototec::de.tobiasroeser.mill.osgi:0.0.5`
import de.tobiasroeser.mill.osgi._

object project extends ScalaModule with OsgiBundleModule {

  def bundleSymbolicName = "com.example.project"

  def osgiHeaders = T{ super.osgiHeaders().copy(
    `Export-Package`   = Seq("com.example.api"),
    `Bundle-Activator` = Some("com.example.internal.Activator")
  )}

  // other settings ...

}
```


## PublishM2

Mill plugin to publish artifacts into a local Maven repository.

Project home: https://github.com/lefou/mill-publishM2

### Quickstart

Just mix-in the `PublishM2Module` into your project.
`PublishM2Module` already extends mill's built-in `PublishModule`.

File: `build.sc`
```scala
import mill._, scalalib._, publish._

import $ivy.`de.tototec::de.tobiasroeser.mill.publishM2:0.0.1`
import de.tobiasroeser.mill.publishM2._

object project extends PublishModule with PublishM2Module {
  // ...
}
```

Publishing to default local Maven repository

```bash
> mill project.publishM2Local
[40/40] project.publishM2Local
Publishing to /home/user/.m2/repository
```

Publishing to custom local Maven repository

```bash
> mill project.publishM2Local /tmp/m2repo
[40/40] project.publishM2Local
Publishing to /tmp/m2repo
```

## JBuildInfo

This is a [mill](https://www.lihaoyi.com/mill/) module similar to 
[BuildInfo](https://www.lihaoyi.com/mill/page/contrib-modules.html#buildinfo)
but for Java. 
It will generate a Java class containing information from your build.

Project home: https://github.com/carueda/mill-jbuildinfo

To declare a module that uses this plugin, extend the
`com.github.carueda.mill.JBuildInfo` trait and provide
the desired information via the `buildInfoMembers` method:

```scala
// build.sc
import $ivy.`com.github.carueda::jbuildinfo:0.1.2`
import com.github.carueda.mill.JBuildInfo
import mill.T

object project extends JBuildInfo {
  def buildInfoMembers: T[Map[String, String]] = T {
    Map(
      "name" -> "some name",
      "version" -> "x.y.z"
    )
  }
}
```

This will generate:

```java
// BuildInfo.java
public class BuildInfo {
  public static final String getName() { return "some name"; }
  public static final String getVersion() { return "x.y.z"; }
}
```

### Configuration options

* `def buildInfoMembers: T[Map[String, String]]`

    The map containing all member names and values for the generated class.

* `def buildInfoClassName: String`, default: `BuildInfo`

    The name of the class that will contain all the members from
    `buildInfoMembers`.

* `def buildInfoPackageName: Option[String]`, default: `None`
  
    The package name for the generated class.