summaryrefslogtreecommitdiff
path: root/docs/extending.md
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2018-02-10 08:52:04 -0800
committerLi Haoyi <haoyi.sg@gmail.com>2018-02-10 08:52:04 -0800
commit2e80b3ae15466ea82a4f8ffa016dee1ee8a62825 (patch)
treedbb2019dc301d63cb13c60d2d46125f4977026a0 /docs/extending.md
parentfb7d39ad7f6dee1580bd30ec96ae494d97f146f1 (diff)
downloadmill-2e80b3ae15466ea82a4f8ffa016dee1ee8a62825.tar.gz
mill-2e80b3ae15466ea82a4f8ffa016dee1ee8a62825.tar.bz2
mill-2e80b3ae15466ea82a4f8ffa016dee1ee8a62825.zip
move docs around, try to fix publishAll
Diffstat (limited to 'docs/extending.md')
-rw-r--r--docs/extending.md152
1 files changed, 152 insertions, 0 deletions
diff --git a/docs/extending.md b/docs/extending.md
index e69de29b..9b4656f8 100644
--- a/docs/extending.md
+++ b/docs/extending.md
@@ -0,0 +1,152 @@
+There are many different ways of extending Mill, depending on how much
+customization and flexibility you need. This page will go through your options
+from the easiest/least-flexible to the hardest/most-flexible.
+
+## Custom Targets & Commands
+
+The simplest way of adding custom functionality to Mill is to define a custom
+Target or Command:
+
+```scala
+def foo = T{ ... }
+def bar(x: Int, s: String) = T.command{ ... }
+```
+
+These can depend on other Targets, contain arbitrary code, and be placed
+top-level or within any module. If you have something you just want to *do* that
+isn't covered by the built-in `ScalaModule`s/`ScalaJSModule`s, simply write a
+custom Target (for cached computations) or Command (for un-cached actions) and
+you're done.
+
+This covers use cases like:
+
+### Compile some Javascript with Webpack and put it in your runtime classpath:
+
+```scala
+def doWebpackStuff(sources: Seq[PathRef]): PathRef = ???
+
+def javascriptSources = T.sources{ millSourcePath / "js" }
+def compiledJavascript = T{ doWebpackStuff(javascriptSources()) }
+object foo extends ScalaModule{
+ def runClasspath = T{ super.runClasspath() ++ compiledJavascript() }
+}
+```
+
+### Deploy your compiled assembly to AWS
+
+```scala
+object foo extends ScalaModule{
+
+}
+
+def deploy(assembly: PathRef, credentials: String) = ???
+
+def deployFoo(credentials: String) = T.command{ deployFoo(foo.assembly()) }
+```
+
+
+## Custom Workers
+
+[Custom Targets & Commands](#custom-targets--commands) are re-computed from
+scratch each time; sometimes you want to keep values around in-memory when using
+`--watch` or the Build REPL. e.g. you may want to keep a webpack process running
+so webpack's own internal caches are hot and compilation is fast:
+
+```scala
+def webpackWorker = T.worker{
+ // Spawn a process using java.lang.Process and return it
+}
+
+def javascriptSources = T.sources{ millSourcePath / "js" }
+
+def doWebpackStuff(webpackProcess: Process, sources: Seq[PathRef]): PathRef = ???
+
+def compiledJavascript = T{ doWebpackStuff(webpackWorker(), javascriptSources()) }
+```
+
+## Custom Modules
+
+```scala
+trait FooModule extends mill.Module{
+ def bar = T{ "hello" }
+ def baz = T{ "world" }
+}
+```
+
+Custom modules are useful if you have a common set of tasks that you want to
+re-used across different parts of your build. You simply define a `trait`
+inheriting from `mill.Module`, and then use that `trait` as many times as you
+want in various `object`s:
+
+```scala
+object foo1 extends FooModule
+object foo2 extends FooModule{
+ def qux = T{ "I am Cow" }
+}
+```
+
+You can also define a `trait` extending the built-in `ScalaModule` if you have
+common configuration you want to apply to all your `ScalaModule`s:
+
+```scala
+trait FooModule extends ScalaModule{
+ def scalaVersion = "2.11.11"
+ object test extends Tests{
+ def ivyDeps = Agg(ivy"org.scalatest::scalatest:3.0.4")
+ def testFramework = "org.scalatest.tools.Framework"
+ }
+}
+```
+
+## import $file
+
+If you want to define some functionality that can be used both inside and
+outside the build, you can create a new `foo.sc` file next to your `build.sc`,
+`import $file.foo`, and use it in your `build.sc` file:
+
+```scala
+// foo.sc
+def fooValue() = 31337
+```
+```scala
+// build.sc
+import $file.foo
+def printFoo() = T.command{ println(foo.fooValue()) }
+```
+
+Mill's `import $file` syntax supports the full functionality of
+[Ammonite Scripts](http://ammonite.io/#ScalaScripts)
+
+## import $ivy
+
+If you want to pull in artifacts from the public repositories (e.g. Maven
+Central) for use in your build, you can simple use `import $ivy`:
+
+```scala
+// build.sc
+import $ivy.`com.lihaoyi::scalatags:0.6.2`
+
+
+def generatedHtml = T{
+ import scalatags.Text.all._
+ html(
+ head(),
+ body(
+ h1("Hello"),
+ p("World")
+ )
+ ).render
+}
+```
+
+This creates the `generatedHtml` target which can then be used however you would
+like: written to a file, further processed, etc.
+
+If you want to publish re-usable libraries that *other* people can use in their
+builds, simply publish your code as a library to maven central.
+
+For more information, see Ammonite's
+[Ivy Dependencies documentation](http://ammonite.io/#import$ivy)
+
+## Custom Main Methods
+