diff --git a/.github/actions/post-build-selective/action.yml b/.github/actions/post-build-selective/action.yml index e90413e6d47..b9d7a05554a 100644 --- a/.github/actions/post-build-selective/action.yml +++ b/.github/actions/post-build-selective/action.yml @@ -21,6 +21,9 @@ runs: - uses: actions/setup-node@v4 with: { node-version: '22' } + - run: cat .mill-jvm-version + shell: ${{ inputs.shell }} + - run: ./mill -i -k selective.resolve ${{ inputs.millargs }} shell: ${{ inputs.shell }} diff --git a/.github/actions/pre-build-setup/action.yml b/.github/actions/pre-build-setup/action.yml index 52e332bdb5d..585dc24d21b 100644 --- a/.github/actions/pre-build-setup/action.yml +++ b/.github/actions/pre-build-setup/action.yml @@ -62,4 +62,7 @@ runs: name: ${{ inputs.os }}-selective-execution-artifact include-hidden-files: true - - uses: actions/checkout@v4 \ No newline at end of file + - uses: actions/checkout@v4 + + - run: echo temurin:${{ inputs.java-version }} > .mill-jvm-version + shell: bash \ No newline at end of file diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 1c1b9efd42d..117431e4498 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -32,6 +32,8 @@ name: Run Tests on: push: + branches-ignore: + - '**-patch-**' pull_request: types: - opened @@ -144,10 +146,13 @@ jobs: install-android-sdk: false - java-version: 17 - millargs: "example.kotlinlib.__.native.server.test" + millargs: "example.kotlinlib.__.local.server.test" install-android-sdk: false - - java-version: 17 + # Run this one using `.native` as a smoketest. Also make sure the java-version + # is the same as that used in the `build-linux` job to avoid diverging code + # hashes (https://github.com/com-lihaoyi/mill/pull/4410) + - java-version: 11 millargs: "example.scalalib.__.native.server.test" install-android-sdk: false diff --git a/.github/workflows/scala-steward.yml b/.github/workflows/scala-steward.yml index 358d4ecadbd..c4a69fcfafe 100644 --- a/.github/workflows/scala-steward.yml +++ b/.github/workflows/scala-steward.yml @@ -19,6 +19,6 @@ jobs: java-version: '17' distribution: 'temurin' - - uses: scala-steward-org/scala-steward-action@v2.72.0 + - uses: scala-steward-org/scala-steward-action@v2.75.0 with: mill-version: 0.12.1 diff --git a/blog/modules/ROOT/pages/1-java-compile.adoc b/blog/modules/ROOT/pages/1-java-compile.adoc index d73c2bedd63..67102e933ae 100644 --- a/blog/modules/ROOT/pages/1-java-compile.adoc +++ b/blog/modules/ROOT/pages/1-java-compile.adoc @@ -7,8 +7,6 @@ :revdate: 29 November 2024 _{author}, {revdate}_ -include::mill:ROOT:partial$gtag-config.adoc[] - Java compiles have the reputation for being slow, but that reputation does not match today's reality. Nowadays the Java compiler can compile "typical" Java code at over 100,000 lines a second on a single core. That means that even a million line project diff --git a/blog/modules/ROOT/pages/2-monorepo-build-tool.adoc b/blog/modules/ROOT/pages/2-monorepo-build-tool.adoc index f21a1f01b09..d04a5b22b18 100644 --- a/blog/modules/ROOT/pages/2-monorepo-build-tool.adoc +++ b/blog/modules/ROOT/pages/2-monorepo-build-tool.adoc @@ -7,7 +7,7 @@ :revdate: 17 December 2024 _{author}, {revdate}_ -include::mill:ROOT:partial$gtag-config.adoc[] + Software build tools mostly fall into two categories: diff --git a/blog/modules/ROOT/pages/3-selective-testing.adoc b/blog/modules/ROOT/pages/3-selective-testing.adoc index ca2499eb0a0..d859f067089 100644 --- a/blog/modules/ROOT/pages/3-selective-testing.adoc +++ b/blog/modules/ROOT/pages/3-selective-testing.adoc @@ -7,7 +7,7 @@ :revdate: 24 December 2024 _{author}, {revdate}_ -include::mill:ROOT:partial$gtag-config.adoc[] + Selective testing is a key technique necessary for working with any large codebase or monorepo: picking which tests to run to validate a change or pull-request, because diff --git a/blog/modules/ROOT/pages/4-flaky-tests.adoc b/blog/modules/ROOT/pages/4-flaky-tests.adoc index f603f17c579..2170e737308 100644 --- a/blog/modules/ROOT/pages/4-flaky-tests.adoc +++ b/blog/modules/ROOT/pages/4-flaky-tests.adoc @@ -7,7 +7,7 @@ :revdate: 1 January 2025 _{author}, {revdate}_ -include::mill:ROOT:partial$gtag-config.adoc[] + Many projects suffer from the problem of flaky tests: tests that pass or fail non-deterministically. These cause confusion, slow development cycles, and endless diff --git a/blog/modules/ROOT/pages/5-executable-jars.adoc b/blog/modules/ROOT/pages/5-executable-jars.adoc index 37c6d598287..ee9fcb924ec 100644 --- a/blog/modules/ROOT/pages/5-executable-jars.adoc +++ b/blog/modules/ROOT/pages/5-executable-jars.adoc @@ -7,7 +7,7 @@ :revdate: 2 January 2025 _{author}, {revdate}_ -include::mill:ROOT:partial$gtag-config.adoc[] + One feature of the https://mill-build.org[Mill JVM build tool] is that the assembly jars it creates are directly executable: diff --git a/blog/modules/ROOT/pages/6-garbage-collector-perf.adoc b/blog/modules/ROOT/pages/6-garbage-collector-perf.adoc index 559c0c43dc3..7a9648a428a 100644 --- a/blog/modules/ROOT/pages/6-garbage-collector-perf.adoc +++ b/blog/modules/ROOT/pages/6-garbage-collector-perf.adoc @@ -7,7 +7,7 @@ :revdate: 10 January 2025 _{author}, {revdate}_ -include::mill:ROOT:partial$gtag-config.adoc[] + Garbage collectors are a core part of many programming languages. While they generally work well, on occasion when they go wrong they can fail in very unintuitive ways. diff --git a/blog/modules/ROOT/pages/index.adoc b/blog/modules/ROOT/pages/index.adoc index 3ccfd313c6f..5ce71d8592f 100644 --- a/blog/modules/ROOT/pages/index.adoc +++ b/blog/modules/ROOT/pages/index.adoc @@ -1,6 +1,6 @@ # The Mill Build Engineering Blog -include::mill:ROOT:partial$gtag-config.adoc[] + Welcome to the Mill build engineering blog! This is the home for articles on diff --git a/bsp/src/mill/bsp/BSP.scala b/bsp/src/mill/bsp/BSP.scala index 0fae175698b..9752ba0347b 100644 --- a/bsp/src/mill/bsp/BSP.scala +++ b/bsp/src/mill/bsp/BSP.scala @@ -34,7 +34,7 @@ object BSP extends ExternalModule with CoursierModule { // we create a file containing the additional jars to load val libUrls = bspWorkerLibs().map(_.path.toNIO.toUri.toURL).iterator.toSeq val cpFile = - T.workspace / Constants.bspDir / s"${Constants.serverName}-${BuildInfo.millVersion}.resources" + Task.workspace / Constants.bspDir / s"${Constants.serverName}-${BuildInfo.millVersion}.resources" os.write.over( cpFile, libUrls.mkString("\n"), @@ -51,9 +51,9 @@ object BSP extends ExternalModule with CoursierModule { */ def startSession(allBootstrapEvaluators: Evaluator.AllBootstrapEvaluators) : Command[BspServerResult] = Task.Command { - T.log.errorStream.println("BSP/startSession: Starting BSP session") + Task.log.errorStream.println("BSP/startSession: Starting BSP session") val res = BspContext.bspServerHandle.runSession(allBootstrapEvaluators.value) - T.log.errorStream.println(s"BSP/startSession: Finished BSP session, result: ${res}") + Task.log.errorStream.println(s"BSP/startSession: Finished BSP session, result: ${res}") res } diff --git a/build.mill b/build.mill index 625819da0dd..edebba07bed 100644 --- a/build.mill +++ b/build.mill @@ -113,7 +113,7 @@ object Deps { Seq(Play_3_0, Play_2_9, Play_2_8, Play_2_7, Play_2_6).map(p => (p.playBinVersion, p)).toMap val acyclic = ivy"com.lihaoyi:::acyclic:0.3.15" - val ammoniteVersion = "3.0.0-2-6342755f" + val ammoniteVersion = "3.0.1" val asmTree = ivy"org.ow2.asm:asm-tree:9.7.1" val bloopConfig = ivy"ch.epfl.scala::bloop-config:1.5.5" @@ -201,7 +201,7 @@ object Deps { ivy"org.apache.maven.resolver:maven-resolver-transport-http:$mavenResolverVersion" val mavenResolverTransportWagon = ivy"org.apache.maven.resolver:maven-resolver-transport-wagon:$mavenResolverVersion" - val coursierJvmIndexVersion = "0.0.4-70-51469f" + val coursierJvmIndexVersion = "0.0.4-84-f852c6" val gradleApi = ivy"dev.gradleplugins:gradle-api:8.11.1" object RuntimeDeps { diff --git a/changelog.adoc b/changelog.adoc index 912868319e6..15968f3325a 100644 --- a/changelog.adoc +++ b/changelog.adoc @@ -9,6 +9,8 @@ endif::[] :link-milestone: {link-github}/milestone // find-replace-regex: https://github.com/com-lihaoyi/mill/pull/(\d*) -> {link-pr}/$1[#$1] +_The changelog below is for tagged, stable releases. For unstable releases, +see the list at https://repo1.maven.org/maven2/com/lihaoyi/mill-dist_ [#0-12-5] === 0.12.5 - 2025-01-01 diff --git a/contrib/artifactory/src/mill/contrib/artifactory/ArtifactoryPublishModule.scala b/contrib/artifactory/src/mill/contrib/artifactory/ArtifactoryPublishModule.scala index aa12ccec721..bce9455dd77 100644 --- a/contrib/artifactory/src/mill/contrib/artifactory/ArtifactoryPublishModule.scala +++ b/contrib/artifactory/src/mill/contrib/artifactory/ArtifactoryPublishModule.scala @@ -5,6 +5,7 @@ import mill.api.Result import scalalib._ import mill.contrib.artifactory.ArtifactoryPublishModule.checkArtifactoryCreds import mill.define.{ExternalModule, Task} +import mill.define.Command trait ArtifactoryPublishModule extends PublishModule { def artifactoryUri: String @@ -35,7 +36,7 @@ trait ArtifactoryPublishModule extends PublishModule { checkArtifactoryCreds(credentials)(), readTimeout, connectTimeout, - T.log + Task.log ).publish(artifacts.map { case (a, b) => (a.path, b) }, artifactInfo) } } @@ -59,9 +60,9 @@ object ArtifactoryPublishModule extends ExternalModule { publishArtifacts: mill.main.Tasks[PublishModule.PublishData], readTimeout: Int = 60000, connectTimeout: Int = 5000 - ) = Task.Command { + ): Command[Unit] = Task.Command { - val artifacts = T.sequence(publishArtifacts.value)().map { + val artifacts = Task.sequence(publishArtifacts.value)().map { case data @ PublishModule.PublishData(_, _) => data.withConcretePath } new ArtifactoryPublisher( @@ -70,7 +71,7 @@ object ArtifactoryPublishModule extends ExternalModule { checkArtifactoryCreds(credentials)(), readTimeout, connectTimeout, - T.log + Task.log ).publishAll( artifacts: _* ) @@ -79,8 +80,8 @@ object ArtifactoryPublishModule extends ExternalModule { private def checkArtifactoryCreds(credentials: String): Task[String] = Task.Anon { if (credentials.isEmpty) { (for { - username <- T.env.get("ARTIFACTORY_USERNAME") - password <- T.env.get("ARTIFACTORY_PASSWORD") + username <- Task.env.get("ARTIFACTORY_USERNAME") + password <- Task.env.get("ARTIFACTORY_PASSWORD") } yield { Result.Success(s"$username:$password") }).getOrElse( diff --git a/contrib/bintray/src/mill/contrib/bintray/BintrayPublishModule.scala b/contrib/bintray/src/mill/contrib/bintray/BintrayPublishModule.scala index bcd0448c21d..e29ae183935 100644 --- a/contrib/bintray/src/mill/contrib/bintray/BintrayPublishModule.scala +++ b/contrib/bintray/src/mill/contrib/bintray/BintrayPublishModule.scala @@ -5,6 +5,7 @@ import mill.api.Result import scalalib._ import mill.contrib.bintray.BintrayPublishModule.checkBintrayCreds import mill.define.{ExternalModule, Task} +import mill.define.Command trait BintrayPublishModule extends PublishModule { @@ -44,7 +45,7 @@ trait BintrayPublishModule extends PublishModule { release, readTimeout, connectTimeout, - T.log + Task.log ).publish(bintrayPublishArtifacts()) } } @@ -69,7 +70,7 @@ object BintrayPublishModule extends ExternalModule { publishArtifacts: mill.main.Tasks[BintrayPublishData], readTimeout: Int = 60000, connectTimeout: Int = 5000 - ) = Task.Command { + ): Command[Unit] = Task.Command { new BintrayPublisher( bintrayOwner, bintrayRepo, @@ -77,17 +78,17 @@ object BintrayPublishModule extends ExternalModule { release, readTimeout, connectTimeout, - T.log + Task.log ).publishAll( - T.sequence(publishArtifacts.value)(): _* + Task.sequence(publishArtifacts.value)(): _* ) } private def checkBintrayCreds(credentials: String): Task[String] = Task.Anon { if (credentials.isEmpty) { (for { - username <- T.env.get("BINTRAY_USERNAME") - password <- T.env.get("BINTRAY_PASSWORD") + username <- Task.env.get("BINTRAY_USERNAME") + password <- Task.env.get("BINTRAY_PASSWORD") } yield { Result.Success(s"$username:$password") }).getOrElse( diff --git a/contrib/bloop/src/mill/contrib/bloop/BloopImpl.scala b/contrib/bloop/src/mill/contrib/bloop/BloopImpl.scala index e58d97f7c36..2dcf81c7e5c 100644 --- a/contrib/bloop/src/mill/contrib/bloop/BloopImpl.scala +++ b/contrib/bloop/src/mill/contrib/bloop/BloopImpl.scala @@ -28,7 +28,7 @@ class BloopImpl(evs: () => Seq[Evaluator], wd: os.Path) extends ExternalModule { * under pwd/.bloop. */ def install() = Task.Command { - val res = T.traverse(computeModules)(_.bloop.writeConfigFile())() + val res = Task.traverse(computeModules)(_.bloop.writeConfigFile())() val written = res.map(_._2).map(_.path) // Make bloopDir if it doesn't exists if (!os.exists(bloopDir)) { @@ -91,7 +91,7 @@ class BloopImpl(evs: () => Seq[Evaluator], wd: os.Path) extends ExternalModule { os.makeDir.all(bloopDir) val path = bloopConfigPath(jm) _root_.bloop.config.write(config(), path.toNIO) - T.log.info(s"Wrote $path") + Task.log.info(s"Wrote $path") name(jm) -> PathRef(path) } @@ -139,7 +139,7 @@ class BloopImpl(evs: () => Seq[Evaluator], wd: os.Path) extends ExternalModule { * from module#sources in bloopInstall */ def moduleSourceMap = Task.Input { - val sources = T.traverse(computeModules) { m => + val sources = Task.traverse(computeModules) { m => m.allSources.map { paths => name(m) -> paths.map(_.path) } @@ -203,7 +203,7 @@ class BloopImpl(evs: () => Seq[Evaluator], wd: os.Path) extends ExternalModule { // ////////////////////////////////////////////////////////////////////////// val classpath = Task.Anon { - val transitiveCompileClasspath = T.traverse(module.transitiveModuleCompileModuleDeps)(m => + val transitiveCompileClasspath = Task.traverse(module.transitiveModuleCompileModuleDeps)(m => Task.Anon { m.localCompileClasspath().map(_.path) ++ Agg(classes(m)) } )().flatten @@ -273,7 +273,7 @@ class BloopImpl(evs: () => Seq[Evaluator], wd: os.Path) extends ExternalModule { Task.Anon { BloopConfig.Platform.Jvm( BloopConfig.JvmConfig( - home = T.env.get("JAVA_HOME").map(s => os.Path(s).toNIO), + home = Task.env.get("JAVA_HOME").map(s => os.Path(s).toNIO), options = { // See https://github.com/scalacenter/bloop/issues/1167 val forkArgs = module.forkArgs().toList diff --git a/contrib/buildinfo/src/mill/contrib/buildinfo/BuildInfo.scala b/contrib/buildinfo/src/mill/contrib/buildinfo/BuildInfo.scala index fbab5932054..01e4b4e4f2f 100644 --- a/contrib/buildinfo/src/mill/contrib/buildinfo/BuildInfo.scala +++ b/contrib/buildinfo/src/mill/contrib/buildinfo/BuildInfo.scala @@ -45,7 +45,7 @@ trait BuildInfo extends JavaModule { val subPath = os.SubPath(buildInfoPackageName.replace('.', '/')) val stream = os.write.outputStream( - T.dest / subPath / s"$buildInfoObjectName.buildinfo.properties", + Task.dest / subPath / s"$buildInfoObjectName.buildinfo.properties", createFolders = true ) @@ -54,7 +54,7 @@ trait BuildInfo extends JavaModule { s"mill.contrib.buildinfo.BuildInfo for ${buildInfoPackageName}.${buildInfoObjectName}" ) stream.close() - PathRef(T.dest) + PathRef(Task.dest) } private def isScala = this.isInstanceOf[ScalaModule] @@ -82,11 +82,11 @@ trait BuildInfo extends JavaModule { val ext = if (isScala) "scala" else "java" os.write( - T.dest / buildInfoPackageName.split('.') / s"${buildInfoObjectName}.$ext", + Task.dest / buildInfoPackageName.split('.') / s"${buildInfoObjectName}.$ext", code, createFolders = true ) - Seq(PathRef(T.dest)) + Seq(PathRef(Task.dest)) } } } diff --git a/contrib/codeartifact/src/mill/contrib/codeartifact/CodeartifactPublishModule.scala b/contrib/codeartifact/src/mill/contrib/codeartifact/CodeartifactPublishModule.scala index ff1b4d24739..25d4d378e59 100644 --- a/contrib/codeartifact/src/mill/contrib/codeartifact/CodeartifactPublishModule.scala +++ b/contrib/codeartifact/src/mill/contrib/codeartifact/CodeartifactPublishModule.scala @@ -27,7 +27,7 @@ trait CodeartifactPublishModule extends PublishModule { credentials, readTimeout, connectTimeout, - T.log + Task.log ).publish(artifacts.map { case (a, b) => (a.path, b) }, artifactInfo) } } @@ -42,7 +42,7 @@ object CodeartifactPublishModule extends ExternalModule { connectTimeout: Int = 5000 ) = Task.Command { - val artifacts = T.sequence(publishArtifacts.value)().map { + val artifacts = Task.sequence(publishArtifacts.value)().map { case data @ PublishModule.PublishData(_, _) => data.withConcretePath } new CodeartifactPublisher( @@ -51,7 +51,7 @@ object CodeartifactPublishModule extends ExternalModule { credentials, readTimeout, connectTimeout, - T.log + Task.log ).publishAll( artifacts: _* ) diff --git a/contrib/docker/src/mill/contrib/docker/DockerModule.scala b/contrib/docker/src/mill/contrib/docker/DockerModule.scala index 92131bc9f23..429a2c98a6a 100644 --- a/contrib/docker/src/mill/contrib/docker/DockerModule.scala +++ b/contrib/docker/src/mill/contrib/docker/DockerModule.scala @@ -73,7 +73,7 @@ trait DockerModule { outer: JavaModule => * [[https://docs.docker.com/engine/reference/commandline/cli/#environment-variables Environment variables]] * for more information. */ - def dockerEnv: T[Map[String, String]] = T.env + def dockerEnv: T[Map[String, String]] = Task.env /** * Commands to add as RUN instructions. @@ -161,7 +161,7 @@ trait DockerModule { outer: JavaModule => } final def build = Task { - val dest = T.dest + val dest = Task.dest val env = dockerEnv() val asmPath = outer.assembly().path @@ -169,7 +169,7 @@ trait DockerModule { outer: JavaModule => os.write(dest / "Dockerfile", dockerfile()) - val log = T.log + val log = Task.log val tagArgs = tags().flatMap(t => List("-t", t)) diff --git a/contrib/flyway/readme.adoc b/contrib/flyway/readme.adoc index 16dec14d4e5..3e932ad3d38 100644 --- a/contrib/flyway/readme.adoc +++ b/contrib/flyway/readme.adoc @@ -41,4 +41,4 @@ mill foo.flywayMigrate CAUTION: You should never hard-code credentials or check them into a version control system. You should write some code to populate the settings for flyway instead. -For example `def flywayPassword = Task.Input(T.ctx.env("FLYWAY_PASSWORD"))` +For example `def flywayPassword = Task.Input(Task.ctx.env("FLYWAY_PASSWORD"))` diff --git a/contrib/flyway/src/mill/contrib/flyway/FlywayModule.scala b/contrib/flyway/src/mill/contrib/flyway/FlywayModule.scala index 2b8c8c102e9..9bf5415510d 100644 --- a/contrib/flyway/src/mill/contrib/flyway/FlywayModule.scala +++ b/contrib/flyway/src/mill/contrib/flyway/FlywayModule.scala @@ -74,7 +74,7 @@ trait FlywayModule extends JavaModule { val out = s"""Schema version: ${currentSchemaVersion} |${MigrationInfoDumper.dumpToAsciiTable(info.all)}""".stripMargin - T.log.outputStream.println(out) + Task.log.outputStream.println(out) out } } diff --git a/contrib/gitlab/readme.adoc b/contrib/gitlab/readme.adoc index f245c0dc0fa..91741ebce82 100644 --- a/contrib/gitlab/readme.adoc +++ b/contrib/gitlab/readme.adoc @@ -55,7 +55,7 @@ personal access token, then deploy token and lastly ci job token. Default search . Workspace file `.gitlab/deploy-token` . Environment variable `CI_JOB_TOKEN` -Items 1-4 are *personal access tokens*, 5-8 *deploy tokens* and 9 is *job token*. Workspace in items 4 and 8 refers to directory where `build.mill` is (`T.workspace` in mill terms). +Items 1-4 are *personal access tokens*, 5-8 *deploy tokens* and 9 is *job token*. Workspace in items 4 and 8 refers to directory where `build.mill` is (`Task.workspace` in mill terms). Because contents of `$CI_JOB_TOKEN` is checked publishing should just work when run in Gitlab CI/CD pipeline. If you want something else than default lookup configuration can be overridden. There are different ways of configuring token resolving. @@ -131,7 +131,7 @@ override def gitlabHeaders( props: Map[String, String] // System properties ): Task[GitlabAuthHeaders] = Task.Anon { // This uses default lookup and ads custom headers - val access = tokenLookup.resolveGitlabToken(T.env, props, T.workspace) + val access = tokenLookup.resolveGitlabToken(Task.env, props, Task.workspace) val accessHeader = access.fold(_ => Seq.empty[(String, String)], _.headers) Success( GitlabAuthHeaders( diff --git a/contrib/gitlab/src/mill/contrib/gitlab/GitlabMavenRepository.scala b/contrib/gitlab/src/mill/contrib/gitlab/GitlabMavenRepository.scala index 786949f72ec..e6c7ac70660 100644 --- a/contrib/gitlab/src/mill/contrib/gitlab/GitlabMavenRepository.scala +++ b/contrib/gitlab/src/mill/contrib/gitlab/GitlabMavenRepository.scala @@ -2,7 +2,6 @@ package mill.contrib.gitlab import coursier.core.Authentication import coursier.maven.MavenRepository -import mill.T import mill.api.Result import mill.api.Result.{Failure, Success} import mill.define.Task @@ -14,7 +13,7 @@ trait GitlabMavenRepository { def mavenRepository: Task[MavenRepository] = Task.Anon { - val gitlabAuth = tokenLookup.resolveGitlabToken(T.env, sys.props.toMap, T.workspace) + val gitlabAuth = tokenLookup.resolveGitlabToken(Task.env, sys.props.toMap, Task.workspace) .map(auth => Authentication(auth.headers)) .map(auth => MavenRepository(gitlabRepository.url(), Some(auth))) diff --git a/contrib/gitlab/src/mill/contrib/gitlab/GitlabPublishModule.scala b/contrib/gitlab/src/mill/contrib/gitlab/GitlabPublishModule.scala index fd72f1b6d2a..88a301ab818 100644 --- a/contrib/gitlab/src/mill/contrib/gitlab/GitlabPublishModule.scala +++ b/contrib/gitlab/src/mill/contrib/gitlab/GitlabPublishModule.scala @@ -17,7 +17,7 @@ trait GitlabPublishModule extends PublishModule { outer => def gitlabHeaders( systemProps: Map[String, String] = sys.props.toMap ): Task[GitlabAuthHeaders] = Task.Anon { - val auth = tokenLookup.resolveGitlabToken(T.env, systemProps, T.workspace) + val auth = tokenLookup.resolveGitlabToken(Task.env, systemProps, Task.workspace) auth match { case Left(msg) => Failure( @@ -36,13 +36,13 @@ trait GitlabPublishModule extends PublishModule { outer => val PublishModule.PublishData(artifactInfo, artifacts) = publishArtifacts() if (skipPublish) { - T.log.info(s"SkipPublish = true, skipping publishing of $artifactInfo") + Task.log.info(s"SkipPublish = true, skipping publishing of $artifactInfo") } else { val uploader = new GitlabUploader(gitlabHeaders()(), readTimeout, connectTimeout) new GitlabPublisher( uploader.upload, gitlabRepo, - T.log + Task.log ).publish(artifacts.map { case (a, b) => (a.path, b) }, artifactInfo) } @@ -62,7 +62,7 @@ object GitlabPublishModule extends ExternalModule { val repo = ProjectRepository(gitlabRoot, projectId) val auth = GitlabAuthHeaders.privateToken(personalToken) - val artifacts = T.sequence(publishArtifacts.value)().map { + val artifacts = Task.sequence(publishArtifacts.value)().map { case data @ PublishModule.PublishData(_, _) => data.withConcretePath } val uploader = new GitlabUploader(auth, readTimeout, connectTimeout) @@ -70,7 +70,7 @@ object GitlabPublishModule extends ExternalModule { new GitlabPublisher( uploader.upload, repo, - T.log + Task.log ).publishAll( artifacts: _* ) diff --git a/contrib/jmh/src/mill/contrib/jmh/JmhModule.scala b/contrib/jmh/src/mill/contrib/jmh/JmhModule.scala index d32ee5e6b09..1ac56b6769b 100644 --- a/contrib/jmh/src/mill/contrib/jmh/JmhModule.scala +++ b/contrib/jmh/src/mill/contrib/jmh/JmhModule.scala @@ -43,7 +43,7 @@ trait JmhModule extends JavaModule { classPath = (runClasspath() ++ generatorDeps()).map(_.path) ++ Seq(compileGeneratedSources().path, resources), mainArgs = args, - workingDir = T.ctx().dest, + workingDir = Task.ctx().dest, javaHome = zincWorker().javaHome().map(_.path) ) } @@ -52,7 +52,7 @@ trait JmhModule extends JavaModule { def compileGeneratedSources = Task { - val dest = T.ctx().dest + val dest = Task.ctx().dest val (sourcesDir, _) = generateBenchmarkSources() val sources = os.walk(sourcesDir).filter(os.isFile) @@ -72,7 +72,7 @@ trait JmhModule extends JavaModule { // returns sources and resources directories def generateBenchmarkSources = Task { - val dest = T.ctx().dest + val dest = Task.ctx().dest val forkedArgs = forkArgs().toSeq val sourcesDir = dest / "jmh_sources" val resourcesDir = dest / "jmh_resources" diff --git a/contrib/package.mill b/contrib/package.mill index 6c5251489c1..07639acd405 100644 --- a/contrib/package.mill +++ b/contrib/package.mill @@ -26,7 +26,7 @@ object `package` extends RootModule { millInternal.modules.collect { case m: ContribModule => m } trait ContribModule extends build.MillPublishScalaModule { - def readme = T.source(millSourcePath / "readme.adoc") + def readme = Task.Source(millSourcePath / "readme.adoc") } object testng extends JavaModule with ContribModule { @@ -59,7 +59,7 @@ object `package` extends RootModule { def compileModuleDeps = Seq(build.scalalib) def testTransitiveDeps = - super.testTransitiveDeps() ++ T.traverse(build.Deps.play.keys.toSeq)(worker(_).testDep)() + super.testTransitiveDeps() ++ Task.traverse(build.Deps.play.keys.toSeq)(worker(_).testDep)() def testArgs = Task { super.testArgs() ++ @@ -81,7 +81,7 @@ object `package` extends RootModule { def playBinary = crossValue def millSourcePath: os.Path = super.millSourcePath / playBinary - def sources = T.sources { + def sources = Task.Sources { // We want to avoid duplicating code as long as the Play APIs allow. // But if newer Play versions introduce incompatibilities, // just remove the shared source dir for that worker and implement directly. diff --git a/contrib/playlib/src/mill/playlib/RouteCompilerWorker.scala b/contrib/playlib/src/mill/playlib/RouteCompilerWorker.scala index a093a2aa5db..7fce25e62ff 100644 --- a/contrib/playlib/src/mill/playlib/RouteCompilerWorker.scala +++ b/contrib/playlib/src/mill/playlib/RouteCompilerWorker.scala @@ -3,7 +3,7 @@ package mill.playlib import mill.api.{Ctx, PathRef, Result} import mill.playlib.api.{RouteCompilerType, RouteCompilerWorkerApi} import mill.scalalib.api.CompilationResult -import mill.{Agg, T} +import mill.{Agg, Task} private[playlib] class RouteCompilerWorker extends AutoCloseable { @@ -58,7 +58,7 @@ private[playlib] class RouteCompilerWorker extends AutoCloseable { dest.toIO ) match { case null => - Result.Success(CompilationResult(T.dest / "zinc", PathRef(T.dest))) + Result.Success(CompilationResult(Task.dest / "zinc", PathRef(Task.dest))) case err => Result.Failure(err) } } diff --git a/contrib/playlib/src/mill/playlib/RouterModule.scala b/contrib/playlib/src/mill/playlib/RouterModule.scala index 11b921257b5..a5f8c62af70 100644 --- a/contrib/playlib/src/mill/playlib/RouterModule.scala +++ b/contrib/playlib/src/mill/playlib/RouterModule.scala @@ -61,7 +61,7 @@ trait RouterModule extends ScalaModule with Version { protected val routeCompilerWorker: RouteCompilerWorkerModule = RouteCompilerWorkerModule def compileRouter: T[CompilationResult] = Task(persistent = true) { - T.log.debug(s"compiling play routes with ${playVersion()} worker") + Task.log.debug(s"compiling play routes with ${playVersion()} worker") routeCompilerWorker.routeCompilerWorker().compile( routerClasspath = playRouterToolsClasspath(), files = routeFiles().map(_.path), @@ -70,7 +70,7 @@ trait RouterModule extends ScalaModule with Version { reverseRouter = generateReverseRouter, namespaceReverseRouter = namespaceReverseRouter, generatorType = generatorType, - dest = T.dest + dest = Task.dest ) } diff --git a/contrib/playlib/src/mill/playlib/Static.scala b/contrib/playlib/src/mill/playlib/Static.scala index 310740ee333..b1ba403c8af 100644 --- a/contrib/playlib/src/mill/playlib/Static.scala +++ b/contrib/playlib/src/mill/playlib/Static.scala @@ -6,7 +6,7 @@ import java.nio.file.attribute.BasicFileAttributes import java.util import mill.scalalib.{Lib, ScalaModule} -import mill.{PathRef, T, Task} +import mill.{PathRef, Task} trait Static extends ScalaModule { @@ -31,7 +31,7 @@ trait Static extends ScalaModule { Collected static assets for the project */ def staticAssets = Task { - val toPath = os.Path(assetsPath(), T.dest) + val toPath = os.Path(assetsPath(), Task.dest) assetSources().foreach { pathRef => val fromPath = pathRef.path if (os.isDir(fromPath)) { @@ -40,7 +40,7 @@ trait Static extends ScalaModule { } } } - PathRef(T.dest) + PathRef(Task.dest) } /** @@ -66,8 +66,8 @@ trait Static extends ScalaModule { * webjar resources extracted from their source jars with version from path removed */ def webJarResources = Task { - extractWebJars(webJars().toSeq, os.Path(assetsPath(), T.dest) / "lib") - PathRef(T.dest) + extractWebJars(webJars().toSeq, os.Path(assetsPath(), Task.dest) / "lib") + PathRef(Task.dest) } private def extractWebJars(jars: Seq[PathRef], webJarBase: os.Path): Unit = { diff --git a/contrib/proguard/src/mill/contrib/proguard/Proguard.scala b/contrib/proguard/src/mill/contrib/proguard/Proguard.scala index 597a56b6f95..744faa3e758 100644 --- a/contrib/proguard/src/mill/contrib/proguard/Proguard.scala +++ b/contrib/proguard/src/mill/contrib/proguard/Proguard.scala @@ -23,7 +23,7 @@ trait Proguard extends ScalaModule { * https://mvnrepository.com/artifact/com.guardsquare/proguard-base */ def proguardVersion: T[String] = Task { - T.log.error( + Task.log.error( "Using default proguard version is deprecated. Please override target proguardVersion to specify the version." ) "7.2.2" @@ -65,7 +65,7 @@ trait Proguard extends ScalaModule { * Keep in sync with [[javaHome]]. */ def java9RtJar: T[Seq[PathRef]] = Task { - if (mill.main.client.Util.isJava9OrAbove) Seq(PathRef(T.home / Export.rtJarName)) + if (mill.main.client.Util.isJava9OrAbove) Seq(PathRef(Task.home / Export.rtJarName)) else Seq() } @@ -87,7 +87,7 @@ trait Proguard extends ScalaModule { * The output jar is written to `dest/our.jar`. */ def proguard: T[PathRef] = Task { - val outJar = T.dest / "out.jar" + val outJar = Task.dest / "out.jar" val args = Seq[Shellable]( steps(), @@ -104,18 +104,18 @@ trait Proguard extends ScalaModule { additionalOptions() ).flatMap(_.value) - T.log.debug(s"Running: ${args.mkString(" ")}") -// T.log.debug(s"stdout: ${T.dest / "stdout.txt"}") -// T.log.debug(s"stderr: ${T.dest / "stderr.txt"}") + Task.log.debug(s"Running: ${args.mkString(" ")}") +// Task.log.debug(s"stdout: ${Task.dest / "stdout.txt"}") +// Task.log.debug(s"stderr: ${Task.dest / "stderr.txt"}") -// val result = os.proc(cmd).call(stdout = T.dest / "stdout.txt", stderr = T.dest / "stderr.txt") -// T.log.debug(s"result: ${result}") +// val result = os.proc(cmd).call(stdout = Task.dest / "stdout.txt", stderr = Task.dest / "stderr.txt") +// Task.log.debug(s"result: ${result}") Jvm.runSubprocess( mainClass = "proguard.ProGuard", classPath = proguardClasspath().map(_.path), mainArgs = args, - workingDir = T.dest + workingDir = Task.dest ) // the call above already throws an exception on a non-zero exit code, @@ -160,7 +160,7 @@ trait Proguard extends ScalaModule { * These are fed as-is to the proguard command. */ def additionalOptions: T[Seq[String]] = Task { - T.log.error( + Task.log.error( "Proguard is set to not warn about message: can't find referenced method 'void invoke()' in library class java.lang.invoke.MethodHandle" ) Seq[String]("-dontwarn java.lang.invoke.MethodHandle") diff --git a/contrib/scalapblib/src/mill/contrib/scalapblib/ScalaPBModule.scala b/contrib/scalapblib/src/mill/contrib/scalapblib/ScalaPBModule.scala index bf93e78909c..a88655a6df6 100644 --- a/contrib/scalapblib/src/mill/contrib/scalapblib/ScalaPBModule.scala +++ b/contrib/scalapblib/src/mill/contrib/scalapblib/ScalaPBModule.scala @@ -34,7 +34,7 @@ trait ScalaPBModule extends ScalaModule { /** ScalaPB enables lenses by default, this option allows you to disable it. */ def scalaPBLenses: T[Boolean] = Task { true } - def scalaPBScala3Sources: T[Boolean] = T { false } + def scalaPBScala3Sources: T[Boolean] = Task { false } def scalaPBSearchDeps: Boolean = false @@ -85,8 +85,10 @@ trait ScalaPBModule extends ScalaModule { def scalaPBIncludePath: T[Seq[PathRef]] = Task.Sources { Seq.empty[PathRef] } - private def scalaDepsPBIncludePath = if (scalaPBSearchDeps) Task { Seq(scalaPBUnpackProto()) } - else Task { Seq.empty[PathRef] } + private def scalaDepsPBIncludePath: Task[Seq[PathRef]] = scalaPBSearchDeps match { + case true => Task.Anon { Seq(scalaPBUnpackProto()) } + case false => Task.Anon { Seq.empty[PathRef] } + } def scalaPBProtoClasspath: T[Agg[PathRef]] = Task { defaultResolver().resolveDeps( @@ -99,7 +101,7 @@ trait ScalaPBModule extends ScalaModule { def scalaPBUnpackProto: T[PathRef] = Task { val cp = scalaPBProtoClasspath() - val dest = T.dest + val dest = Task.dest cp.iterator.foreach { ref => Using(new ZipInputStream(ref.path.getInputStream)) { zip => while ({ @@ -109,7 +111,7 @@ trait ScalaPBModule extends ScalaModule { if (entry.getName.endsWith(".proto")) { val protoDest = dest / os.SubPath(entry.getName) if (os.exists(protoDest)) - T.log.error(s"Warning: Overwriting ${dest} / ${os.SubPath(entry.getName)} ...") + Task.log.error(s"Warning: Overwriting ${dest} / ${os.SubPath(entry.getName)} ...") Using.resource(os.write.over.outputStream(protoDest, createFolders = true)) { os => IO.stream(zip, os) } @@ -140,7 +142,7 @@ trait ScalaPBModule extends ScalaModule { scalaPBClasspath(), scalaPBSources().map(_.path), scalaPBOptions(), - T.dest, + Task.dest, scalaPBCompileOptions() ) } diff --git a/contrib/scoverage/src/mill/contrib/scoverage/ScoverageModule.scala b/contrib/scoverage/src/mill/contrib/scoverage/ScoverageModule.scala index 750a953d334..0c754673e07 100644 --- a/contrib/scoverage/src/mill/contrib/scoverage/ScoverageModule.scala +++ b/contrib/scoverage/src/mill/contrib/scoverage/ScoverageModule.scala @@ -138,7 +138,7 @@ trait ScoverageModule extends ScalaModule { outer: ScalaModule => ScoverageReportWorker .scoverageReportWorker() .bridge(scoverageToolsClasspath()) - .report(reportType, allSources().map(_.path), Seq(data().path), T.workspace) + .report(reportType, allSources().map(_.path), Seq(data().path), Task.workspace) } /** @@ -147,7 +147,7 @@ trait ScoverageModule extends ScalaModule { outer: ScalaModule => */ def data: T[PathRef] = Task(persistent = true) { // via the persistent target, we ensure, the dest dir doesn't get cleared - PathRef(T.dest) + PathRef(Task.dest) } override def compileResources: T[Seq[PathRef]] = outer.compileResources @@ -177,12 +177,12 @@ trait ScoverageModule extends ScalaModule { outer: ScalaModule => if (isScala3()) { Seq( s"-coverage-out:${data().path.toIO.getPath()}", - s"-sourceroot:${T.workspace}" + s"-sourceroot:${Task.workspace}" ) } else { Seq( s"-P:scoverage:dataDir:${data().path.toIO.getPath()}", - s"-P:scoverage:sourceRoot:${T.workspace}" + s"-P:scoverage:sourceRoot:${Task.workspace}" ) } diff --git a/contrib/scoverage/src/mill/contrib/scoverage/ScoverageReport.scala b/contrib/scoverage/src/mill/contrib/scoverage/ScoverageReport.scala index e7c6ed5670f..4aac79e41e2 100644 --- a/contrib/scoverage/src/mill/contrib/scoverage/ScoverageReport.scala +++ b/contrib/scoverage/src/mill/contrib/scoverage/ScoverageReport.scala @@ -108,13 +108,13 @@ trait ScoverageReport extends Module { } Task.Anon { - val sourcePaths: Seq[Path] = T.sequence(sourcesTasks)().flatten.map(_.path) - val dataPaths: Seq[Path] = T.sequence(dataTasks)().map(_.path) + val sourcePaths: Seq[Path] = Task.sequence(sourcesTasks)().flatten.map(_.path) + val dataPaths: Seq[Path] = Task.sequence(dataTasks)().map(_.path) scoverageReportWorkerModule .scoverageReportWorker() .bridge(workerModule.scoverageToolsClasspath()) - .report(reportType, sourcePaths, dataPaths, T.workspace) - PathRef(T.dest) + .report(reportType, sourcePaths, dataPaths, Task.workspace) + PathRef(Task.dest) } } } diff --git a/contrib/sonatypecentral/src/mill/contrib/sonatypecentral/SonatypeCentralPublishModule.scala b/contrib/sonatypecentral/src/mill/contrib/sonatypecentral/SonatypeCentralPublishModule.scala index fd5fc26f386..884fc5f3de9 100644 --- a/contrib/sonatypecentral/src/mill/contrib/sonatypecentral/SonatypeCentralPublishModule.scala +++ b/contrib/sonatypecentral/src/mill/contrib/sonatypecentral/SonatypeCentralPublishModule.scala @@ -21,7 +21,7 @@ import mill.scalalib.publish.SonatypeHelpers.{ trait SonatypeCentralPublishModule extends PublishModule { def sonatypeCentralGpgArgs: T[String] = Task { - PublishModule.defaultGpgArgsForPassphrase(T.env.get("MILL_PGP_PASSPHRASE")).mkString(",") + PublishModule.defaultGpgArgsForPassphrase(Task.env.get("MILL_PGP_PASSPHRASE")).mkString(",") } def sonatypeCentralConnectTimeout: T[Int] = Task { defaultConnectTimeout } @@ -41,15 +41,15 @@ trait SonatypeCentralPublishModule extends PublishModule { val fileMapping = publishData.withConcretePath._1 val artifact = publishData.meta val finalCredentials = getSonatypeCredentials(username, password)() - PublishModule.pgpImportSecretIfProvided(T.env) + PublishModule.pgpImportSecretIfProvided(Task.env) val publisher = new SonatypeCentralPublisher( credentials = finalCredentials, gpgArgs = sonatypeCentralGpgArgs().split(",").toIndexedSeq, connectTimeout = sonatypeCentralConnectTimeout(), readTimeout = sonatypeCentralReadTimeout(), - log = T.log, - workspace = T.workspace, - env = T.env, + log = Task.log, + workspace = Task.workspace, + env = Task.env, awaitTimeout = sonatypeCentralAwaitTimeout() ) publisher.publish( @@ -81,24 +81,24 @@ object SonatypeCentralPublishModule extends ExternalModule { ): Command[Unit] = Task.Command { val artifacts: Seq[(Seq[(os.Path, String)], Artifact)] = - T.sequence(publishArtifacts.value)().map { + Task.sequence(publishArtifacts.value)().map { case data @ PublishModule.PublishData(_, _) => data.withConcretePath } val finalBundleName = if (bundleName.isEmpty) None else Some(bundleName) val finalCredentials = getSonatypeCredentials(username, password)() - PublishModule.pgpImportSecretIfProvided(T.env) + PublishModule.pgpImportSecretIfProvided(Task.env) val publisher = new SonatypeCentralPublisher( credentials = finalCredentials, gpgArgs = gpgArgs match { - case "" => PublishModule.defaultGpgArgsForPassphrase(T.env.get("MILL_PGP_PASSPHRASE")) + case "" => PublishModule.defaultGpgArgsForPassphrase(Task.env.get("MILL_PGP_PASSPHRASE")) case gpgArgs => gpgArgs.split(",").toIndexedSeq }, connectTimeout = connectTimeout, readTimeout = readTimeout, - log = T.log, - workspace = T.workspace, - env = T.env, + log = Task.log, + workspace = Task.workspace, + env = Task.env, awaitTimeout = awaitTimeout ) publisher.publishAll( @@ -125,7 +125,7 @@ object SonatypeCentralPublishModule extends ExternalModule { Result.Success(credentialParameterValue) } else { (for { - credential <- T.env.get(envVariableName) + credential <- Task.env.get(envVariableName) } yield { Result.Success(credential) }).getOrElse( diff --git a/contrib/twirllib/src/mill/twirllib/TwirlModule.scala b/contrib/twirllib/src/mill/twirllib/TwirlModule.scala index 0c3269e78c2..864a763ea8d 100644 --- a/contrib/twirllib/src/mill/twirllib/TwirlModule.scala +++ b/contrib/twirllib/src/mill/twirllib/TwirlModule.scala @@ -93,7 +93,7 @@ trait TwirlModule extends mill.Module { twirlModule => .compile( twirlClasspath(), twirlSources().map(_.path), - T.dest, + Task.dest, twirlImports(), twirlFormats(), twirlConstructorAnnotations, diff --git a/contrib/versionfile/src/mill/contrib/versionfile/VersionFileModule.scala b/contrib/versionfile/src/mill/contrib/versionfile/VersionFileModule.scala index e7f95fbd55a..c113b2e21a9 100644 --- a/contrib/versionfile/src/mill/contrib/versionfile/VersionFileModule.scala +++ b/contrib/versionfile/src/mill/contrib/versionfile/VersionFileModule.scala @@ -33,7 +33,7 @@ trait VersionFileModule extends Module { } protected def setVersionTask(version: Task[Version]) = Task.Anon { - T.log.info(generateCommitMessage(version())) + Task.log.info(generateCommitMessage(version())) writeVersionToFile(versionFile(), version()) } @@ -85,7 +85,7 @@ object VersionFileModule extends define.ExternalModule { /** Executes the given processes. */ def exec(procs: mill.main.Tasks[Seq[os.proc]]) = Task.Command { for { - procs <- T.sequence(procs.value)() + procs <- Task.sequence(procs.value)() proc <- procs } yield proc.call() } diff --git a/dist/package.mill b/dist/package.mill index f7fcbca930c..f226bfe7999 100644 --- a/dist/package.mill +++ b/dist/package.mill @@ -284,14 +284,14 @@ object `package` extends RootModule with InstallModule { } object native extends mill.scalalib.NativeImageModule with InstallModule { - def artifactOsSuffix = T { + def artifactOsSuffix = Task { val osName = System.getProperty("os.name").toLowerCase if (osName.contains("mac")) "mac" else if (osName.contains("windows")) "windows" else "linux" } - def artifactCpuSuffix = T { + def artifactCpuSuffix = Task { System.getProperty("os.arch") match { case "x86_64" => "amd64" case s => s diff --git a/docs/modules/ROOT/images/index/iconscout-python.svg b/docs/modules/ROOT/images/index/iconscout-python.svg new file mode 100644 index 00000000000..2965f75b4ba --- /dev/null +++ b/docs/modules/ROOT/images/index/iconscout-python.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc index 93400c58e48..ec9156fa191 100644 --- a/docs/modules/ROOT/nav.adoc +++ b/docs/modules/ROOT/nav.adoc @@ -28,23 +28,23 @@ ** xref:kotlinlib/publishing.adoc[] // ** xref:kotlinlib/build-examples.adoc[] ** xref:kotlinlib/web-examples.adoc[] +* xref:pythonlib/intro.adoc[] +** xref:pythonlib/module-config.adoc[] +** xref:pythonlib/dependencies.adoc[] +** xref:pythonlib/testing.adoc[] +** xref:pythonlib/publishing.adoc[] +** xref:pythonlib/web-examples.adoc[] * Experimental Platform Support ** Building Android Apps *** xref:android/java.adoc[] *** xref:android/kotlin.adoc[] *** xref:android/android-linting.adoc[] -** xref:pythonlib/intro.adoc[] -*** xref:pythonlib/module-config.adoc[] -*** xref:pythonlib/dependencies.adoc[] -*** xref:pythonlib/linting.adoc[] -*** xref:pythonlib/publishing.adoc[] -*** xref:pythonlib/web-examples.adoc[] -*** xref:pythonlib/testing.adoc[] ** xref:javascriptlib/intro.adoc[] *** xref:javascriptlib/dependencies.adoc[] *** xref:javascriptlib/module-config.adoc[] *** xref:javascriptlib/testing.adoc[] *** xref:javascriptlib/publishing.adoc[] +*** xref:javascriptlib/linting.adoc[] * xref:comparisons/why-mill.adoc[] ** xref:comparisons/maven.adoc[] ** xref:comparisons/gradle.adoc[] @@ -120,4 +120,5 @@ // *somewhere*. * Reference ** {mill-doc-url}/api/latest/mill/index.html[Mill Scaladoc] -** xref:reference/changelog.adoc[] +** {mill-github-url}/blob/main/changelog.adoc[Changelog] +** xref:reference/talks-blog-posts.adoc[]] diff --git a/docs/modules/ROOT/pages/android/android-linting.adoc b/docs/modules/ROOT/pages/android/android-linting.adoc index d4ff2f35056..292871b5805 100644 --- a/docs/modules/ROOT/pages/android/android-linting.adoc +++ b/docs/modules/ROOT/pages/android/android-linting.adoc @@ -1,7 +1,7 @@ = Linting Android Projects :page-aliases: Linting_Android_Projects.adoc -include::partial$gtag-config.adoc[] + This page covers essential practices for maintaining and enforcing code quality in Android projects using the Mill build tool. Proper linting helps detect diff --git a/docs/modules/ROOT/pages/android/java.adoc b/docs/modules/ROOT/pages/android/java.adoc index 9eceb94a082..38af5891af5 100644 --- a/docs/modules/ROOT/pages/android/java.adoc +++ b/docs/modules/ROOT/pages/android/java.adoc @@ -1,7 +1,7 @@ = Android Java Projects :page-aliases: android_app_examples.adoc -include::partial$gtag-config.adoc[] + This page provides an example of using Mill as a build tool for Android applications. This workflow is still pretty rough and nowhere near production ready, but can serve as diff --git a/docs/modules/ROOT/pages/android/kotlin.adoc b/docs/modules/ROOT/pages/android/kotlin.adoc index 64dc36270db..3b62f3748b8 100644 --- a/docs/modules/ROOT/pages/android/kotlin.adoc +++ b/docs/modules/ROOT/pages/android/kotlin.adoc @@ -1,7 +1,7 @@ = Android Kotlin Projects :page-aliases: android_app_kotlin_examples.adoc -include::partial$gtag-config.adoc[] + This page provides an example of using Mill as a build tool for Android applications. This workflow is still pretty rough and nowhere near production ready, but can serve as diff --git a/docs/modules/ROOT/pages/cli/builtin-commands.adoc b/docs/modules/ROOT/pages/cli/builtin-commands.adoc index 577748c5963..fc4a2420d3d 100644 --- a/docs/modules/ROOT/pages/cli/builtin-commands.adoc +++ b/docs/modules/ROOT/pages/cli/builtin-commands.adoc @@ -1,7 +1,7 @@ = Built-in Commands :page-aliases: Scala_Builtin_Commands.adoc, -include::partial$gtag-config.adoc[] + :language: Scala :language-small: scala diff --git a/docs/modules/ROOT/pages/cli/installation-ide.adoc b/docs/modules/ROOT/pages/cli/installation-ide.adoc index d85474310b4..900084cb92d 100644 --- a/docs/modules/ROOT/pages/cli/installation-ide.adoc +++ b/docs/modules/ROOT/pages/cli/installation-ide.adoc @@ -14,8 +14,8 @@ globally. [#_bootstrap_scripts] == Bootstrap Scripts -Although the Mill example projects come with their own `./mill` and `./mill.bat` bootstrap script, -you can also download it manually: +The Mill example projects in this documentation come with `./mill` and `./mill.bat` +bootstrap script, included. You can also download the boostrap script manually: [source,bash,subs="verbatim,attributes"] ---- @@ -58,7 +58,7 @@ pick one most similar to what you are doing so you can hit the ground running wo The default Mill executable configured above requires a JVM (11 or above) installed globally in order to run, and imposes some Java startup overhead (100-200ms) when running Mill from the -command line.You can also use Mill's native executables by appending a `-native` suffix to the +command line. You can also use Mill's native executables by appending a `-native` suffix to the Mill version: [source,bash,subs="verbatim,attributes"] @@ -67,27 +67,41 @@ echo {mill-last-tag}-native > .mill-version ---- Using the `-native` suffix should provide a faster CLI experience than using Mill's default -JVM launcher. Mill native executables are supported on the following OS/CPU combinations: +JVM launcher, and makes it easier to install Mill in environments without a JVM pre-installed. -- `windows-amd64` (Intel Windows) -- `linux-amd64` (Intel Linux) -- `mac-aarch64` (M1-M4 Mac) -If you are on a combination not supported by Mill's native executables, use the default +Mill native executables are supported on the following OS/CPU combinations: + +|=== +| | Windows | Mac | Linux +| Intel | Y | Y | Y +| ARM | | Y | Y +|=== + +Notably, Mill native executables _do not_ support Windows-ARM, due to limitations in the +upstream Graal Native Image tooling (see https://github.com/oracle/graal/issues/9215[oracle/graal#9215]). +If you are on a platform not supported by Mill's native executables, use the default JVM launcher instead. === Customizing Mill's JVM -To use Mill in environments without a JVM installed, the native launcher can download its -own JVM as necessary. You need to specify the version you want via a `.mill-jvm-version` -file such as: +Mill allows you to specify the exact JVM version you want to use to run the build tool +via a `.mill-jvm-version` file such as: ```bash echo temurin:17.0.6 > .mill-jvm-version ``` -`.mill-jvm-version` can also be used with Mill's default JVM launcher, if you want -your Mill process to use a different JVM than what you have installed globally. +This has two benefits + +* `.mill-jvm-version` can also be used with Mill's default JVM launcher if you want +your Mill process to use a different JVM than what you have installed globally. This +can help ensure your project uses a consistent JVM version and behaves identically regardless +of what the developer may have installed on their laptop or dev environment + +* `.mill-jvm-version` can be used together with <>s to build your +project without needing a JVM pre-installed at all. This simplifies project setup and +onboarding of new developers. == IDE Support @@ -97,12 +111,7 @@ your Mill process to use a different JVM than what you have installed globally. Mill supports IntelliJ and VSCode and in general any client of the standard https://build-server-protocol.github.io/[Build Server Protocol (BSP)]. -To prepare your project for IDEs, and in general any BSP client, you can run this command to generate the BSP configuration files: -[source,bash] ----- -./mill mill.bsp.BSP/install ----- Your IDEs may already auto-detect the Mill project and run this command on behalf of you, when opening/importing the project. @@ -111,7 +120,7 @@ Your IDEs may already auto-detect the Mill project and run this command on behal To use Mill with IntelliJ, first ensure you have the free https://plugins.jetbrains.com/plugin/1347-scala[IntelliJ Scala Plugin] installed. This is necessary as Mill build files are written in Scala, -even if you are using it to build a Java or Kotlin project. +even if you are using it to build a Java or Kotlin or Python project. Once you have the plugin installed, you can use IntelliJ to open any project containing a Mill `build.mill` file, and IntelliJ will automatically load the @@ -139,6 +148,14 @@ those updates by opening the "BSP" tab and clicking the "Refresh" button image::basic/IntellijRefresh.png[] +To prepare your project for IDEs, and in general any BSP client, you can also +run this command to generate the BSP configuration files: + +[source,bash] +---- +./mill mill.bsp.BSP/install +---- + ==== IntelliJ IDEA XML Support Apart from using the Build Server Protocol, you can also generate IDEA project @@ -235,7 +252,7 @@ MILL_VERSION=0.5.0-3-4faefb ./mill __.compile to override the Mill version manually. This takes precedence over the version specified in `./mill`, `.config/mill-version` or `.mill-version` -== Working without access to Maven Central +== Using Mill without access to Maven Central Under some circumstances (e.g. corporate firewalls), you may not have access maven central. The typical symptom will be error messages which look like this; @@ -251,19 +268,21 @@ Resolution failed for 1 modules: ---- It is expected that basic commands (e.g. clean) will not work, as Mill saying it is -unable to resolve it's own, fundamental, dependencies. Under such circumstances, you +unable to resolve it's own, fundamental, dependencies from the default Maven Central +JVM package repository. Under such circumstances, you will normally have access to some proxy, or other corporate repository which resolves maven artifacts. The strategy is simply to tell mill to use that instead. -The idea is to set an environment variable COURSIER_REPOSITORIES (see coursier docs). +To resolve this, you can set an environment variable COURSIER_REPOSITORIES (see coursier docs) +to point at your own server that mirrors the Maven Central artifacts. The below command should pass the environment variable to the `mill` command. ---- - COURSIER_REPOSITORIES=https://packages.corp.com/artifactory/maven/ mill resolve _ +COURSIER_REPOSITORIES=https://packages.corp.com/artifactory/maven/ mill resolve _ ---- If you are using bootstrap script, a more permanent solution could be to set the environment variable -at the top of the bootstrap script, or as a user environment variable etc. +at the top of the bootstrap script, or as a user environment variable. @@ -278,17 +297,27 @@ TIP: Scala Steward can also xref:scalalib/dependencies.adoc#_keeping_up_to_date_with_scala_steward[scan your project dependencies] and keep them up-to-date. -== Development Releases +== Unstable Development Releases In case you want to try out the latest features and improvements that are currently in the main branch, unstable versions of Mill -are -https://github.com/com-lihaoyi/mill/releases[available] as binaries named -`+#.#.#-n-hash+` linked to the latest tag. +are available as versions named: + +* `+{stable-version}-{commits-since-stable-version}-{commit-hash}+` + +For example, `0.12.5-193-b4d975` is an unstable release after `0.12.5`, with `193` +additional commits, on commit hash `b4d975`. + +The list of unstable releases can be seen on Maven Central: + +* https://repo1.maven.org/maven2/com/lihaoyi/mill-dist + +Or find the latest unstable version here: + +* https://central.sonatype.com/artifact/com.lihaoyi/mill-dist -The easiest way to use a development release is to use one of the -<<_bootstrap_scripts>>, which support overriding Mill versions via an -`MILL_VERSION` environment variable or a `.mill-version` or `.config/mill-version` file. +You can update your `.mill-version` to to the unstable version and the bootstrap script +will download it for you to try it out in your project. diff --git a/docs/modules/ROOT/pages/cli/query-syntax.adoc b/docs/modules/ROOT/pages/cli/query-syntax.adoc index 7ca0ce9dd4f..1733e0af0a4 100644 --- a/docs/modules/ROOT/pages/cli/query-syntax.adoc +++ b/docs/modules/ROOT/pages/cli/query-syntax.adoc @@ -1,7 +1,7 @@ = Task Query Syntax :page-aliases: Task_Query_Syntax.adoc -include::partial$gtag-config.adoc[] + When interacting with Mill from the CLI, you often need to select tasks or modules. In most places, where Mill accepts a task, it really accepts a task selector query, which is the name of a task in its simplest form, but it can also contain wildcards, type pattern and other special syntax, making it a powerful tool to select specific tasks. diff --git a/docs/modules/ROOT/pages/comparisons/gradle.adoc b/docs/modules/ROOT/pages/comparisons/gradle.adoc index e65794657d4..2140cc57e6a 100644 --- a/docs/modules/ROOT/pages/comparisons/gradle.adoc +++ b/docs/modules/ROOT/pages/comparisons/gradle.adoc @@ -1,7 +1,7 @@ = Case Study: Mill vs Gradle :page-aliases: Case_Study_Mill_vs_Gradle.adoc -include::partial$gtag-config.adoc[] + Compared to Gradle, diff --git a/docs/modules/ROOT/pages/comparisons/maven.adoc b/docs/modules/ROOT/pages/comparisons/maven.adoc index c583a5c1b4e..7b96c8a4eec 100644 --- a/docs/modules/ROOT/pages/comparisons/maven.adoc +++ b/docs/modules/ROOT/pages/comparisons/maven.adoc @@ -1,7 +1,7 @@ = Case Study: Mill vs Maven :page-aliases: Case_Study_Mill_vs_Maven.adoc -include::partial$gtag-config.adoc[] + Compared to Maven: @@ -398,15 +398,15 @@ object common extends NettyModule{ context.put("collection.template.dir", "common/src/main/templates") context.put("collection.template.test.dir", "common/src/test/templates") - context.put("collection.src.dir", (T.dest / "src").toString) - context.put("collection.testsrc.dir", (T.dest / "testsrc").toString) + context.put("collection.src.dir", (Task.dest / "src").toString) + context.put("collection.testsrc.dir", (Task.dest / "testsrc").toString) shell.setProperty("properties", context) shell.setProperty("ant", new groovy.ant.AntBuilder()) shell.evaluate((script().path / "codegen.groovy").toIO) - (PathRef(T.dest / "src"), PathRef(T.dest / "testsrc")) + (PathRef(Task.dest / "src"), PathRef(Task.dest / "testsrc")) } def generatedSources = Task { Seq(generatedSources0()._1)} @@ -524,24 +524,24 @@ def makefile = Task.Source(millSourcePath / "Makefile") def cSources = Task.Source(millSourcePath / "src" / "main" / "c") def cHeaders = Task { for(p <- os.walk(cSources().path) if p.ext == "h"){ - os.copy(p, T.dest / p.relativeTo(cSources().path), createFolders = true) + os.copy(p, Task.dest / p.relativeTo(cSources().path), createFolders = true) } - PathRef(T.dest) + PathRef(Task.dest) } def make = Task { - os.copy(makefile().path, T.dest / "Makefile") - os.copy(cSources().path, T.dest / "src" / "main" / "c", createFolders = true) + os.copy(makefile().path, Task.dest / "Makefile") + os.copy(cSources().path, Task.dest / "src" / "main" / "c", createFolders = true) val Seq(sourceJar) = resolveDeps( deps = Task.Anon(Agg(ivy"io.netty:netty-jni-util:0.0.9.Final").map(bindDependency())), sources = true )().toSeq - os.proc("jar", "xf", sourceJar.path).call(cwd = T.dest / "src" / "main" / "c") + os.proc("jar", "xf", sourceJar.path).call(cwd = Task.dest / "src" / "main" / "c") os.proc("make").call( - cwd = T.dest, + cwd = Task.dest, env = Map( "CC" -> "clang", "AR" -> "ar", @@ -561,7 +561,7 @@ def make = Task { ) ) - (PathRef(T.dest / "lib-out"), PathRef(T.dest / "obj-out")) + (PathRef(Task.dest / "lib-out"), PathRef(Task.dest / "obj-out")) } ``` diff --git a/docs/modules/ROOT/pages/comparisons/sbt.adoc b/docs/modules/ROOT/pages/comparisons/sbt.adoc index cc84733024c..9199dca2d08 100644 --- a/docs/modules/ROOT/pages/comparisons/sbt.adoc +++ b/docs/modules/ROOT/pages/comparisons/sbt.adoc @@ -1,7 +1,7 @@ = Case Study: Mill vs SBT :page-aliases: Case_Study_Mill_vs_SBT.adoc -include::partial$gtag-config.adoc[] + Compared to SBT, @@ -231,7 +231,7 @@ It is able to pull up any overridden implementations of task, directly in the ed image::comparisons/IntellijGatlingMillTask2.png[] -And you can easily navigate to the overriden implementations to see where they are defined and +And you can easily navigate to the overridden implementations to see where they are defined and what you are overriding: image::comparisons/IntellijGatlingMillTask3.png[] diff --git a/docs/modules/ROOT/pages/comparisons/unique.adoc b/docs/modules/ROOT/pages/comparisons/unique.adoc index a760cd9c2c9..8fe5879ed9c 100644 --- a/docs/modules/ROOT/pages/comparisons/unique.adoc +++ b/docs/modules/ROOT/pages/comparisons/unique.adoc @@ -1,6 +1,6 @@ # What Makes Mill Unique -include::partial$gtag-config.adoc[] + https://mill-build.org/[Mill] is a JVM build tool that targets Java/Scala/Kotlin and has potential to serve the large-monorepo codebases that Bazel currently serves. Mill has good diff --git a/docs/modules/ROOT/pages/comparisons/why-mill.adoc b/docs/modules/ROOT/pages/comparisons/why-mill.adoc index 2bd8eb7b044..dd72327f618 100644 --- a/docs/modules/ROOT/pages/comparisons/why-mill.adoc +++ b/docs/modules/ROOT/pages/comparisons/why-mill.adoc @@ -215,13 +215,12 @@ the Gradle build in an IDE, the IDE can only explore the configuration logic (th `getCompilerArgs` method above) and is unable to explore the actual build logic (how `getCompilerArgs` _actually gets used in Gradle_) -In comparison, Mill's `.mill` files are all statically typed, and as a result IntelliJ is easily able to -pull up the documentation for `def javacOptions`, even though it doesn't have any special support -for Mill built into the IDE: +In comparison, not only are Mill's `.mill` files statically typed, allowing IDEs like IntelliJ +to pull up the documentation for `def javacOptions`: image::comparisons/IntellijMockitoMillJavacOptionsDocs.png[] -Apart from static typing, the way Mill builds are structured also helps the IDE: Mill +The way Mill builds are structured also helps the IDE: Mill code _actually performs your build_, rather than configuring some opaque build engine. While that sounds academic, one concrete consequence is that IntelliJ is able to take your `def javacOptions` override and @@ -229,7 +228,7 @@ find the original definitions that were overridden, and show you where they are image::comparisons/IntellijMockitoMillJavacOptionsParents.png[] -You can jump to any of the overriden `def`s quickly and precisely: +You can jump to any of the overridden `def`s quickly and precisely: image::comparisons/IntellijMockitoMillJavacOptionsDef.png[] @@ -364,7 +363,7 @@ Line Count: 18 Next, we'll look at a more realistic example, which includes usage of third-party libraries in the build. -### Using Libraries from Maven Central in Tasks +### Using Third-Party JVM Libraries in Tasks Earlier on we discussed possibly pre-rendering HTML pages in the build so they can be served at runtime. The use case for this are obvious: if a page never changes, rendering @@ -386,9 +385,14 @@ import $ivy.`org.thymeleaf:thymeleaf:3.1.1.RELEASE` import org.thymeleaf.TemplateEngine import org.thymeleaf.context.Context object foo extends JavaModule { + /** Total number of lines in module source files */ + def lineCount = Task { + allSourceFiles().map(f => os.read.lines(f.path).size).sum + } + def htmlSnippet = Task { val context = new Context() - context.setVariable("heading", "hello") + context.setVariable("heading", "Line Count is: " + lineCount()) new TemplateEngine().process( "

", context @@ -411,14 +415,14 @@ is inspectable from the Mill command line via `show`, and we wire it up into ```bash > mill show foo.htmlSnippet -"

hello

" +"

Line count is: 17

" > mill foo.compile compiling 1 Java source... ... > mill foo.run -generated snippet.txt resource:

hello

+generated snippet.txt resource:

Line count is: 17

``` Rendering HTML using the Thymeleaf templating engine is not rocket science, but what is @@ -434,9 +438,9 @@ interesting here is what we did _not_ need to do: implement the functionality we need. -Instead, we could simply import Thymeleaf directly from Maven Central and use it just -like we would use it in any Java application, with IDE support, typechecking, -and automatic parallelism and caching. +Instead, we could simply import Thymeleaf as a Java library directly from Maven Central +and use it just like we would use it in any Java application, with IDE support, +typechecking, and automatic parallelism and caching. ''' diff --git a/docs/modules/ROOT/pages/depth/design-principles.adoc b/docs/modules/ROOT/pages/depth/design-principles.adoc index 29e5508bf24..d4f6487c57b 100644 --- a/docs/modules/ROOT/pages/depth/design-principles.adoc +++ b/docs/modules/ROOT/pages/depth/design-principles.adoc @@ -1,23 +1,24 @@ = Mill Design Principles :page-aliases: Mill_Internals.adoc, Mill_Design_Principles.adoc -include::partial$gtag-config.adoc[] + The following external resources give more of a flavor of the architecture behind Mill: * https://www.youtube.com/watch?v=UsXgCeU-ovI[Video: A Deep Dive into the Mill Build Tool] -* https://www.lihaoyi.com/post/SoWhatsSoSpecialAboutTheMillScalaBuildTool.html[Blog Post: What's So Special About The Mill Scala Build Tool?] -* https://www.youtube.com/watch?v=j6uThGxx-18[Video: Mill a Build Tool based on Pure Functional Programming] -* http://www.lihaoyi.com/post/BuildToolsasPureFunctionalPrograms.html[Blog Post: Build Tools as Pure Functional Programs] -* http://www.lihaoyi.com/post/SowhatswrongwithSBT.html[Blog Post: So, what's wrong with SBT?] +* https://www.youtube.com/watch?v=MEPtepNWHs8[Video: Mill a JVM Build Tool based on Pure Functional Programming] + +There are also more talks and blog posts available to read on the following page: + +- xref:reference/talks-blog-posts.adoc[] == Principles === Dependency graph first Mill's most important abstraction is the dependency graph of ``Task``s. -Constructed using the `T {...}` `Task.Anon {...}` `Task.Command {...}` syntax, these +Constructed using the `Task {...}` `Task.Anon {...}` `Task.Command {...}` syntax, these track the dependencies between steps of a build, so those steps can be executed in the correct order, queried, or parallelized. @@ -118,7 +119,7 @@ sorts of useful operations on the graph before running it: with an exception In order to avoid making people using `.map` and `.zip` all over the place when -defining their ``Task``s, we use the `T {...}`/`Task.Anon {...}`/`Task.Command {...}` +defining their ``Task``s, we use the `Task {...}`/`Task.Anon {...}`/`Task.Command {...}` macros which allow you to use `Task#apply()` within the block to "extract" a value. @@ -138,7 +139,7 @@ This is roughly equivalent to the following: [source,scala] ---- -def test() = Task.Command { T.zipMap(runDepClasspath, compile, compile) { +def test() = Task.Command { Task.zipMap(runDepClasspath, compile, compile) { (runDepClasspath1, compile2, compile3) => TestRunner.apply( "mill.UTestFramework", @@ -150,7 +151,7 @@ def test() = Task.Command { T.zipMap(runDepClasspath, compile, compile) { ---- This is similar to SBT's `:=`/`.value` macros, or ``scala-async``'s -`async`/`await`. Like those, the `T {...}` macro should let users program most of +`async`/`await`. Like those, the `Task {...}` macro should let users program most of their code in a "direct" style and have it "automatically" lifted into a graph of ``Task``s. @@ -277,7 +278,7 @@ digraph G { ``` The Scala call graph of "which task references which other task" is core to -how Mill operates. This graph is reified via the `T {...}` macro to make it +how Mill operates. This graph is reified via the `Task {...}` macro to make it available to the Mill execution engine at runtime. The call graph tells you: * Which ``Task``s depend on which other ``Task``s @@ -294,7 +295,7 @@ available to the Mill execution engine at runtime. The call graph tells you: its return value) * Defining your own task that depends on others is as simple as `def foo = - T {...}` +Task {...}` The call graph within your Scala code is essentially a data-flow graph: by defining a snippet of code: @@ -312,7 +313,7 @@ you are telling everyone that the value `a` depends on the values of `b` `c` and knowing what `Task` depends on what other ``Task``s, and what processing it does on its inputs! -With Mill, you can take the Scala call graph, wrap everything in the `T {...}` +With Mill, you can take the Scala call graph, wrap everything in the `Task {...}` macro, and get a `Task`-dependency graph that matches exactly the call-graph you already had: diff --git a/docs/modules/ROOT/pages/depth/execution-model.adoc b/docs/modules/ROOT/pages/depth/execution-model.adoc index fb67118b27f..ea0c0ae0be3 100644 --- a/docs/modules/ROOT/pages/depth/execution-model.adoc +++ b/docs/modules/ROOT/pages/depth/execution-model.adoc @@ -1,7 +1,7 @@ = The Mill Execution Model :page-aliases: The_Mill_Evaluation_Model.adoc, depth/evaluation-model.adoc -include::partial$gtag-config.adoc[] + This page does a deep dive on how Mill evaluates your build tasks, so you can better understand what Mill is doing behind the scenes when building your project. @@ -386,7 +386,7 @@ the overall workflow remains fast even for large projects: * ``Task``s are evaluated in dependency order - * xref:fundamentals/tasks.adoc#_cached_tasks[Cached Task]s only re-evaluate if their input ``Task``s + * xref:fundamentals/tasks.adoc#_tasks[Cached Task]s only re-evaluate if their input ``Task``s change. * xref:fundamentals/tasks.adoc#_persistent_tasks[Persistent Tasks]s preserve the `Task.dest` diff --git a/docs/modules/ROOT/pages/depth/process-architecture.adoc b/docs/modules/ROOT/pages/depth/process-architecture.adoc index 436be147912..377a5fafeb0 100644 --- a/docs/modules/ROOT/pages/depth/process-architecture.adoc +++ b/docs/modules/ROOT/pages/depth/process-architecture.adoc @@ -1,6 +1,6 @@ = The Mill Process Architecture -include::partial$gtag-config.adoc[] + This page goes into detail of how the Mill process and application is structured. At a high-level, a simplified version of the main components and data-flows within diff --git a/docs/modules/ROOT/pages/depth/sandboxing.adoc b/docs/modules/ROOT/pages/depth/sandboxing.adoc index 118aaf01ddc..2374bc024f3 100644 --- a/docs/modules/ROOT/pages/depth/sandboxing.adoc +++ b/docs/modules/ROOT/pages/depth/sandboxing.adoc @@ -1,7 +1,7 @@ = Mill Sandboxing :page-aliases: Mill_Sandboxing.adoc -include::partial$gtag-config.adoc[] + == Task Sandboxing diff --git a/docs/modules/ROOT/pages/depth/why-scala.adoc b/docs/modules/ROOT/pages/depth/why-scala.adoc index 3f880088be1..f7fd592dbce 100644 --- a/docs/modules/ROOT/pages/depth/why-scala.adoc +++ b/docs/modules/ROOT/pages/depth/why-scala.adoc @@ -1,6 +1,6 @@ = Why does Mill use Scala? -include::partial$gtag-config.adoc[] + One question that comes up a lot among Mill users is why use Scala as the language to configure your build? Why not YAML, XML, TOML, Bash, Groovy, Python, Java, or any of the diff --git a/docs/modules/ROOT/pages/extending/contrib-plugins.adoc b/docs/modules/ROOT/pages/extending/contrib-plugins.adoc index f412f76bb0b..ae0dafba237 100644 --- a/docs/modules/ROOT/pages/extending/contrib-plugins.adoc +++ b/docs/modules/ROOT/pages/extending/contrib-plugins.adoc @@ -1,7 +1,7 @@ = Contrib Plugins :page-aliases: Contrib_Plugins.adoc, Contrib_Modules.adoc -include::partial$gtag-config.adoc[] + The ((plugins)) in this section are hosted in the Mill git tree and developed / maintained by the community. diff --git a/docs/modules/ROOT/pages/extending/example-python-support.adoc b/docs/modules/ROOT/pages/extending/example-python-support.adoc index 319929a5df4..bc1d7b9f1c0 100644 --- a/docs/modules/ROOT/pages/extending/example-python-support.adoc +++ b/docs/modules/ROOT/pages/extending/example-python-support.adoc @@ -1,6 +1,6 @@ = Example: Python Support -include::partial$gtag-config.adoc[] + This section demonstrates how to integrate `Python` support into `Mill`. We will define a simple `PythonModule` trait that can resolve dependencies, diff --git a/docs/modules/ROOT/pages/extending/example-typescript-support.adoc b/docs/modules/ROOT/pages/extending/example-typescript-support.adoc index af3b7c8544f..e38f14ef863 100644 --- a/docs/modules/ROOT/pages/extending/example-typescript-support.adoc +++ b/docs/modules/ROOT/pages/extending/example-typescript-support.adoc @@ -1,6 +1,6 @@ = Example: Typescript Support -include::partial$gtag-config.adoc[] + This section walks through the process of adding support for a new programming language to Mill. We will be adding a small `trait TypeScriptModule` with the diff --git a/docs/modules/ROOT/pages/extending/import-ivy-plugins.adoc b/docs/modules/ROOT/pages/extending/import-ivy-plugins.adoc index dfc7eb838d2..0d1d347b553 100644 --- a/docs/modules/ROOT/pages/extending/import-ivy-plugins.adoc +++ b/docs/modules/ROOT/pages/extending/import-ivy-plugins.adoc @@ -1,7 +1,7 @@ = Import Libraries and Plugins :page-aliases: Import_File_And_Import_Ivy.adoc, Using_Plugins.adoc -include::partial$gtag-config.adoc[] + This page illustrates usage of `import $ivy`. `import $ivy` lets you import JVM dependencies into your `build.mill`, so diff --git a/docs/modules/ROOT/pages/extending/meta-build.adoc b/docs/modules/ROOT/pages/extending/meta-build.adoc index 66a3e0045e9..83abb9f0a49 100644 --- a/docs/modules/ROOT/pages/extending/meta-build.adoc +++ b/docs/modules/ROOT/pages/extending/meta-build.adoc @@ -1,7 +1,7 @@ = The Mill Meta-Build :page-aliases: The_Mill_Meta_Build.adoc -include::partial$gtag-config.adoc[] + The meta-build manages the compilation of the `build.mill`. Customizing the meta-build gives you greater control over how exactly your diff --git a/docs/modules/ROOT/pages/extending/running-jvm-code.adoc b/docs/modules/ROOT/pages/extending/running-jvm-code.adoc index 9a02338c99c..ff0b6fb7bfc 100644 --- a/docs/modules/ROOT/pages/extending/running-jvm-code.adoc +++ b/docs/modules/ROOT/pages/extending/running-jvm-code.adoc @@ -1,6 +1,6 @@ = Running Dynamic JVM Code -include::partial$gtag-config.adoc[] + While xref:extending/import-ivy-plugins.adoc[import $ivy] is convenient, it comes with limitations as the JVM library it imports is global to your build: diff --git a/docs/modules/ROOT/pages/extending/thirdparty-plugins.adoc b/docs/modules/ROOT/pages/extending/thirdparty-plugins.adoc index 8502da9032f..95092ef6afe 100644 --- a/docs/modules/ROOT/pages/extending/thirdparty-plugins.adoc +++ b/docs/modules/ROOT/pages/extending/thirdparty-plugins.adoc @@ -1,7 +1,7 @@ = Third-Party Plugins :page-aliases: Thirdparty_Modules.adoc, Thirdparty_Plugins.adoc -include::partial$gtag-config.adoc[] + The Plugins in this section are developed/maintained outside the mill git tree. This list is most likely not complete. @@ -1069,7 +1069,7 @@ import ba.sake.squery.generator._ import ba.sake.squery.generator.mill.SqueryGeneratorModule object app extends ScalaModule with SqueryGeneratorModule { - // use T.input(T.ctx.env("MY_ENV_VAR")) to set sensitive variables like password etc + // use Task.Input(Task.ctx.env("MY_ENV_VAR")) to set sensitive variables like password etc def squeryJdbcUrl = "jdbc:..." def squeryUsername = ".." def squeryPassword = ".." diff --git a/docs/modules/ROOT/pages/extending/writing-plugins.adoc b/docs/modules/ROOT/pages/extending/writing-plugins.adoc index d3f24383f6d..247fefff25b 100644 --- a/docs/modules/ROOT/pages/extending/writing-plugins.adoc +++ b/docs/modules/ROOT/pages/extending/writing-plugins.adoc @@ -1,6 +1,6 @@ = Writing Mill Plugins :page-aliases: Writing_Mill_Plugins.adoc -include::partial$gtag-config.adoc[] + include::partial$example/extending/plugins/7-writing-mill-plugins.adoc[] \ No newline at end of file diff --git a/docs/modules/ROOT/pages/fundamentals/bundled-libraries.adoc b/docs/modules/ROOT/pages/fundamentals/bundled-libraries.adoc index 779c7348d8f..c8165f9d706 100644 --- a/docs/modules/ROOT/pages/fundamentals/bundled-libraries.adoc +++ b/docs/modules/ROOT/pages/fundamentals/bundled-libraries.adoc @@ -1,7 +1,7 @@ = Bundled Libraries :page-aliases: External_References.adoc, Bundled_Libraries.adoc -include::partial$gtag-config.adoc[] + Mill comes bundled with a set of external Open Source libraries and projects. diff --git a/docs/modules/ROOT/pages/fundamentals/cross-builds.adoc b/docs/modules/ROOT/pages/fundamentals/cross-builds.adoc index f04145ede85..55061b56d10 100644 --- a/docs/modules/ROOT/pages/fundamentals/cross-builds.adoc +++ b/docs/modules/ROOT/pages/fundamentals/cross-builds.adoc @@ -1,7 +1,7 @@ = Cross Builds :page-aliases: Cross_Builds.adoc -include::partial$gtag-config.adoc[] + Cross-building refers to taking the same sources and configuration and building it multiple times with minor changes. This could mean taking the same Scala @@ -13,19 +13,19 @@ config and building it across a variety of source folders. include::partial$example/fundamentals/cross/1-simple.adoc[] -== Cross Modules Defaults +=== Cross Modules Defaults include::partial$example/fundamentals/cross/11-default-cross-module.adoc[] -== Cross Modules Source Paths +=== Cross Modules Source Paths include::partial$example/fundamentals/cross/2-cross-source-path.adoc[] -== Using Cross Modules from Outside Tasks +=== Using Cross Modules from Outside Tasks include::partial$example/fundamentals/cross/3-outside-dependency.adoc[] -== Using Cross Modules from other Cross Modules +=== Using Cross Modules from other Cross Modules include::partial$example/fundamentals/cross/4-cross-dependencies.adoc[] @@ -33,7 +33,7 @@ include::partial$example/fundamentals/cross/4-cross-dependencies.adoc[] include::partial$example/fundamentals/cross/5-multiple-cross-axes.adoc[] -== Extending Cross Modules +=== Extending Cross Modules include::partial$example/fundamentals/cross/6-axes-extension.adoc[] diff --git a/docs/modules/ROOT/pages/fundamentals/library-deps.adoc b/docs/modules/ROOT/pages/fundamentals/library-deps.adoc index fed38f21094..a7b4f72bdaf 100644 --- a/docs/modules/ROOT/pages/fundamentals/library-deps.adoc +++ b/docs/modules/ROOT/pages/fundamentals/library-deps.adoc @@ -3,7 +3,7 @@ :link-coursier-doc: https://get-coursier.io/docs/overview :page-aliases: Library_Dependencies.adoc -include::partial$gtag-config.adoc[] + Beside the dependencies between Mill modules, most non-trivial source projects have dependencies to other libraries. @@ -26,7 +26,6 @@ ivy"{organization}:{name}:{version}[;{attribute}={value}]*" ---- When working in other Java and Scala projects, you will find some synonyms, which typically all mean the same. - For example in the Maven ecosystem, the `organization` is called the `group` and the `name` is called the `artifact`. The whole triplet is often called `GAV`. @@ -42,7 +41,7 @@ def ivyDeps = Agg( ---- -== Test dependencies (there is no `test` scope) +=== Test dependencies (there is no `test` scope) One difference between Mill and other build tools like sbt or Maven is the fact, that tests are ordinary submodules on their own. For convenience, most modules already come with a pre-configured trait for a test submodule, @@ -65,7 +64,7 @@ object main extends JavaModule { } ---- -== Compile-only dependencies (`provided` scope) +=== Compile-only dependencies (`provided` scope) If you want to use a dependency only at compile time, you can declare it with the `compileIvyDeps` task. @@ -82,7 +81,7 @@ When Mill generated file to interact with package manager like `pom.xml` for Mav Please note, that dependencies with `provided` scope will never be resolved transitively. Hence, the name "provided", as the task runtime needs to "provide" them, if they are needed. -== Runtime dependencies +=== Runtime dependencies If you want to declare dependencies to be used at runtime (but not at compile time), you can use the `runIvyDeps` tasks. @@ -96,105 +95,7 @@ def runIvyDeps = Agg( It is also possible to use a higher version of the same library dependencies already defined in `ivyDeps`, to ensure you compile against a minimal API version, but actually run with the latest available version. -== Dependency management - -Dependency management consists in listing dependencies whose versions we want to force. Having -a dependency in dependency management doesn't mean that this dependency will be fetched, only -that - -* if it ends up being fetched transitively, its version will be forced to the one in dependency management - -* if its version is empty in an `ivyDeps` section in Mill, the version from dependency management will be used - -Dependency management also allows to add exclusions to dependencies, both explicit dependencies and -transitive ones. - -Dependency management can be passed to Mill in two ways: - -* via external Maven Bill of Material (BOM), like https://repo1.maven.org/maven2/com/google/cloud/libraries-bom/26.50.0/libraries-bom-26.50.0.pom[this one], -whose Maven coordinates are `com.google.cloud:libraries-bom:26.50.0` - -* via the `depManagement` task, that allows to directly list dependencies whose versions we want to enforce - -=== External Bill of Material (BOM) - -include::partial$example/fundamentals/library-deps/bom-1-external-bom.adoc[] - -=== Managed Bill of Material (BOM) - -include::partial$example/fundamentals/library-deps/bom-2-managed.adoc[] - -== Searching For Dependency Updates - -include::partial$example/fundamentals/dependencies/1-search-updates.adoc[] - -== Scala dependencies - -Scala major releases up until version `2.13` are binary incompatible. -That means, mixing dependencies of different binary platforms will result in non-working runtimes and obscure and hard to debug issues. - -To easily pick only a compatible version, a convention was established to append the scala major version as a suffix to the package name.footnote:[ -Scala 2 versions have the unusual version format: `{epoch}.{major}.{minor}`.] -E.g. to select the Scala 2.13 version of a library `foo`, the final `artifactId` will contain the additional suffix `_2.13`, such that the final `artifactId` is `foo_2.13`. - -To always pick the right version and support cross compiling, -you can omit the scala version and instead use a double colon (`::`) between the `organization` and the `name`, e.g. `ivy"com.typesafe.akka:akka-actor_2.12:2.5.25"`. -Your module needs to `extends ScalaModule` though. - -If you want to use dependencies that are cross-published against the full Scala version, e.g. `2.12.12`, -you can use three colons (`:::`) between `organization` and `name`, e.g.: `ivy"org.scalamacros:::paradise:2.1.1"`. - -.Example -[source,scala] ----- -def ivyDeps = Agg( - // explicit scala version suffix, NOT RECOMMENDED! - ivy"com.typesafe.akka:akka-actor_2.12:2.5.25", - ivy"com.typesafe.akka::akka-actor:2.5.25", - ivy"org.scalamacros:::paradise:2.1.1" -) ----- - -== Scala 3 interoperability - -Since the release of Scala 3, the binary compatibility story for Scala has changed. -That means, Scala 3 dependencies can be mixed with Scala 2.13 dependencies. -In fact, the Scala 3 standard library is the same as for Scala 2.13. - - -[CAUTION] --- -As Scala 3 and Scala 2.13 have different binary platforms, but their artifacts are in general compatible, this introduces new challenges. - -There is currently no mechanism, that impedes to bring the same dependency twice into the classpath (one for Scala 2.13 and one for Scala 3). --- - - -=== Using Scala 2.13 from Scala 3 - -If your Scala version is a Scala 3.x, but you want to use the Scala 2.13 version of a specific library, you can use the `.withDottyCompat` method on that dependency. - -.Example: -[source,scala] ----- -def scalaVersion = "3.2.1" -def ivyDeps = Agg( - ivy"com.lihaoyi::upickle:2.0.0".withDottyCompat(scalaVersion()) //1 -) ----- -<1> This will result in a Scala 2.13 dependency `com.lihaoyi::upicke_2.13:2.0.0` - - -[NOTE] --- -Do you wonder where the name "dotty" comes from? - -In the early development of Scala 3, the Scala 3 compiler was called "Dotty". Later, the name was changed to Scala 3, but the compiler project itself is still named "dotty". - -The dotty compiler itself is an implementation of the http://lampwww.epfl.ch/~amin/dot/fool.pdf[Dependent Object Types (DOT) calculus], which is the new basis of Scala 3. It also enhances the type system to a next level and allows features like union-types and intersection-types. --- - -== Detecting transitive dependencies +== Transitive dependencies To render a tree of dependencies (transitive included) you can run `mill myModule.ivyDepsTree`. Here is how the start of `./mill __.ivyDepsTree` looks like in the `mill` project itself: @@ -252,7 +153,7 @@ Also note that when using `--whatDependsOn` on usage of `--inverse` is forced in order to make the tree appear in an inverted manner to more easily show you where the dependency is coming from. -== Excluding transitive dependencies +=== Excluding transitive dependencies You can use the `.exclude` method on a dependency. It accepts `organization` and `name` tuples, to be excluded. Use the special name `*` to match all ``organization``s or ``name``s. @@ -295,9 +196,7 @@ val deps = Agg( ) ---- -== Forcing versions - -CAUTION: Please treat forceVersion as experimental; it has some bugs and isn't production-ready (forced versions https://github.com/com-lihaoyi/mill/issues/1975[aren't propagated to published artifacts]). +=== Forcing versions You can use the `forceVersion` method to ensure the used version of a dependency is what you have declared. @@ -308,19 +207,36 @@ You can use the `forceVersion` method to ensure the used version of a dependency * If you want to force to the older version (to prevent it being evicted, and replaced by 0.4.0) then you can use `val deps = Agg(ivy"com.lihaoyi::fansi:0.2.14".forceVersion())` * `mill show myModule.resolvedIvyDeps | grep "fansi"` should show fansi 0.2.14 -== ScalaJS dependencies +== Dependency management -Scala.js introduces an additional binary platform axis. -To the already required Scala version, there comes the Scala.js version. +Dependency management consists in listing dependencies whose versions we want to force. Having +a dependency in dependency management doesn't mean that this dependency will be fetched, only +that -You can use two colons (`::`) between `name` and `version` to define a Scala.js dependency. -Your module needs to `extends ScalaJSModule` to accept Scala.js dependencies. +* if it ends up being fetched transitively, its version will be forced to the one in dependency management -== Scala Native dependencies +* if its version is empty in an `ivyDeps` section in Mill, the version from dependency management will be used -Scala Native introduces an additional binary platform axis. -To the already required Scala version, there comes the Scala Native version. +Dependency management also allows to add exclusions to dependencies, both explicit dependencies and +transitive ones. -You can use two colons (`::`) between `name` and `version` to define a Scala Native dependency. -Your module needs to `extends ScalaNativeModule` to accept Scala Native dependencies. +Dependency management can be passed to Mill in two ways: + +* via external Maven Bill of Material (BOM), like https://repo1.maven.org/maven2/com/google/cloud/libraries-bom/26.50.0/libraries-bom-26.50.0.pom[this one], +whose Maven coordinates are `com.google.cloud:libraries-bom:26.50.0` + +* via the `depManagement` task, that allows to directly list dependencies whose versions we want to enforce + +=== External Bill of Material (BOM) + +include::partial$example/fundamentals/dependencies/1-external-bom.adoc[] + +=== Managed Bill of Material (BOM) + +include::partial$example/fundamentals/dependencies/2-managed.adoc[] + + + +== Searching For Dependency Updates +include::partial$example/fundamentals/dependencies/3-search-updates.adoc[] diff --git a/docs/modules/ROOT/pages/fundamentals/modules.adoc b/docs/modules/ROOT/pages/fundamentals/modules.adoc index f6f8ac0155b..6dd16702a81 100644 --- a/docs/modules/ROOT/pages/fundamentals/modules.adoc +++ b/docs/modules/ROOT/pages/fundamentals/modules.adoc @@ -1,8 +1,6 @@ = Modules :page-aliases: Modules.adoc -include::partial$gtag-config.adoc[] - `mill.Module` serves two main purposes: 1. As ``object``s, they serve as namespaces that let you group related ``Task``s @@ -25,6 +23,10 @@ include::partial$example/fundamentals/modules/7-root-module.adoc[] include::partial$example/fundamentals/modules/8-diy-java-modules.adoc[] +== Default Tasks + +include::partial$example/fundamentals/modules/12-default-tasks.adoc[] + == Backticked Names include::partial$example/fundamentals/modules/9-backticked-names.adoc[] @@ -65,14 +67,10 @@ service & cache that is shared between all ``ScalaModule``s, and `mill.scalalib.GenIdea/idea` lets you generate IntelliJ projects without needing to define your own `Task.Command` in your `build.mill` file -== Aliasing External Modules +=== Aliasing External Modules include::partial$example/fundamentals/modules/10-external-module-aliases.adoc[] == Abstract Modules References include::partial$example/fundamentals/modules/11-abstract-module-ref.adoc[] - -== Default Tasks - -include::partial$example/fundamentals/modules/12-default-tasks.adoc[] \ No newline at end of file diff --git a/docs/modules/ROOT/pages/fundamentals/out-dir.adoc b/docs/modules/ROOT/pages/fundamentals/out-dir.adoc index 5bd7501ccdc..8435c82deed 100644 --- a/docs/modules/ROOT/pages/fundamentals/out-dir.adoc +++ b/docs/modules/ROOT/pages/fundamentals/out-dir.adoc @@ -1,7 +1,7 @@ = The Output Directory :page-aliases: Out_Dir.adoc -include::partial$gtag-config.adoc[] + include::partial$example/fundamentals/out-dir/1-out-files.adoc[] diff --git a/docs/modules/ROOT/pages/fundamentals/tasks.adoc b/docs/modules/ROOT/pages/fundamentals/tasks.adoc index fcd22e38499..81e0ac82e83 100644 --- a/docs/modules/ROOT/pages/fundamentals/tasks.adoc +++ b/docs/modules/ROOT/pages/fundamentals/tasks.adoc @@ -1,14 +1,14 @@ = Tasks :page-aliases: Tasks.adoc -include::partial$gtag-config.adoc[] + One of Mill's core abstractions is its _Task Graph_: this is how Mill defines, orders and caches work it needs to do, and exists independently of any support for building Java, Kotlin, or Scala. Mill task graphs are primarily built using methods and macros defined on -`mill.define.Task`, aliased as `T` for conciseness: +`mill.define.Task`, whose type is often aliased as `T[_]` for conciseness: - {mill-doc-url}/api/latest/mill/define/Task$.html[mill.define.Task] @@ -19,14 +19,14 @@ different Task types: [cols="<,<,<,<,<,<,<"] |=== -| |Target |Command |Source/Input |Anonymous Task |Persistent Task |Worker - -|Cached to Disk |X | | | |X | -|JSON Writable |X |X |X| |X | -|JSON Readable |X | | | |X | -|CLI Runnable |X |X | | |X | -|Takes Arguments | |X | |X | | -|Cached In-Memory | | | | | |X +| |Target |Command |Source/Input |Persistent Task |Worker|Anonymous Task + +|Cached to Disk |X | | |X | | +|JSON Writable |X |X |X|X | | +|JSON Readable |X | | |X | | +|CLI Runnable |X |X | |X | | +|Takes Arguments | |X | | | | X +|Cached In-Memory | | | | |X | |=== include::partial$example/fundamentals/tasks/1-task-graph.adoc[] @@ -38,10 +38,6 @@ include::partial$example/fundamentals/tasks/2-primary-tasks.adoc[] == Other Tasks -=== Anonymous Tasks - -include::partial$example/fundamentals/tasks/3-anonymous-tasks.adoc[] - === Inputs include::partial$example/fundamentals/tasks/4-inputs.adoc[] @@ -54,6 +50,10 @@ include::partial$example/fundamentals/tasks/5-persistent-tasks.adoc[] include::partial$example/fundamentals/tasks/6-workers.adoc[] +=== Anonymous Tasks + +include::partial$example/fundamentals/tasks/3-anonymous-tasks.adoc[] + == (Experimental) Forking Concurrent Futures within Tasks include::partial$example/fundamentals/tasks/7-forking-futures.adoc[] diff --git a/docs/modules/ROOT/pages/index.adoc b/docs/modules/ROOT/pages/index.adoc index 8ad304f3039..1ec5c420406 100644 --- a/docs/modules/ROOT/pages/index.adoc +++ b/docs/modules/ROOT/pages/index.adoc @@ -1,19 +1,24 @@ = Mill: A Fast JVM Build Tool -include::partial$gtag-config.adoc[] +https://github.com/com-lihaoyi/mill/blob/main/changelog.adoc[image:https://index.scala-lang.org/com-lihaoyi/mill/mill-main/latest.svg[Mill]] +https://central.sonatype.com/artifact/com.lihaoyi/mill-dist[image:https://img.shields.io/maven-central/v/com.lihaoyi/mill-dist?label=latest-unstable[Maven Central Version]] + Mill is a fast, scalable, multi-language build tool that supports Java, Scala, -and Kotlin: +Kotlin, and Python: * Mill can build the same Java codebase xref:comparisons/maven.adoc[4-10x faster than Maven], or xref:comparisons/gradle.adoc[2-4x faster than Gradle] +* Mill comes builtin with all the tools needed to develop and publish your project without +needing plugins + * Mill's typed config language and immutable xref:depth/design-principles.adoc[task graph] helps keep builds clean and understandable -* Mill is an easier alternative to https://bazel.build/[Bazel] -for xref:large/large.adoc[large multi-language monorepos] with hundreds of modules +* Mill scales well from small projects to +xref:large/large.adoc[large multi-language monorepos] with hundreds of modules To get started using Mill, see: @@ -21,11 +26,12 @@ To get started using Mill, see: Or see the language-specific introductory documentation linked below: -[cols="1a,1a,1a"] +[cols="1a,1a,1a,1a"] |=== | xref:javalib/intro.adoc[image:index/iconscout-java.svg[java,32] Java with Mill] | xref:scalalib/intro.adoc[image:index/iconscout-scala.svg[scala,20] Scala with Mill] -| xref:kotlinlib/intro.adoc[image:index/iconscout-kotlin.svg[kotlin,32] Kotlin with Mill] +| xref:kotlinlib/intro.adoc[image:index/iconscout-kotlin.svg[kotlin,28] Kotlin with Mill] +| xref:pythonlib/intro.adoc[image:index/iconscout-python.svg[python,28] Python with Mill] |=== If you want to use Mill on an existing codebase, see xref:migrating/migrating.adoc[] @@ -44,8 +50,17 @@ and avoids the long configuration times seen in other tools like Gradle or SBT. xref:large/selective-execution.adoc[Selective execution] keeps CI validation times short by only running the tests necessary to validate a code change. +* *Builtins*: Mill has builtin support for most common workflows: not just compile/run/test, but also xref:javalib/linting.adoc#_autoformatting_with_palantir_java_format[autoformatting], +xref:javalib/linting.adoc#_linting_with_checkstyle[linting], +xref:javalib/publishing.adoc#_publishing_to_sonatype_maven_central[publishing], +building xref:javalib/publishing.adoc#_building_executable_assemblies[executable assemblies], +xref:javalib/publishing.adoc#_building_native_image_binaries_with_graal_vm[native binaries] +or xref:javalib/publishing.adoc#_java_installers_using_jpackage[installers], +etc. This lets you focus on your actual project and spend less time +fiddling with tooling and plugins. + * *Maintainability*: Mill's config and xref:javalib/intro.adoc#_custom_build_logic[custom logic] -is written in xref:depth/why-scala.adoc[concise type-checked Scala code], +is written in xref:depth/why-scala.adoc[concise type-checked JVM code], with an immutable xref:depth/design-principles.adoc[module tree and task graph]. This catches config issues early, and helps both humans and IDEs (xref:cli/installation-ide.adoc#_intellij[IntelliJ] or @@ -61,7 +76,7 @@ or xref:extending/writing-plugins.adoc[write plugins yourself] and publish them to Maven Central for others to use. -For a quick introduction of why you may care about Mill, see the following page: +For a quick introduction of why you may care about Mill, see: * xref:comparisons/why-mill.adoc[] * xref:comparisons/unique.adoc[] diff --git a/docs/modules/ROOT/pages/javalib/build-examples.adoc b/docs/modules/ROOT/pages/javalib/build-examples.adoc index 991c0cec76b..deabbde654e 100644 --- a/docs/modules/ROOT/pages/javalib/build-examples.adoc +++ b/docs/modules/ROOT/pages/javalib/build-examples.adoc @@ -1,7 +1,7 @@ = Java Build Examples :page-aliases: Java_Build_Examples.adoc -include::partial$gtag-config.adoc[] + == Example Builds for Real Projects diff --git a/docs/modules/ROOT/pages/javalib/dependencies.adoc b/docs/modules/ROOT/pages/javalib/dependencies.adoc index ac2c01aef22..fab4455e288 100644 --- a/docs/modules/ROOT/pages/javalib/dependencies.adoc +++ b/docs/modules/ROOT/pages/javalib/dependencies.adoc @@ -1,6 +1,6 @@ = Java Library Dependencies -include::partial$gtag-config.adoc[] + This page goes into more detail about configuring third party dependencies for `JavaModule`. diff --git a/docs/modules/ROOT/pages/javalib/intro.adoc b/docs/modules/ROOT/pages/javalib/intro.adoc index f8d5f124390..8f8edbd4037 100644 --- a/docs/modules/ROOT/pages/javalib/intro.adoc +++ b/docs/modules/ROOT/pages/javalib/intro.adoc @@ -2,7 +2,7 @@ = Building Java with Mill :page-aliases: Intro_to_Mill.adoc, Intro_to_Mill_for_Java.adoc, Java_Intro_to_Mill.adoc -include::partial$gtag-config.adoc[] + :language: Java diff --git a/docs/modules/ROOT/pages/javalib/linting.adoc b/docs/modules/ROOT/pages/javalib/linting.adoc index 316072591c1..1ac78692c02 100644 --- a/docs/modules/ROOT/pages/javalib/linting.adoc +++ b/docs/modules/ROOT/pages/javalib/linting.adoc @@ -1,7 +1,7 @@ = Linting Java Projects :page-aliases: Linting_Java_Projects.adoc -include::partial$gtag-config.adoc[] + This page will discuss common topics around enforcing the code quality of Java codebases using the Mill build tool diff --git a/docs/modules/ROOT/pages/javalib/module-config.adoc b/docs/modules/ROOT/pages/javalib/module-config.adoc index dff0272c4a9..153b1eb451d 100644 --- a/docs/modules/ROOT/pages/javalib/module-config.adoc +++ b/docs/modules/ROOT/pages/javalib/module-config.adoc @@ -1,7 +1,7 @@ = Java Module Configuration :page-aliases: Java_Module_Config.adoc -include::partial$gtag-config.adoc[] + :language: Java :language-small: java diff --git a/docs/modules/ROOT/pages/javalib/publishing.adoc b/docs/modules/ROOT/pages/javalib/publishing.adoc index 9f8616833bf..626a1ad6009 100644 --- a/docs/modules/ROOT/pages/javalib/publishing.adoc +++ b/docs/modules/ROOT/pages/javalib/publishing.adoc @@ -1,14 +1,32 @@ = Java Packaging & Publishing :page-aliases: Publishing_Java_Projects.adoc -include::partial$gtag-config.adoc[] + This page will discuss common topics around packaging and publishing your Java projects for others to use -== Customizing the Assembly +== Building Executable Assemblies include::partial$example/javalib/publishing/1-assembly-config.adoc[] +== Building Native Image Binaries with Graal VM + +include::partial$example/javalib/publishing/7-native-image.adoc[] + + +For another example building a slightly less trivial project into a Graal native +image, see below: + +include::partial$example/javalib/publishing/8-native-image-libs.adoc[] + + +== Java App and Bundles using `jlink` + +include::partial$example/javalib/publishing/5-jlink.adoc[] + +== Java Installers using `jpackage` + +include::partial$example/javalib/publishing/6-jpackage.adoc[] == Publishing Locally @@ -41,23 +59,3 @@ The `revapi` task returns the path to a directory that can be used to resolve th ==== include::partial$Publishing_Footer.adoc[] - -== Java App and Bundles using `jlink` - -include::partial$example/javalib/publishing/5-jlink.adoc[] - -== Java Installers using `jpackage` - -include::partial$example/javalib/publishing/6-jpackage.adoc[] - - -== Building Native Image with Graal VM - -include::partial$example/javalib/publishing/7-native-image.adoc[] - - -For another example building a slightly less trivial project into a Graal native -image, see below: - -include::partial$example/javalib/publishing/8-native-image-config.adoc[] - diff --git a/docs/modules/ROOT/pages/javalib/testing.adoc b/docs/modules/ROOT/pages/javalib/testing.adoc index 0890139620a..ff8fde99d47 100644 --- a/docs/modules/ROOT/pages/javalib/testing.adoc +++ b/docs/modules/ROOT/pages/javalib/testing.adoc @@ -1,7 +1,7 @@ = Testing Java Projects :page-aliases: Testing_Java_Projects.adoc -include::partial$gtag-config.adoc[] + This page will discuss common topics around working with test suites using the Mill build tool diff --git a/docs/modules/ROOT/pages/javalib/web-examples.adoc b/docs/modules/ROOT/pages/javalib/web-examples.adoc index 7d33d58f35d..76a1a612aa1 100644 --- a/docs/modules/ROOT/pages/javalib/web-examples.adoc +++ b/docs/modules/ROOT/pages/javalib/web-examples.adoc @@ -1,7 +1,7 @@ = Java Web Project Examples :page-aliases: Java_Web_Examples.adoc -include::partial$gtag-config.adoc[] + This page contains examples of using Mill as a build tool for web-applications. It covers setting up a basic backend server with a variety of server frameworks diff --git a/docs/modules/ROOT/pages/javascriptlib/dependencies.adoc b/docs/modules/ROOT/pages/javascriptlib/dependencies.adoc index 0e88c9c4792..1d0a57ea9ad 100644 --- a/docs/modules/ROOT/pages/javascriptlib/dependencies.adoc +++ b/docs/modules/ROOT/pages/javascriptlib/dependencies.adoc @@ -1,6 +1,6 @@ = Typescript Library Dependencies -include::partial$gtag-config.adoc[] + This page goes into more detail about configuring third party dependencies for `TypescriptModule`s. diff --git a/docs/modules/ROOT/pages/javascriptlib/intro.adoc b/docs/modules/ROOT/pages/javascriptlib/intro.adoc index 081b8374de8..9e29f9bd4d3 100644 --- a/docs/modules/ROOT/pages/javascriptlib/intro.adoc +++ b/docs/modules/ROOT/pages/javascriptlib/intro.adoc @@ -1,6 +1,6 @@ = Building Javascript with Mill -include::partial$gtag-config.adoc[] + :language: Typescript :language-small: typescript diff --git a/docs/modules/ROOT/pages/javascriptlib/linting.adoc b/docs/modules/ROOT/pages/javascriptlib/linting.adoc new file mode 100644 index 00000000000..e9b6a6b2f56 --- /dev/null +++ b/docs/modules/ROOT/pages/javascriptlib/linting.adoc @@ -0,0 +1,21 @@ += Linting Typescript Projects +:page-aliases: Linting_Typescript_Projects.adoc + + + +This page will discuss common topics around maintaining the code quality of Typescript +codebases using the Mill build tool + +== Linting and AutoFormatting with Eslint and Prettier + +Eslint and Prettier are tools that analyzes your Typescript source code, performing intelligent analyses and code quality checks, and is often able to automatically fix the issues that it discovers. It can also perform automated refactoring. + +include::partial$example/javascriptlib/linting/1-linting.adoc[] + +include::partial$example/javascriptlib/linting/2-autoformatting.adoc[] + +== Code Coverage with Jest, Mocha, Vitest and Jasmine + +Mill supports code coverage analysis with multiple Typescript testing frameworks. + +include::partial$example/javascriptlib/linting/3-code-coverage.adoc[] diff --git a/docs/modules/ROOT/pages/javascriptlib/module-config.adoc b/docs/modules/ROOT/pages/javascriptlib/module-config.adoc index 4e5af0731a6..8f8c29933af 100644 --- a/docs/modules/ROOT/pages/javascriptlib/module-config.adoc +++ b/docs/modules/ROOT/pages/javascriptlib/module-config.adoc @@ -1,6 +1,6 @@ = Typescript Module Configuration -include::partial$gtag-config.adoc[] + :language: Typescript :language-small: typescript diff --git a/docs/modules/ROOT/pages/javascriptlib/publishing.adoc b/docs/modules/ROOT/pages/javascriptlib/publishing.adoc index d2964358423..e004d04b09e 100644 --- a/docs/modules/ROOT/pages/javascriptlib/publishing.adoc +++ b/docs/modules/ROOT/pages/javascriptlib/publishing.adoc @@ -1,7 +1,7 @@ = Typescript Packaging & Publishing :page-aliases: Publishing_Typescript_Projects.adoc -include::partial$gtag-config.adoc[] + This page will discuss common topics around publishing your Typescript projects for others to use. diff --git a/docs/modules/ROOT/pages/javascriptlib/testing.adoc b/docs/modules/ROOT/pages/javascriptlib/testing.adoc index ce86231289b..a9542d1f069 100644 --- a/docs/modules/ROOT/pages/javascriptlib/testing.adoc +++ b/docs/modules/ROOT/pages/javascriptlib/testing.adoc @@ -1,6 +1,6 @@ = Testing Typescript Projects -include::partial$gtag-config.adoc[] + This page will discuss common topics around working with test suites using the Mill build tool diff --git a/docs/modules/ROOT/pages/kotlinlib/build-examples.adoc b/docs/modules/ROOT/pages/kotlinlib/build-examples.adoc index 7b20349bcea..7e17838a96b 100644 --- a/docs/modules/ROOT/pages/kotlinlib/build-examples.adoc +++ b/docs/modules/ROOT/pages/kotlinlib/build-examples.adoc @@ -1,5 +1,5 @@ = (TODO) Kotlin Build Examples :page-aliases: Kotlin_Build_Examples.adoc -include::partial$gtag-config.adoc[] + diff --git a/docs/modules/ROOT/pages/kotlinlib/dependencies.adoc b/docs/modules/ROOT/pages/kotlinlib/dependencies.adoc index 9670e311702..92c8d79084b 100644 --- a/docs/modules/ROOT/pages/kotlinlib/dependencies.adoc +++ b/docs/modules/ROOT/pages/kotlinlib/dependencies.adoc @@ -1,6 +1,6 @@ = Kotlin Library Dependencies -include::partial$gtag-config.adoc[] + This page goes into more detail about the various configuration options for `KotlinModule`. diff --git a/docs/modules/ROOT/pages/kotlinlib/intro.adoc b/docs/modules/ROOT/pages/kotlinlib/intro.adoc index 6de8bc33ee7..95d0c3d62fd 100644 --- a/docs/modules/ROOT/pages/kotlinlib/intro.adoc +++ b/docs/modules/ROOT/pages/kotlinlib/intro.adoc @@ -2,7 +2,7 @@ = Building Kotlin with Mill :page-aliases: Kotlin_Intro_to_Mill.adoc -include::partial$gtag-config.adoc[] + :language: Kotlin :language-small: kotlin diff --git a/docs/modules/ROOT/pages/kotlinlib/linting.adoc b/docs/modules/ROOT/pages/kotlinlib/linting.adoc index 3eaa8331535..132004cd2f3 100644 --- a/docs/modules/ROOT/pages/kotlinlib/linting.adoc +++ b/docs/modules/ROOT/pages/kotlinlib/linting.adoc @@ -1,7 +1,7 @@ = Linting Kotlin Projects :page-aliases: Linting_Kotlin_Projects.adoc -include::partial$gtag-config.adoc[] + This page will discuss common topics around enforcing the code quality of Kotlin codebases using the Mill build tool diff --git a/docs/modules/ROOT/pages/kotlinlib/module-config.adoc b/docs/modules/ROOT/pages/kotlinlib/module-config.adoc index 51747e47cfa..aa16e54e570 100644 --- a/docs/modules/ROOT/pages/kotlinlib/module-config.adoc +++ b/docs/modules/ROOT/pages/kotlinlib/module-config.adoc @@ -1,7 +1,7 @@ = Kotlin Module Configuration :page-aliases: Kotlin_Module_Config.adoc -include::partial$gtag-config.adoc[] + :language: Kotlin :language-small: kotlin diff --git a/docs/modules/ROOT/pages/kotlinlib/publishing.adoc b/docs/modules/ROOT/pages/kotlinlib/publishing.adoc index 4547af5c037..c72036378f9 100644 --- a/docs/modules/ROOT/pages/kotlinlib/publishing.adoc +++ b/docs/modules/ROOT/pages/kotlinlib/publishing.adoc @@ -1,15 +1,23 @@ = Kotlin Packaging & Publishing :page-aliases: Publishing_Kotlin_Projects.adoc -include::partial$gtag-config.adoc[] + This page will discuss common topics around packaging and publishing your Kotlin projects for others to use -== Customizing the Assembly +== Building Executable Assemblies include::partial$example/kotlinlib/publishing/1-assembly-config.adoc[] +== Building Native Image Binaries with Graal VM + +include::partial$example/kotlinlib/publishing/7-native-image.adoc[] + +For another example building a slightly less trivial project into a Graal native +image, see below: + +include::partial$example/kotlinlib/publishing/8-native-image-libs.adoc[] == Publishing Locally @@ -27,6 +35,3 @@ For more details, see: * xref:javalib/publishing.adoc#_java_app_and_bundles_using_jlink[Java App and Bundles using JLink] * xref:javalib/publishing.adoc#_java_installers_using_jpackage[Java Installers using JPackage] -== Building Native Image with Graal VM - -include::partial$example/kotlinlib/publishing/7-native-image.adoc[] diff --git a/docs/modules/ROOT/pages/kotlinlib/testing.adoc b/docs/modules/ROOT/pages/kotlinlib/testing.adoc index ae8c7b25218..8c4c8500d32 100644 --- a/docs/modules/ROOT/pages/kotlinlib/testing.adoc +++ b/docs/modules/ROOT/pages/kotlinlib/testing.adoc @@ -1,7 +1,7 @@ = Testing Kotlin Projects :page-aliases: Testing_Kotlin_Projects.adoc -include::partial$gtag-config.adoc[] + This page will discuss common topics around working with test suites using the Mill build tool diff --git a/docs/modules/ROOT/pages/kotlinlib/web-examples.adoc b/docs/modules/ROOT/pages/kotlinlib/web-examples.adoc index b9a9586e851..d82473b07ff 100644 --- a/docs/modules/ROOT/pages/kotlinlib/web-examples.adoc +++ b/docs/modules/ROOT/pages/kotlinlib/web-examples.adoc @@ -1,6 +1,6 @@ = Kotlin Web Project Examples -include::partial$gtag-config.adoc[] + This page contains examples of using Mill as a build tool for web-applications. It covers setting up a basic backend server with a variety of server frameworks diff --git a/docs/modules/ROOT/pages/large/multi-file-builds.adoc b/docs/modules/ROOT/pages/large/multi-file-builds.adoc index b2f363c51d3..d40b940ed24 100644 --- a/docs/modules/ROOT/pages/large/multi-file-builds.adoc +++ b/docs/modules/ROOT/pages/large/multi-file-builds.adoc @@ -1,7 +1,7 @@ = Multi-File Builds :page-aliases: Structuring_Large_Builds.adoc -include::partial$gtag-config.adoc[] + include::partial$example/large/multi/10-multi-file-builds.adoc[] diff --git a/docs/modules/ROOT/pages/large/selective-execution.adoc b/docs/modules/ROOT/pages/large/selective-execution.adoc index f6da91ea78d..35642d48a55 100644 --- a/docs/modules/ROOT/pages/large/selective-execution.adoc +++ b/docs/modules/ROOT/pages/large/selective-execution.adoc @@ -1,6 +1,6 @@ = Selective Test Execution -include::partial$gtag-config.adoc[] + include::partial$example/large/selective/9-selective-execution.adoc[] diff --git a/docs/modules/ROOT/pages/migrating/gradle.adoc b/docs/modules/ROOT/pages/migrating/gradle.adoc index e86df29abeb..c61037650d0 100644 --- a/docs/modules/ROOT/pages/migrating/gradle.adoc +++ b/docs/modules/ROOT/pages/migrating/gradle.adoc @@ -2,7 +2,7 @@ :page-aliases: Migrating_A_Gradle_Build_to_Mill.adoc :icons: font -include::partial$gtag-config.adoc[] + The Mill `init` command can be used to convert a Gradle build to Mill. This has xref:#limitations[limitations] and is not intended to reliably migrate 100% of diff --git a/docs/modules/ROOT/pages/migrating/maven.adoc b/docs/modules/ROOT/pages/migrating/maven.adoc index a054e593c74..8ae66a0013c 100644 --- a/docs/modules/ROOT/pages/migrating/maven.adoc +++ b/docs/modules/ROOT/pages/migrating/maven.adoc @@ -2,7 +2,7 @@ :page-aliases: Migrating_A_Maven_Build_to_Mill.adoc :icons: font -include::partial$gtag-config.adoc[] + The Mill `init` command can be used to convert a Maven build to Mill. This has xref:#limitations[limitations] and is not intended to reliably migrate 100% of @@ -18,7 +18,7 @@ This means that while small projects can be expected to complete without issue: include::partial$example/javalib/migrating/1-maven-complete.adoc[] -More larger projects often require some manual tweaking in order to work: +Larger projects often require some manual tweaking in order to work: include::partial$example/javalib/migrating/2-maven-incomplete.adoc[] diff --git a/docs/modules/ROOT/pages/migrating/migrating.adoc b/docs/modules/ROOT/pages/migrating/migrating.adoc index fee3802ef28..96c9596e494 100644 --- a/docs/modules/ROOT/pages/migrating/migrating.adoc +++ b/docs/modules/ROOT/pages/migrating/migrating.adoc @@ -1,6 +1,6 @@ = Migrating to Mill -include::partial$gtag-config.adoc[] + This page documents a playbook for migrating existing projects from Maven, Gradle, or SBT to Mill. @@ -290,7 +290,7 @@ and understandability of your build system, and while you may not want to apply front during the migration, once you have everything working you can go back and revisit to see which ones may help: -* xref:fundamentals/modules.adoc#_trait_modules[Trait Modules] to centralize common config +* xref:fundamentals/modules.adoc#_module_traits[Trait Modules] to centralize common config * xref:large/multi-file-builds.adoc[Multi-File Builds] to let you co-locate build logic and the code being built diff --git a/docs/modules/ROOT/pages/pythonlib/dependencies.adoc b/docs/modules/ROOT/pages/pythonlib/dependencies.adoc index 79e946ce869..7806e25cfd4 100644 --- a/docs/modules/ROOT/pages/pythonlib/dependencies.adoc +++ b/docs/modules/ROOT/pages/pythonlib/dependencies.adoc @@ -1,10 +1,10 @@ = Python Library Dependencies -include::partial$gtag-config.adoc[] + This page goes into more detail about configuring third party dependencies -for `PythonModule`s. +for ``PythonModule``s. == Adding Dependencies diff --git a/docs/modules/ROOT/pages/pythonlib/intro.adoc b/docs/modules/ROOT/pages/pythonlib/intro.adoc index c6a4a46e8ee..7e1372f31a8 100644 --- a/docs/modules/ROOT/pages/pythonlib/intro.adoc +++ b/docs/modules/ROOT/pages/pythonlib/intro.adoc @@ -1,7 +1,7 @@ = Building Python with Mill -include::partial$gtag-config.adoc[] + :language: python @@ -9,6 +9,16 @@ include::partial$gtag-config.adoc[] include::partial$Intro_Header.adoc[] +NOTE: Mill's Python support is still under active development, and you can expect +the APIs to evolve over time. Nevertheless, it is complete enough to support most +common tasks like xref:pythonlib/dependencies.adoc[downloading dependencies from PyPI], +xref:pythonlib/testing.adoc[running tests], +xref:pythonlib/publishing.adoc[publishing libraries] or +xref:pythonlib/web-examples.adoc[running web apps], while providing build-tool benefits +like automatic build-time parallelism, caching, and xref:large/selective-execution.adoc[Selective Test Execution] +that especially benefit large multi-module codebases and monorepos. +Please try it out and let us know on Github if you hit any issues! + == Simple Python Module include::partial$example/pythonlib/basic/1-simple.adoc[] diff --git a/docs/modules/ROOT/pages/pythonlib/module-config.adoc b/docs/modules/ROOT/pages/pythonlib/module-config.adoc index 460318c60f4..2854f26e14f 100644 --- a/docs/modules/ROOT/pages/pythonlib/module-config.adoc +++ b/docs/modules/ROOT/pages/pythonlib/module-config.adoc @@ -1,7 +1,7 @@ = Python Module Configuration :page-aliases: Python_Module_Config.adoc -include::partial$gtag-config.adoc[] + :language: Python :language-small: python diff --git a/docs/modules/ROOT/pages/pythonlib/publishing.adoc b/docs/modules/ROOT/pages/pythonlib/publishing.adoc index 5671b0dddf7..4a9a8f72347 100644 --- a/docs/modules/ROOT/pages/pythonlib/publishing.adoc +++ b/docs/modules/ROOT/pages/pythonlib/publishing.adoc @@ -1,7 +1,7 @@ = Python Packaging & Publishing :page-aliases: Publishing_Python_Projects.adoc -include::partial$gtag-config.adoc[] + This page will discuss common topics around publishing your Python projects for others to use. diff --git a/docs/modules/ROOT/pages/pythonlib/testing.adoc b/docs/modules/ROOT/pages/pythonlib/testing.adoc index 64118b3f103..cfca44c7a41 100644 --- a/docs/modules/ROOT/pages/pythonlib/testing.adoc +++ b/docs/modules/ROOT/pages/pythonlib/testing.adoc @@ -1,7 +1,7 @@ = Testing Python Projects :page-aliases: Testing_Python_Projects.adoc -include::partial$gtag-config.adoc[] + This page will discuss topics around defining and running Python tests using the Mill build tool diff --git a/docs/modules/ROOT/pages/pythonlib/web-examples.adoc b/docs/modules/ROOT/pages/pythonlib/web-examples.adoc index 5118e2a3220..8a050f18553 100644 --- a/docs/modules/ROOT/pages/pythonlib/web-examples.adoc +++ b/docs/modules/ROOT/pages/pythonlib/web-examples.adoc @@ -1,7 +1,7 @@ = Python Web Project Examples :page-aliases: Python_Web_Examples.adoc -include::partial$gtag-config.adoc[] + This page provides examples of using Mill as a build tool for Python web applications. It includes setting up a basic "Hello, World!" application and developing a fully diff --git a/docs/modules/ROOT/pages/reference/changelog.adoc b/docs/modules/ROOT/pages/reference/changelog.adoc deleted file mode 100644 index b19731564a6..00000000000 --- a/docs/modules/ROOT/pages/reference/changelog.adoc +++ /dev/null @@ -1,10 +0,0 @@ -// Commented out because it gets picked up from the include below -// == Changelog -:page-aliases: Changelog.adoc - - -include::partial$project-changelog.adoc[tag=changelog,leveloffset=-1] - -include::partial$project-changelog.adoc[tag=changelogOld,leveloffset=-1] - -include::partial$gtag-config.adoc[] \ No newline at end of file diff --git a/docs/modules/ROOT/pages/reference/talks-blog-posts.adoc b/docs/modules/ROOT/pages/reference/talks-blog-posts.adoc new file mode 100644 index 00000000000..ada7d8581d0 --- /dev/null +++ b/docs/modules/ROOT/pages/reference/talks-blog-posts.adoc @@ -0,0 +1,18 @@ += Talks & Blog Posts + +This page lists the external talks and blog posts that discuss Mill. + +== Talks + +* https://www.youtube.com/watch?v=MEPtepNWHs8[Mill, a JVM Build Tool based on Pure Functional Programming], 24 Jan 2025 +* https://www.youtube.com/watch?v=igarEERjUuQ[Better Scala Builds with the Mill Vuild Tool], Functional Scala Online 5 Dec 2024 +* https://www.youtube.com/watch?v=xbGG7MDWR-M[Better Scala Builds with the Mill Vuild Tool], Scala.IO Paris 8 Nov 2024 +* https://www.youtube.com/watch?v=Dry6wMRN6MI&t=34s[Better Java Builds with the Mill Build Tool], Japan Java User Group Winter Conference Tokyo 27 Oct 2024 +* https://www.youtube.com/watch?v=UsXgCeU-ovI[A Deep Dive into the Mill Build Tool], Scaladays Madrid 13 Sep 2023 +* https://www.youtube.com/watch?v=j6uThGxx-18[Mill a Build Tool based on Pure Functional Programming], Scala Love Online 18 Apr 2020 + +== Blog Posts + +* https://www.lihaoyi.com/post/SoWhatsSoSpecialAboutTheMillScalaBuildTool.html[What's So Special About The Mill Scala Build Tool?] +* http://www.lihaoyi.com/post/BuildToolsasPureFunctionalPrograms.html[Build Tools as Pure Functional Programs] +* http://www.lihaoyi.com/post/SowhatswrongwithSBT.html[So, what's wrong with SBT?] diff --git a/docs/modules/ROOT/pages/scalalib/build-examples.adoc b/docs/modules/ROOT/pages/scalalib/build-examples.adoc index da0e19283b5..c76df693e5b 100644 --- a/docs/modules/ROOT/pages/scalalib/build-examples.adoc +++ b/docs/modules/ROOT/pages/scalalib/build-examples.adoc @@ -1,7 +1,7 @@ = Scala Build Examples :page-aliases: Scala_Build_Examples.adoc -include::partial$gtag-config.adoc[] + diff --git a/docs/modules/ROOT/pages/scalalib/dependencies.adoc b/docs/modules/ROOT/pages/scalalib/dependencies.adoc index 902d8b7be15..54c860037fe 100644 --- a/docs/modules/ROOT/pages/scalalib/dependencies.adoc +++ b/docs/modules/ROOT/pages/scalalib/dependencies.adoc @@ -1,6 +1,6 @@ = Scala Library Dependencies -include::partial$gtag-config.adoc[] + This page goes into more detail about configuring third party dependencies @@ -35,3 +35,87 @@ include::partial$example/scalalib/dependencies/4-downloading-unmanaged-jars.adoc == Repository Config include::partial$example/scalalib/dependencies/5-repository-config.adoc[] + + +== Scala Dependencies In Detail + +Scala major releases up until version `2.13` are binary incompatible. +That means, mixing dependencies of different binary platforms will result in non-working runtimes and obscure and hard to debug issues. + +To easily pick only a compatible version, a convention was established to append the scala major version as a suffix to the package name.footnote:[ +Scala 2 versions have the unusual version format: `{epoch}.{major}.{minor}`.] +E.g. to select the Scala 2.13 version of a library `foo`, the final `artifactId` will contain the additional suffix `_2.13`, such that the final `artifactId` is `foo_2.13`. + +To always pick the right version and support cross compiling, +you can omit the scala version and instead use a double colon (`::`) between the `organization` and the `name`, e.g. `ivy"com.typesafe.akka:akka-actor_2.12:2.5.25"`. +Your module needs to `extends ScalaModule` though. + +If you want to use dependencies that are cross-published against the full Scala version, e.g. `2.12.12`, +you can use three colons (`:::`) between `organization` and `name`, e.g.: `ivy"org.scalamacros:::paradise:2.1.1"`. + +.Example +[source,scala] +---- +def ivyDeps = Agg( + // explicit scala version suffix, NOT RECOMMENDED! + ivy"com.typesafe.akka:akka-actor_2.12:2.5.25", + ivy"com.typesafe.akka::akka-actor:2.5.25", + ivy"org.scalamacros:::paradise:2.1.1" +) +---- + +=== Scala 3 interoperability + +Since the release of Scala 3, the binary compatibility story for Scala has changed. +That means, Scala 3 dependencies can be mixed with Scala 2.13 dependencies. +In fact, the Scala 3 standard library is the same as for Scala 2.13. + + +[CAUTION] +-- +As Scala 3 and Scala 2.13 have different binary platforms, but their artifacts are in general compatible, this introduces new challenges. + +There is currently no mechanism to bring the same dependency twice into the classpath (one for Scala 2.13 and one for Scala 3). +-- + + +=== Using Scala 2.13 from Scala 3 + +If your Scala version is a Scala 3.x, but you want to use the Scala 2.13 version of a specific library, you can use the `.withDottyCompat` method on that dependency. + +.Example: +[source,scala] +---- +def scalaVersion = "3.2.1" +def ivyDeps = Agg( + ivy"com.lihaoyi::upickle:2.0.0".withDottyCompat(scalaVersion()) //1 +) +---- +<1> This will result in a Scala 2.13 dependency `com.lihaoyi::upicke_2.13:2.0.0` + + +[NOTE] +-- +Do you wonder where the name "dotty" comes from? + +In the early development of Scala 3, the Scala 3 compiler was called "Dotty". Later, the name was changed to Scala 3, but the compiler project itself is still named "dotty". + +The dotty compiler itself is an implementation of the http://lampwww.epfl.ch/~amin/dot/fool.pdf[Dependent Object Types (DOT) calculus], which is the new basis of Scala 3. It also enhances the type system to a next level and allows features like union-types and intersection-types. +-- + +=== ScalaJS dependencies + +Scala.js introduces an additional binary platform axis. +To the already required Scala version, there comes the Scala.js version. + +You can use two colons (`::`) between `name` and `version` to define a Scala.js dependency. +Your module needs to `extends ScalaJSModule` to accept Scala.js dependencies. + +=== Scala Native dependencies + +Scala Native introduces an additional binary platform axis. +To the already required Scala version, there comes the Scala Native version. + +You can use two colons (`::`) between `name` and `version` to define a Scala Native dependency. +Your module needs to `extends ScalaNativeModule` to accept Scala Native dependencies. + diff --git a/docs/modules/ROOT/pages/scalalib/intro.adoc b/docs/modules/ROOT/pages/scalalib/intro.adoc index 21db19866b6..9c078435518 100644 --- a/docs/modules/ROOT/pages/scalalib/intro.adoc +++ b/docs/modules/ROOT/pages/scalalib/intro.adoc @@ -2,7 +2,7 @@ = Building Scala with Mill :page-aliases: Intro_to_Mill_for_Scala.adoc, Scala_Intro_to_Mill.adoc -include::partial$gtag-config.adoc[] + :language: Scala :language-small: scala diff --git a/docs/modules/ROOT/pages/scalalib/linting.adoc b/docs/modules/ROOT/pages/scalalib/linting.adoc index 58c06ede50b..0aee3ddad30 100644 --- a/docs/modules/ROOT/pages/scalalib/linting.adoc +++ b/docs/modules/ROOT/pages/scalalib/linting.adoc @@ -1,7 +1,7 @@ = Linting Scala Projects :page-aliases: Linting_Scala_Projects.adoc -include::partial$gtag-config.adoc[] + This page will discuss common topics around maintaining the code quality of Scala codebases using the Mill build tool diff --git a/docs/modules/ROOT/pages/scalalib/module-config.adoc b/docs/modules/ROOT/pages/scalalib/module-config.adoc index a881dc814d1..85fbf789c7a 100644 --- a/docs/modules/ROOT/pages/scalalib/module-config.adoc +++ b/docs/modules/ROOT/pages/scalalib/module-config.adoc @@ -1,7 +1,7 @@ = Scala Module Configuration :page-aliases: Configuring_Mill.adoc, Scala_Module_Config.adoc -include::partial$gtag-config.adoc[] + :language: Scala :language-small: scala diff --git a/docs/modules/ROOT/pages/scalalib/publishing.adoc b/docs/modules/ROOT/pages/scalalib/publishing.adoc index d315e3f1ab7..3ec8d84bffe 100644 --- a/docs/modules/ROOT/pages/scalalib/publishing.adoc +++ b/docs/modules/ROOT/pages/scalalib/publishing.adoc @@ -1,16 +1,25 @@ = Scala Packaging & Publishing :page-aliases: Publishing_Scala_Projects.adoc -include::partial$gtag-config.adoc[] -This page will discuss common topics around packaging and publishing your Scala projects for others to use +This page will discuss common topics around packaging and publishing your Scala projects for others to use -== Customizing the Assembly +== Building Executable Assemblies include::partial$example/scalalib/publishing/1-assembly-config.adoc[] +== Building Native Image Binaries with Graal VM + +include::partial$example/scalalib/publishing/7-native-image.adoc[] + +For another example building a slightly less trivial project into a Graal native +image, see below: + +include::partial$example/scalalib/publishing/8-native-image-libs.adoc[] + + == Publishing Locally include::partial$example/scalalib/publishing/2-publish-module.adoc[] @@ -26,7 +35,3 @@ For more details, see: * xref:javalib/publishing.adoc#_java_app_and_bundles_using_jlink[Java App and Bundles using JLink] * xref:javalib/publishing.adoc#_java_installers_using_jpackage[Java Installers using JPackage] - -== Building Native Image with Graal VM - -include::partial$example/scalalib/publishing/7-native-image.adoc[] diff --git a/docs/modules/ROOT/pages/scalalib/testing.adoc b/docs/modules/ROOT/pages/scalalib/testing.adoc index 8cccab792b7..a0447d39ce0 100644 --- a/docs/modules/ROOT/pages/scalalib/testing.adoc +++ b/docs/modules/ROOT/pages/scalalib/testing.adoc @@ -1,7 +1,7 @@ = Testing Scala Projects :page-aliases: Testing_Scala_Projects.adoc -include::partial$gtag-config.adoc[] + This page will discuss common topics around working with test suites using the Mill build tool diff --git a/docs/modules/ROOT/pages/scalalib/web-examples.adoc b/docs/modules/ROOT/pages/scalalib/web-examples.adoc index f448f3b4bf8..9e4be2f9c28 100644 --- a/docs/modules/ROOT/pages/scalalib/web-examples.adoc +++ b/docs/modules/ROOT/pages/scalalib/web-examples.adoc @@ -1,7 +1,7 @@ = Scala Web Project Examples :page-aliases: Web_Build_Examples.adoc, Scala_Web_Examples.adoc -include::partial$gtag-config.adoc[] + This page contains examples of using Mill as a build tool for web-applications. diff --git a/docs/modules/ROOT/partials/Intro_Header.adoc b/docs/modules/ROOT/partials/Intro_Header.adoc index 3ad1bf90e41..2364fd07cd9 100644 --- a/docs/modules/ROOT/partials/Intro_Header.adoc +++ b/docs/modules/ROOT/partials/Intro_Header.adoc @@ -1,9 +1,11 @@ This page contains a quick introduction to getting start with using Mill to build -a simple {language} program. We will walk through a series of Mill builds of increasing +a simple {language} program. It walks through a series of Mill builds of increasing complexity to show you the key features and usage of the Mill build tool. -The other pages of this section on {language} go into more depth into individual features, +The other pages of this section of the documentation go into more depth into individual features, with more examples of how to use Mill for {language} and more details of how the Mill build tool works. They aren't intended to be read comprehensively top-to-bottom, but -rather looked up when you have a particular interest e.g. in testing, linting, -publishing, and so on. \ No newline at end of file +rather looked up when you have a particular interest e.g. in +xref:{language-small}lib/testing.adoc[testing], +xref:{language-small}lib/publishing.adoc[publishing], +xref:{language-small}lib/web-examples.adoc[web dev], and so on. \ No newline at end of file diff --git a/docs/modules/ROOT/partials/gtag-config.adoc b/docs/modules/ROOT/partials/gtag-config.adoc deleted file mode 100644 index 6f6f521b0e4..00000000000 --- a/docs/modules/ROOT/partials/gtag-config.adoc +++ /dev/null @@ -1,22 +0,0 @@ -++++ - - -++++ diff --git a/docs/package.mill b/docs/package.mill index 110a761c50d..f7e829545e5 100644 --- a/docs/package.mill +++ b/docs/package.mill @@ -31,7 +31,7 @@ object `package` extends RootModule { private val npmExe = if (scala.util.Properties.isWin) "npm.cmd" else "npm" private val antoraExe = if (scala.util.Properties.isWin) "antora.cmd" else "antora" - def npmBase: T[os.Path] = T.persistent { T.dest } + def npmBase: T[os.Path] = Task(persistent = true) { Task.dest } def prepareAntora(npmDir: os.Path) = { Jvm.runSubprocess( commandArgs = Seq( @@ -64,19 +64,19 @@ object `package` extends RootModule { PathRef(workDir / "build" / "site") } - def source0 = T.source(millSourcePath) - def projectChangelog = T.source(T.workspace / "changelog.adoc") + def source0 = Task.Source(millSourcePath) + def projectChangelog = Task.Source(Task.workspace / "changelog.adoc") def source = Task { - os.copy(source0().path, T.dest, mergeFolders = true) + os.copy(source0().path, Task.dest, mergeFolders = true) - val pagesWd = T.dest / "modules" / "ROOT" / "pages" - val partialsWd = T.dest / "modules" / "ROOT" / "partials" + val pagesWd = Task.dest / "modules" / "ROOT" / "pages" + val partialsWd = Task.dest / "modules" / "ROOT" / "partials" os.copy(projectChangelog().path, partialsWd / "project-changelog.adoc", createFolders = true) val renderedExamples: Seq[(os.SubPath, PathRef)] = - T.traverse(build.example.exampleModules)(m => - T.task { + Task.traverse(build.example.exampleModules)(m => + Task.Anon { (m.millSourcePath.subRelativeTo(build.example.millSourcePath), m.rendered()) } )() @@ -87,8 +87,8 @@ object `package` extends RootModule { createFolders = true ) - val contribReadmes = T.traverse(build.contrib.contribModules)(m => - T.task { + val contribReadmes = Task.traverse(build.contrib.contribModules)(m => + Task.Anon { m.millModuleSegments.parts.last -> m.readme() } )() @@ -99,9 +99,9 @@ object `package` extends RootModule { createFolders = true ) - expandDiagramsInDirectoryAdocFile(T.dest, mill.main.VisualizeModule.classpath().map(_.path)) + expandDiagramsInDirectoryAdocFile(Task.dest, mill.main.VisualizeModule.classpath().map(_.path)) - PathRef(T.dest) + PathRef(Task.dest) } def expandDiagramsInDirectoryAdocFile(dest: os.Path, visualizeClassPath: Agg[os.Path])(implicit @@ -128,9 +128,11 @@ object `package` extends RootModule { if (inputs.isEmpty) output((p, i)) = graphvizLines.mkString("\n") else { outputLines.append("++++") + outputLines.append("
") outputLines.append("
") outputLines.append(inputs((p, i))) outputLines.append("
") + outputLines.append("
") outputLines.append("++++") } @@ -164,13 +166,13 @@ object `package` extends RootModule { } - def supplementalFiles = T.source(millSourcePath / "supplemental-ui") + def supplementalFiles = Task.Source(millSourcePath / "supplemental-ui") /** * The doc root ready to be built by antora for the current branch. */ def devAntoraSources: T[PathRef] = Task { - val dest = T.dest + val dest = Task.dest os.copy(source().path, dest, mergeFolders = true) sanitizeAntoraYml( dest, @@ -213,7 +215,7 @@ object `package` extends RootModule { expandDiagramsInDirectoryAdocFile(Task.dest, mill.main.VisualizeModule.classpath().map(_.path)) PathRef(Task.dest) } - def githubPagesPlaybookText(authorMode: Boolean) = T.task { extraSources: Seq[os.Path] => + def githubPagesPlaybookText(authorMode: Boolean) = Task.Anon { extraSources: Seq[os.Path] => val taggedSources = for (path <- extraSources) yield { s""" - url: ${build.baseDir} | start_path: ${path.relativeTo(build.baseDir)} @@ -222,7 +224,7 @@ object `package` extends RootModule { } s"""site: | title: The Mill JVM Build Tool - | url: ${if (authorMode) s"${T.dest}/site" else build.Settings.docUrl} + | url: ${if (authorMode) s"${Task.dest}/site" else build.Settings.docUrl} | start_page: mill::index.adoc | keys: | google_analytics: 'G-1C582ZJR85' @@ -253,7 +255,7 @@ object `package` extends RootModule { |asciidoc: | attributes: | mill-github-url: ${build.Settings.projectUrl} - | mill-doc-url: ${if (authorMode) s"file://${T.dest}/site" else build.Settings.docUrl} + | mill-doc-url: ${if (authorMode) s"file://${Task.dest}/site" else build.Settings.docUrl} | utest-github-url: https://github.com/com-lihaoyi/utest | upickle-github-url: https://github.com/com-lihaoyi/upickle | mill-scip-version: ${build.Deps.DocDeps.millScip.dep.version} @@ -279,8 +281,8 @@ object `package` extends RootModule { Seq((build.Settings.docTags.last, "master", s"latest-${build.Settings.docTags.last}")) for ((millLastTag, version, displayVersion) <- versionLabels) yield { - val checkout = T.dest / displayVersion - os.proc("git", "clone", T.workspace / ".git", checkout).call(stdout = os.Inherit) + val checkout = Task.dest / displayVersion + os.proc("git", "clone", Task.workspace / ".git", checkout).call(stdout = os.Inherit) os.proc("git", "checkout", millLastTag).call(cwd = checkout, stdout = os.Inherit) val outputFolder = checkout / "out" / "docs" / "source.dest" os.proc("./mill", "-i", "docs.source").call(cwd = checkout, stdout = os.Inherit) @@ -311,24 +313,24 @@ object `package` extends RootModule { def localPages: T[PathRef] = Task { val pages = generatePages(authorMode = true)().apply(oldDocSources().map(_.path)) - T.log.outputStream.println( + Task.log.outputStream.println( s"You can browse the pages at: ${(pages.path / "index.html").toNIO.toUri()}" ) pages } def fastPages: T[PathRef] = Task { val pages = generatePages(authorMode = true)().apply(Nil) - T.log.outputStream.println( + Task.log.outputStream.println( s"You can browse the pages at: ${(pages.path / "index.html").toNIO.toUri()}" ) pages } def generatePages(authorMode: Boolean) = Task.Anon { extraSources: Seq[os.Path] => - T.log.errorStream.println("Creating Antora playbook ...") + Task.log.errorStream.println("Creating Antora playbook ...") // dependency to sources source() - val docSite = T.dest + val docSite = Task.dest val playbook = docSite / "antora-playbook.yml" val siteDir = docSite / "site" os.write( @@ -336,7 +338,7 @@ object `package` extends RootModule { data = githubPagesPlaybookText(authorMode)().apply(extraSources), createFolders = true ) - T.log.errorStream.println("Running Antora ...") + Task.log.errorStream.println("Running Antora ...") runAntora( npmDir = npmBase(), workDir = docSite, @@ -352,12 +354,12 @@ object `package` extends RootModule { os.write(siteDir / ".nojekyll", "") // sanitize devAntora source URLs - T.log.errorStream.println("Sanitizing links ...") + Task.log.errorStream.println("Sanitizing links ...") sanitizeDevUrls(siteDir, devAntoraSources().path, build.baseDir / "docs", build.baseDir) // only copy the "api" sub-dir; api docs contains a top-level index.html with we don't want val unidocSrc = if (authorMode) site.unidocLocal().path else site.unidocSite().path - T.log.errorStream.println(s"Copying API docs from ${unidocSrc} ...") + Task.log.errorStream.println(s"Copying API docs from ${unidocSrc} ...") os.copy(unidocSrc, siteDir / "api" / "latest", createFolders = true) PathRef(siteDir) diff --git a/docs/supplemental-ui/partials/header-content.hbs b/docs/supplemental-ui/partials/header-content.hbs index 953b8867ea2..09b12900554 100644 --- a/docs/supplemental-ui/partials/header-content.hbs +++ b/docs/supplemental-ui/partials/header-content.hbs @@ -1,4 +1,50 @@
+ +