Scala Build Examples
Example Builds for Real Projects
Mill comes bundled with example builds for real-world open-source projects, demonstrating how Mill can be used to build code outside of tiny example codebases:
Acyclic
package build
import mill.*, scalalib.*, publish.*
import mill.api.BuildCtx
acyclic test suite assumes files are on disk at specific paths relative to os.pwd
.
To avoid changing the test code, we instead copy the necessary files into the os.pwd
when preparing the resources for test suite execution
BuildCtx.withFilesystemCheckerDisabled {
os.copy.over(
BuildCtx.watch(mill.api.BuildCtx.workspaceRoot / "acyclic"),
os.pwd / "acyclic",
createFolders = true
)
}
object Deps {
def acyclic = mvn"com.lihaoyi:::acyclic:0.3.6"
def scalaCompiler(scalaVersion: String) = mvn"org.scala-lang:scala-compiler:$scalaVersion"
val utest = mvn"com.lihaoyi::utest:0.8.5"
}
val crosses =
Range.inclusive(8, 20).map("2.12." + _) ++
Range.inclusive(0, 16).map("2.13." + _)
object acyclic extends Cross[AcyclicModule](crosses)
trait AcyclicModule extends CrossScalaModule, PublishModule {
def crossFullScalaVersion = true
def artifactName = "acyclic"
def publishVersion = "1.3.3.7"
def pomSettings = PomSettings(
description = artifactName(),
organization = "com.lihaoyi",
url = "https://github.com/com-lihaoyi/acyclic",
licenses = Seq(License.MIT),
versionControl = VersionControl.github(owner = "com-lihaoyi", repo = "acyclic"),
developers = Seq(Developer("lihaoyi", "Li Haoyi", "https://github.com/lihaoyi"))
)
def compileMvnDeps = Seq(Deps.scalaCompiler(crossScalaVersion))
object test extends ScalaTests, TestModule.Utest {
def sources = Task.Sources("src", "resources")
def mvnDeps = Seq(Deps.utest, Deps.scalaCompiler(crossScalaVersion))
}
}
Acyclic is an example of a very small project that is a Scala compiler
plugin. It is cross-built against all point versions of Scala from 2.11.12
to 2.13.10, and has a dependency on the org.scala-lang:scala-compiler
Project home: https://github.com/com-lihaoyi/acyclic
> ./mill acyclic[2.12.20].compile
compiling 6 Scala sources...
...
> ./mill acyclic[2.13.16].test.testLocal # acyclic tests need testLocal due to classloader assumptions
-------------------------------- Running Tests --------------------------------
...
Fansi
package build
import mill._, scalalib._, scalajslib._, scalanativelib._, publish._
import mill.util.VcsVersion
import mill.javalib.api.JvmWorkerUtil.isScala3
val dottyCommunityBuildVersion = sys.props.get("dottyVersion")
val scalaVersions = Seq("2.12.20", "2.13.16", "3.3.6") ++ dottyCommunityBuildVersion
trait FansiModule extends PublishModule with CrossScalaModule with PlatformScalaModule {
def artifactName = "fansi"
def publishVersion = "1.3.3.7"
def pomSettings = PomSettings(
description = artifactName(),
organization = "com.lihaoyi",
url = "https://github.com/com-lihaoyi/Fansi",
licenses = Seq(License.MIT),
versionControl = VersionControl.github(owner = "com-lihaoyi", repo = "fansi"),
developers = Seq(
Developer("lihaoyi", "Li Haoyi", "https://github.com/lihaoyi")
)
)
def mvnDeps = Seq(mvn"com.lihaoyi::sourcecode::0.4.0")
}
trait FansiTestModule extends ScalaModule with TestModule.Utest {
def mvnDeps = Seq(mvn"com.lihaoyi::utest::0.8.3")
}
object fansi extends Module {
object jvm extends Cross[JvmFansiModule](scalaVersions)
trait JvmFansiModule extends FansiModule with ScalaModule {
object test extends ScalaTests with FansiTestModule
}
object js extends Cross[JsFansiModule](scalaVersions)
trait JsFansiModule extends FansiModule with ScalaJSModule {
def scalaJSVersion = "1.19.0"
object test extends ScalaJSTests with FansiTestModule
}
object native extends Cross[NativeFansiModule](scalaVersions)
trait NativeFansiModule extends FansiModule with ScalaNativeModule {
def scalaNativeVersion = "0.5.8"
object test extends ScalaNativeTests with FansiTestModule
}
}
Fansi is an example of a small library that is cross built against every minor version of Scala (including Scala 3.x) and every platform: JVM, JS, and Native. Both the library and the test suite are duplicated across all entries in the {version}x{platform} matrix, and you can select which one you want to compile, test, or publish
Project home: https://github.com/com-lihaoyi/fansi
> ./mill resolve __.compile
fansi.js[2.12.20].compile
fansi.js[2.12.20].test.compile
fansi.js[2.13.16].compile
fansi.js[2.13.16].test.compile
fansi.js[3.3.6].compile
fansi.js[3.3.6].test.compile
fansi.jvm[2.12.20].compile
fansi.jvm[2.12.20].test.compile
fansi.jvm[2.13.16].compile
fansi.jvm[2.13.16].test.compile
fansi.jvm[3.3.6].compile
fansi.jvm[3.3.6].test.compile
fansi.native[2.12.20].compile
fansi.native[2.12.20].test.compile
fansi.native[2.13.16].compile
fansi.native[2.13.16].test.compile
fansi.native[3.3.6].compile
fansi.native[3.3.6].test.compile
> ./mill fansi.jvm[2.12.20].compile
compiling 1 Scala source...
...
> ./mill fansi.js[2.13.16].test
Starting process: node
-------------------------------- Running Tests --------------------------------
...
> ./mill fansi.native[3.3.6].publishLocal
Publishing Artifact(com.lihaoyi,fansi_native0.5_3,1.3.3.7) to ivy repo...
...
Real World Mill Builds
Ammonite
Ammonite is an ergonomic Scala REPL.
Scala-CLI
Scala-CLI is the primary CLI tool that
runs when you enter scala
in the terminal. It is able to compile, test, run,
and package your Scala code in a variety of different ways
Coursier
Coursier is a fast JVM dependency resolver, used in many build tools down resolve and download third party dependencies