-
-
Notifications
You must be signed in to change notification settings - Fork 303
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
example/basic/2-custom-build-logic
(#2559)
This is a minimal example meant to demonstrate how including custom logic in your Mill build works. This is notable enough that it's worth calling out up-front, rather than waiting until the more detailed discussion of the same topics in `example/scalabuilds/2-custom-tasks`
- Loading branch information
Showing
12 changed files
with
97 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// Mill makes it very easy to customize your build graph, overriding portions | ||
// of it with custom logic. In this example, we override the JVM `resources` of | ||
// our `ScalaModule` - normally the `resources/` folder - to instead contain a | ||
// single generated text file containing the line count of all the source files | ||
// in that module | ||
import mill._, scalalib._ | ||
|
||
object foo extends RootModule with ScalaModule { | ||
def scalaVersion = "2.13.8" | ||
|
||
/** Total number of lines in module's source files */ | ||
def lineCount = T{ | ||
allSourceFiles().map(f => os.read.lines(f.path).size).sum | ||
} | ||
|
||
/** Generate resources using lineCount of sources */ | ||
override def resources = T{ | ||
os.write(T.dest / "line-count.txt", "" + lineCount()) | ||
Seq(PathRef(T.dest)) | ||
} | ||
} | ||
|
||
/** Usage | ||
> ./mill run | ||
... | ||
Line Count: 11 | ||
> ./mill show lineCount | ||
11 | ||
> ./mill inspect lineCount | ||
lineCount(build.sc:7) | ||
Total number of lines in module's source files | ||
Inputs: | ||
allSourceFiles | ||
*/ | ||
|
||
// Above, `def lineCount` is a new build target we define, which makes use of | ||
// `allSourceFiles` (an existing target) and is in-turn used in our override of | ||
// `resources` (also an existing target). This generated file can then be | ||
// loaded and used at runtime, as see in the output of `./mill run` | ||
// | ||
// While this is a toy example, it shows how easy it is to customize your Mill | ||
// build to include the kinds of custom logic common in the build config of | ||
// most real-world projects. | ||
// | ||
// This customization is done in a principled fashion familiar to most | ||
// programmers - object-orienting overrides - rather than ad-hoc | ||
// monkey-patching or mutation common in other build tools. You never have | ||
// "spooky action at a distance" affecting your build / graph definition, and | ||
// your IDE can always help you find the final override of any particular build | ||
// target as well as where any overriden implementations may be defined. | ||
// | ||
// Lastly, custom user-defined targets in Mill benefit from all the same things | ||
// that built-in targets do: caching, parallelism (with the `-j`/`--jobs` | ||
// flag), inspectability via `show`/`inspect`, and so on. | ||
// | ||
// While these things may not matter for such a simple example that runs | ||
// quickly, they ensure that custom build logic remains performant and | ||
// maintainable even as the complexity of your project grows. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package foo | ||
|
||
object Foo{ | ||
def main(args: Array[String]): Unit = { | ||
val lineCount = scala.io.Source | ||
.fromResource("line-count.txt") | ||
.mkString | ||
|
||
println(s"Line Count: $lineCount") | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
example/basic/2-custom-build-logic/test/src/FooTests.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package foo | ||
import utest._ | ||
object FooTests extends TestSuite { | ||
def tests = Tests { | ||
test("simple") { | ||
val result = Foo.generateHtml("hello") | ||
assert(result == "<h1>hello</h1>") | ||
result | ||
} | ||
test("escaping") { | ||
val result = Foo.generateHtml("<hello>") | ||
assert(result == "<h1><hello></h1>") | ||
result | ||
} | ||
} | ||
} |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters