diff --git a/build.sc b/build.sc index 4fb20d20c53..dab0238e412 100644 --- a/build.sc +++ b/build.sc @@ -1185,18 +1185,65 @@ object example extends MillScalaModule { def moduleDeps = Seq(integration) object basic extends Cross[ExampleCrossModule](listIn(millSourcePath / "basic")) + object basicjava extends Cross[ExampleCrossModuleJava](listIn(millSourcePath / "basicjava")) object scalabuilds extends Cross[ExampleCrossModule](listIn(millSourcePath / "scalabuilds")) + object javabuilds extends Cross[ExampleCrossModuleJava](listIn(millSourcePath / "javabuilds")) object scalamodule extends Cross[ExampleCrossModule](listIn(millSourcePath / "scalamodule")) + object javamodule extends Cross[ExampleCrossModuleJava](listIn(millSourcePath / "javamodule")) object tasks extends Cross[ExampleCrossModule](listIn(millSourcePath / "tasks")) object cross extends Cross[ExampleCrossModule](listIn(millSourcePath / "cross")) object misc extends Cross[ExampleCrossModule](listIn(millSourcePath / "misc")) object web extends Cross[ExampleCrossModule](listIn(millSourcePath / "web")) + trait ExampleCrossModuleJava extends ExampleCrossModule { + + def upstreamCross(s: String) = s match{ + case "basicjava" => basic + case "javabuilds" => scalabuilds + case "javamodule" => scalamodule + } + + def buildScLines = T{ + val upstreamLines = os.read.lines( + upstreamCross(this.millModuleSegments.parts.dropRight(1).last)(crossValue) + .testRepoRoot().path / "build.sc" + ) + val lines = os.read.lines(testRepoRoot().path / "build.sc") + + import collection.mutable + val groupedLines = mutable.Map.empty[String, mutable.Buffer[String]] + var current = Option.empty[String] + lines.foreach{ + case s"//// SNIPPET:$name" => + current = Some(name) + groupedLines(name) = mutable.Buffer() + case s => groupedLines(current.get).append(s) + } + + upstreamLines.flatMap{ + case s"//// SNIPPET:$name" => + if (name != "END") { + + current = Some(name) + groupedLines(name) + } else{ + current = None + Nil + } + + case s => + if (current.nonEmpty) None + else Some(s) + } + } + } trait ExampleCrossModule extends IntegrationTestCrossModule { // disable scalafix because these example modules don't have sources causing it to misbehave def fix(args: String*): Command[Unit] = T.command {} def testRepoRoot: T[PathRef] = T.source(millSourcePath) def compile = example.compile() + + def buildScLines = T{ os.read.lines(testRepoRoot().path / "build.sc") } def forkEnv = super.forkEnv() ++ Map("MILL_EXAMPLE_PARSED" -> upickle.default.write(parsed())) /** @@ -1206,7 +1253,7 @@ object example extends MillScalaModule { val states = collection.mutable.Buffer("scala") val chunks = collection.mutable.Buffer(collection.mutable.Buffer.empty[String]) - for (line <- os.read.lines(testRepoRoot().path / "build.sc")) { + for (line <- buildScLines()) { val (newState, restOpt) = line match { case s"/** Usage" => ("example", None) case s"/** See Also: $path */" => @@ -1278,7 +1325,8 @@ object example extends MillScalaModule { def repoInfo = Map( "acyclic" -> ("com-lihaoyi/acyclic", "1ec221f377794db39e8ff9b43415f81c703c202f"), "fansi" -> ("com-lihaoyi/fansi", "169ac96d7c6761a72590d312a433cf12c572573c"), - "jimfs" -> ("google/jimfs", "5b60a42eb9d3cd7a2073d549bd0cb833f5a7e7e9") + "jimfs" -> ("google/jimfs", "5b60a42eb9d3cd7a2073d549bd0cb833f5a7e7e9"), + "commons-io" -> ("apache/commons-io", "b91a48074231ef813bc9b91a815d77f6343ff8f0") ) object thirdparty extends Cross[ThirdPartyModule](listIn(millSourcePath / "thirdparty")) trait ThirdPartyModule extends ExampleCrossModule { @@ -1467,6 +1515,7 @@ object dev extends MillPublishScalaModule { contrib.buildinfo.testDep(), contrib.scoverage.testDep(), contrib.scoverage.worker2.testDep(), + contrib.jmh.testDep(), contrib.playlib.testDep(), contrib.playlib.worker("2.8").testDep(), bsp.worker.testDep() @@ -1704,7 +1753,7 @@ object docs extends Module { s"""site: | title: Mill | url: ${if (authorMode) s"${T.dest}/site" else Settings.docUrl} - | start_page: mill::Intro_to_Mill.adoc + | start_page: mill::Intro_to_Mill_for_Scala.adoc | |content: | sources: @@ -1744,6 +1793,10 @@ object docs extends Module { | - require: '@antora/lunr-extension' | index_latest_only: true | + |runtime: + | log: + | failure_level: error + | |""".stripMargin } diff --git a/ci/test-mill-bootstrap.sh b/ci/test-mill-bootstrap.sh index c26bbc39437..8a178fb709b 100755 --- a/ci/test-mill-bootstrap.sh +++ b/ci/test-mill-bootstrap.sh @@ -21,4 +21,4 @@ ci/prepare-mill-bootstrap.sh # Run tests target/mill-release -i "__.compile" target/mill-release -i "{main,scalalib}.__.test" -target/mill-release -i "example.basic[1-simple-scala].server.test" +target/mill-release -i "example.basic[1-simple].server.test" diff --git a/ci/test-mill-dev.sh b/ci/test-mill-dev.sh index 4c1516e26be..0711d239759 100755 --- a/ci/test-mill-dev.sh +++ b/ci/test-mill-dev.sh @@ -2,7 +2,7 @@ set -eux -EXAMPLE=example/scalabuilds/10-scala-realistic +EXAMPLE=example/scalabuilds/9-realistic rm -rf $EXAMPLE/out diff --git a/ci/test-mill-release.sh b/ci/test-mill-release.sh index ce4436b17e5..6a0f8bf3e1a 100755 --- a/ci/test-mill-release.sh +++ b/ci/test-mill-release.sh @@ -5,7 +5,7 @@ set -eux # Build Mill ./mill -i dev.assembly -EXAMPLE=example/scalabuilds/10-scala-realistic +EXAMPLE=example/scalabuilds/9-realistic rm -rf $EXAMPLE/out diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc index 3f1254f9857..7abb9a13515 100644 --- a/docs/modules/ROOT/nav.adoc +++ b/docs/modules/ROOT/nav.adoc @@ -2,14 +2,21 @@ // do this other thing, etc. We touch on a lot of topics about how Mill works, // but we intentionally skim over them and do not go into depth: the focus is // on end user goals and how to achieve them. -.Quick Start -* xref:Intro_to_Mill.adoc[] -* xref:Installation_IDE_Support.adoc[] +.Scala Quick Start +* xref:Intro_to_Mill_for_Scala.adoc[] +* xref:Scala_Installation_IDE_Support.adoc[] * xref:Builtin_Commands.adoc[] * xref:Scala_Build_Examples.adoc[] * xref:Scala_Module_Config.adoc[] * xref:Web_Build_Examples.adoc[] +.Java Quick Start +* xref:Intro_to_Mill_for_Java.adoc[] +* xref:Java_Installation_IDE_Support.adoc[] +* xref:Java_Builtin_Commands.adoc[] +* xref:Java_Build_Examples.adoc[] +* xref:Java_Module_Config.adoc[] + // This section is all about developing a deeper understanding of specific // topics in Mill. This is the opposite of `Quick Start` above: while we touch // on some end-user use cases, it is only to motivate the Mill features that we diff --git a/docs/modules/ROOT/pages/Extending_Mill.adoc b/docs/modules/ROOT/pages/Extending_Mill.adoc index 0294fc03001..91601627082 100644 --- a/docs/modules/ROOT/pages/Extending_Mill.adoc +++ b/docs/modules/ROOT/pages/Extending_Mill.adoc @@ -57,6 +57,10 @@ include::example/misc/4-mill-build-folder.adoc[] include::example/misc/5-module-run-task.adoc[] +== Importing Contrib Modules + +include::example/misc/6-contrib-import.adoc[] + == Evaluator Commands (experimental) _Evaluator Command are experimental and suspected to change. diff --git a/docs/modules/ROOT/pages/Intro_to_Mill_for_Java.adoc b/docs/modules/ROOT/pages/Intro_to_Mill_for_Java.adoc new file mode 100644 index 00000000000..5dff93ddc3b --- /dev/null +++ b/docs/modules/ROOT/pages/Intro_to_Mill_for_Java.adoc @@ -0,0 +1,34 @@ + +// Author Notes: +// +// This is the first page a user is expected to land on when learning about +// Mill. It is designed to be a quick, broad overview to get someone started: +// what is Mill, why should they care, and what some simple Mill builds look +// like and how to use them. We intentionally touch shallowly on a lot of +// topics without giving them a proper discussion, since the other pages have +// plenty of space to go in-depth. +// +// By the end of this page, a prospective Mill user should be familiar with +// what Mill is, hopefully have downloaded an example to try out, and be +// interested in learning more about the Mill build tool + += Introduction to Mill for Java + +include::partial$Intro_to_Mill_Header.adoc[] + + +== Simple Java Module + +include::example/basicjava/1-simple.adoc[] + +== Custom Build Logic + +include::example/basicjava/2-custom-build-logic.adoc[] + +== Multi-Module Project + +include::example/basicjava/3-multi-module.adoc[] + + + +include::partial$Intro_to_Mill_Footer.adoc[] \ No newline at end of file diff --git a/docs/modules/ROOT/pages/Intro_to_Mill_for_Scala.adoc b/docs/modules/ROOT/pages/Intro_to_Mill_for_Scala.adoc new file mode 100644 index 00000000000..5172a670695 --- /dev/null +++ b/docs/modules/ROOT/pages/Intro_to_Mill_for_Scala.adoc @@ -0,0 +1,34 @@ +// Author Notes: +// +// This is the first page a user is expected to land on when learning about +// Mill. It is designed to be a quick, broad overview to get someone started: +// what is Mill, why should they care, and what some simple Mill builds look +// like and how to use them. We intentionally touch shallowly on a lot of +// topics without giving them a proper discussion, since the other pages have +// plenty of space to go in-depth. +// +// By the end of this page, a prospective Mill user should be familiar with +// what Mill is, hopefully have downloaded an example to try out, and be +// interested in learning more about the Mill build tool + += Introduction to Mill for Scala + +:page-aliases: index.adoc + +include::partial$Intro_to_Mill_Header.adoc[] + + +== Simple Scala Module + +include::example/basic/1-simple.adoc[] + +== Custom Build Logic + +include::example/basic/2-custom-build-logic.adoc[] + +== Multi-Module Project + +include::example/basic/3-multi-module.adoc[] + + +include::partial$Intro_to_Mill_Footer.adoc[] \ No newline at end of file diff --git a/docs/modules/ROOT/pages/Java_Build_Examples.adoc b/docs/modules/ROOT/pages/Java_Build_Examples.adoc new file mode 100644 index 00000000000..9fbb0ca1167 --- /dev/null +++ b/docs/modules/ROOT/pages/Java_Build_Examples.adoc @@ -0,0 +1,73 @@ += Java Build Examples + +On this page, we will explore the Mill build tool via a series of simple Java +example projects. Each project demonstrates one particular feature of the Mill +build tool, and is also an executable codebase you can download and run. By the +end of this page, you will be familiar with how to configure Mill to work with +realistic Java codebases: cross-building, testing, and publishing them. + + +Many of the APIs covered here are listed in the API documentation: + +* {mill-doc-url}/api/latest/mill/main/RootModule.html[`mill.scalalib.RootModule`] +* {mill-doc-url}/api/latest/mill/scalalib/TestModule$.html[`mill.scalalib.TestModule`] +* {mill-doc-url}/api/latest/mill/scalalib/PublishModule.html[`mill.scalalib.PublishModule`] +* {mill-doc-url}/api/latest/mill/scalalib/CrossScalaModule.html[`mill.scalalib.CrossScalaModule`] +* {mill-doc-url}/api/latest/mill/scalalib/MavenModule.html[`mill.scalalib.MavenModule`] +* {mill-doc-url}/api/latest/mill/scalalib/CrossSbtModule.html[`mill.scalalib.CrossSbtModule`] +* {mill-doc-url}/api/latest/mill/scalalib/JavaModule.html[`mill.scalalib.JavaModule`] + +== Common Configuration Overrides + +include::example/javabuilds/1-common-config.adoc[] + +== Custom Tasks + +include::example/javabuilds/2-custom-tasks.adoc[] + +== Overriding Tasks + +include::example/javabuilds/3-override-tasks.adoc[] + +== Nesting Modules + +include::example/javabuilds/4-nested-modules.adoc[] + +== Java Module With Test Suite + +include::example/javabuilds/5-test-suite.adoc[] + +== Publish Module + +include::example/javabuilds/6-publish-module.adoc[] + + +== Maven-Compatible Modules + +include::example/javabuilds/8-compat-modules.adoc[] + + +== Realistic Java Example Project + +include::example/javabuilds/9-realistic.adoc[] + + +== Example Builds for Real Projects + +Mill comes bundled with example builds for real-world open-source projects, +demonstrating how Mill can be used to build code outside of tiny example codebases: + +=== JimFS + +include::example/thirdparty/jimfs.adoc[] + +=== Apache Commons IO + +include::example/thirdparty/commons-io.adoc[] + +== Real World Mill Builds + +=== C3P0 + +https://github.com/swaldman/c3p0[C3P0] is a JDBC connection pooling library +written in Java, built using the Mill build tool. diff --git a/docs/modules/ROOT/pages/Java_Builtin_Commands.adoc b/docs/modules/ROOT/pages/Java_Builtin_Commands.adoc new file mode 100644 index 00000000000..e60e3901759 --- /dev/null +++ b/docs/modules/ROOT/pages/Java_Builtin_Commands.adoc @@ -0,0 +1,85 @@ += Built-in Commands + +Mill comes with a number of useful commands out of the box. These are listed +in the Scaladoc: + +* {mill-doc-url}/api/latest/mill/main/MainModule.html[mill.main.MainModule] + +Mill's built-in commands are typically not directly related to building your +application code, but instead are utilities that help you understand and work +with your Mill build. + +include::example/basicjava/4-builtin-commands.adoc[] + +== visualize + +[source,bash] +---- +$ mill show visualize foo._ +[ + ".../out/visualize.dest/out.txt", + ".../out/visualize.dest/out.dot", + ".../out/visualize.dest/out.json", + ".../out/visualize.dest/out.png", + ".../out/visualize.dest/out.svg" +] +---- + +`mill show visualize` takes a subset of the Mill build graph (e.g. `+core._+` +is every task directly under the `core` module) and draws out their +relationships in `.svg` and `.png` form for you to inspect. It also generates +`.txt`, `.dot` and `.json` for easy processing by downstream tools. + +The above command generates the following diagram: + +image::VisualizeFoo.svg[VisualizeFoo.svg] + +`visualize` can be very handy for trying to understand the dependency graph of +tasks within your Mill build. + +== visualizePlan + +[source,bash] +---- +$ mill show visualizePlan foo.compile +[ + ".../out/visualizePlan.dest/out.txt", + ".../out/visualizePlan.dest/out.dot", + ".../out/visualizePlan.dest/out.json", + ".../out/visualizePlan.dest/out.png", + ".../out/visualizePlan.dest/out.svg" +] +---- + +`mill show visualizePlan` is similar to `mill show visualize` except that it +shows a graph of the entire build plan, including tasks not directly resolved +by the query. Tasks directly resolved are shown with a solid border, and +dependencies are shown with a dotted border. + +The above command generates the following diagram: + +image::VisualizeCompile.svg[VisualizeCompile.svg] + +== Running Mill with custom JVM options + +It's possible to pass JVM options to the Mill launcher. To do this you need to +create a `.mill-jvm-opts` file in your project's root. This file should contain +JVM options, one per line. + +For example, if your build requires a lot of memory and bigger stack size, your +`.mill-jvm-opts` could look like this: + +---- +-Xss10m +-Xmx10G +---- + +The file name for passing JVM options to the Mill launcher is configurable. If +for some reason you don't want to use `.mill-jvm-opts` file name, add +`MILL_JVM_OPTS_PATH` environment variable with any other file name. + + +--- + +Come by our https://discord.com/channels/632150470000902164/940067748103487558[Discord Channel] +if you want to ask questions or say hi! diff --git a/docs/modules/ROOT/pages/Java_Installation_IDE_Support.adoc b/docs/modules/ROOT/pages/Java_Installation_IDE_Support.adoc new file mode 100644 index 00000000000..951ea10b6bf --- /dev/null +++ b/docs/modules/ROOT/pages/Java_Installation_IDE_Support.adoc @@ -0,0 +1,3 @@ += Installation and IDE Support + +include::partial$Installation_IDE_Support.adoc[] \ No newline at end of file diff --git a/docs/modules/ROOT/pages/Java_Module_Config.adoc b/docs/modules/ROOT/pages/Java_Module_Config.adoc new file mode 100644 index 00000000000..f9f0d3f900f --- /dev/null +++ b/docs/modules/ROOT/pages/Java_Module_Config.adoc @@ -0,0 +1,75 @@ += Java Module Configuration + +This page goes into more detail about the various configuration options +for `JavaModule`. + +Many of the APIs covered here are listed in the API documentation: + +* {mill-doc-url}/api/latest/mill/scalalib/JavaModule.html[mill.scalalib.JavaModule] + + +== Compilation & Execution Flags + +include::example/javamodule/1-compilation-execution-flags.adoc[] + +== Adding Ivy Dependencies + +include::example/javamodule/2-ivy-deps.adoc[] + +== Runtime and Compile-time Dependencies + +include::example/javamodule/3-run-compile-deps.adoc[] + +== Test Dependencies + +include::example/javamodule/4-test-deps.adoc[] + + +== Javadoc Config + +include::example/javamodule/6-docjar.adoc[] + +== Unmanaged Jars + +include::example/javamodule/7-unmanaged-jars.adoc[] + +== Specifying the Main Class + +include::example/javamodule/8-main-class.adoc[] + +== Downloading Non-Maven Jars + +include::example/javamodule/9-downloading-non-maven-jars.adoc[] + +== Customizing the Assembly + +include::example/javamodule/10-assembly-config.adoc[] + +== Repository Config + +include::example/javamodule/11-repository-config.adoc[] + +== Maven Central: Blocked! + +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; + +---- +1 targets failed +mill.scalalib.ZincWorkerModule.classpath +Resolution failed for 1 modules: +-------------------------------------------- + com.lihaoyi:mill-scalalib-worker_2.13:0.11.1 + not found: C:\Users\partens\.ivy2\local\com.lihaoyi\mill-scalalib-worker_2.13\0.11.1\ivys\ivy.xml + download error: Caught java.io.IOException (Server returned HTTP response code: 503 for URL: https://repo1.maven.org/maven2/com/lihaoyi/mill-scalalib-worker_2.13/0.11.1/mill-scalalib-worker_2.13-0.11.1.pom) while downloading https://repo1.maven.org/maven2/com/lihaoyi/mill-scalalib-worker_2.13/0.11.1/mill-scalalib-worker_2.13-0.11.1.pom +---- + +It is expected that basic commands (e.g. clean) will not work, as Mill saying it is unable to resolve it's own, fundamental, dependancies. Under such circumstances, you will normally have access to some proxy, or other corporate repository which resolves maven artefacts. The strategy is simply to tell mill to use that instead. + +The idea is to set an environment variable COURSIER_REPOSITORIES (see coursier docs). The below command should set the environment variable for the current shell, and then run the mill command. + +---- + COURSIER_REPOSITORIES=https://packages.corp.com/artifactory/maven/ mill resolve _ +---- + +If you are using millw, a more permanent solution could be to set the environment variable at the top of the millw script, or as a user environment variable etc. + diff --git a/docs/modules/ROOT/pages/Modules.adoc b/docs/modules/ROOT/pages/Modules.adoc index 2f4800ff173..0a94c96c57f 100644 --- a/docs/modules/ROOT/pages/Modules.adoc +++ b/docs/modules/ROOT/pages/Modules.adoc @@ -18,6 +18,11 @@ include::example/tasks/7-modules.adoc[] include::example/tasks/8-diy-java-modules.adoc[] +== Backticked Names + +include::example/tasks/9-backticked-names.adoc[] + + == External Modules Libraries for use in Mill can define ``ExternalModule``s: ``Module``s which are diff --git a/docs/modules/ROOT/pages/Plugin_BSP.adoc b/docs/modules/ROOT/pages/Plugin_BSP.adoc index 1d23d8fe86f..2b1631be794 100644 --- a/docs/modules/ROOT/pages/Plugin_BSP.adoc +++ b/docs/modules/ROOT/pages/Plugin_BSP.adoc @@ -3,4 +3,4 @@ _The contrib.bsp plugin is no longer available. The BSP server is now integrated in Mill by default._ -Read on in the xref:Installation_IDE_Support.adoc#_build_server_protocol_bsp[Build Server Protocol] section. +Read on in the xref:Scala_Installation_IDE_Support.adoc#_build_server_protocol_bsp[Build Server Protocol] section. diff --git a/docs/modules/ROOT/pages/Scala_Build_Examples.adoc b/docs/modules/ROOT/pages/Scala_Build_Examples.adoc index da0661600c5..5f48ac20dce 100644 --- a/docs/modules/ROOT/pages/Scala_Build_Examples.adoc +++ b/docs/modules/ROOT/pages/Scala_Build_Examples.adoc @@ -48,21 +48,18 @@ include::example/scalabuilds/7-cross-scala-version.adoc[] == SBT-Compatible Modules -include::example/scalabuilds/8-sbt-compat-modules.adoc[] +include::example/scalabuilds/8-compat-modules.adoc[] -== Java Modules - -include::example/scalabuilds/9-java-modules.adoc[] == Realistic Scala Example Project -include::example/scalabuilds/10-scala-realistic.adoc[] +include::example/scalabuilds/9-realistic.adoc[] -== Example Builds +== Example Builds for Real Projects -Mill comes bundled with example builds for existing open-source projects, as -integration tests and examples: +Mill comes bundled with example builds for real-world open-source projects, +demonstrating how Mill can be used to build code outside of tiny example codebases: === Acyclic @@ -72,6 +69,19 @@ include::example/thirdparty/acyclic.adoc[] include::example/thirdparty/fansi.adoc[] -=== JimFS +== Real World Mill Builds + +=== Ammonite + +https://github.com/com-lihaoyi/Ammonite[Ammonite] is an ergonomic Scala REPL. + +=== Scala-ClI + +https://github.com/VirtusLab/scala-cli[Scala-CLI] is the primary CLI tool that +runs when you enter `scala` in the terminal. It is able to compile, test, run, +and package your Scala code in a variety of different ways + +=== Coursier -include::example/thirdparty/jimfs.adoc[] +https://github.com/coursier/coursier[Coursier] is a fast JVM dependency resolver, +used in many build tools down resolve and download third party dependencies \ No newline at end of file diff --git a/docs/modules/ROOT/pages/Scala_Installation_IDE_Support.adoc b/docs/modules/ROOT/pages/Scala_Installation_IDE_Support.adoc new file mode 100644 index 00000000000..803f81d9dd8 --- /dev/null +++ b/docs/modules/ROOT/pages/Scala_Installation_IDE_Support.adoc @@ -0,0 +1,4 @@ += Installation and IDE Support +:page-aliases: Installation.adoc, IDE_Support.adoc + +include::partial$Installation_IDE_Support.adoc[] \ No newline at end of file diff --git a/docs/modules/ROOT/pages/Scala_Module_Config.adoc b/docs/modules/ROOT/pages/Scala_Module_Config.adoc index eb85edd9a56..cfd2d57020f 100644 --- a/docs/modules/ROOT/pages/Scala_Module_Config.adoc +++ b/docs/modules/ROOT/pages/Scala_Module_Config.adoc @@ -31,7 +31,7 @@ include::example/scalamodule/5-scala-compiler-plugins.adoc[] == Scaladoc Config -include::example/scalamodule/6-scaladoc.adoc[] +include::example/scalamodule/6-docjar.adoc[] == Unmanaged Jars @@ -77,9 +77,9 @@ The idea is to set an environment variable COURSIER_REPOSITORIES (see coursier d If you are using millw, a more permanent solution could be to set the environment variable at the top of the millw script, or as a user environment variable etc. -== Backticked Names +== Scoverage -include::example/scalamodule/12-backticked-names.adoc[] +include::example/scalamodule/12-contrib-scoverage.adoc[] == Unidoc diff --git a/docs/modules/ROOT/pages/Installation_IDE_Support.adoc b/docs/modules/ROOT/partials/Installation_IDE_Support.adoc similarity index 99% rename from docs/modules/ROOT/pages/Installation_IDE_Support.adoc rename to docs/modules/ROOT/partials/Installation_IDE_Support.adoc index 44035abe2dd..9747db782a1 100644 --- a/docs/modules/ROOT/pages/Installation_IDE_Support.adoc +++ b/docs/modules/ROOT/partials/Installation_IDE_Support.adoc @@ -1,5 +1,3 @@ -= Installation and IDE Support -:page-aliases: Installation.adoc, IDE_Support.adoc The best method of installing Mill is to just install a <<_bootstrap_scripts,bootstrap script>>. This script can determine the best version to be used by a project (e.g. by diff --git a/docs/modules/ROOT/pages/Intro_to_Mill.adoc b/docs/modules/ROOT/partials/Intro_to_Mill_Footer.adoc similarity index 66% rename from docs/modules/ROOT/pages/Intro_to_Mill.adoc rename to docs/modules/ROOT/partials/Intro_to_Mill_Footer.adoc index 4ee1a2d8859..bed4b2adaec 100644 --- a/docs/modules/ROOT/pages/Intro_to_Mill.adoc +++ b/docs/modules/ROOT/partials/Intro_to_Mill_Footer.adoc @@ -1,66 +1,3 @@ -// Author Notes: -// -// This is the first page a user is expected to land on when learning about -// Mill. It is designed to be a quick, broad overview to get someone started: -// what is Mill, why should they care, and what some simple Mill builds look -// like and how to use them. We intentionally touch shallowly on a lot of -// topics without giving them a proper discussion, since the other pages have -// plenty of space to go in-depth. -// -// By the end of this page, a prospective Mill user should be familiar with -// what Mill is, hopefully have downloaded an example to try out, and be -// interested in learning more about the Mill build tool - -= Introduction to Mill -:page-aliases: index.adoc - -{mill-github-url}[Mill] is your shiny new Scala/Java build tool! Mill aims for -simplicity by reusing concepts you are already familiar with, borrowing ideas -from modern tools like https://bazel.build/[Bazel] and -https://www.scala-sbt.org/[SBT]. It lets you build your projects in a way -that's simple, fast, and predictable. - -Mill automates dealing with a lot of common build-tool concerns: Caching, -incremental re-computation, parallelism, discoverability, etc. This allows you -to focus your effort on the business logic unique to your build, while letting -Mill take care of all the rest. - -Mill has built-in support for the https://www.scala-lang.org/[Scala] -programming language, and can serve as a replacement for -http://www.scala-sbt.org/[SBT]. It can be xref:Extending_Mill.adoc[extended] -to support any other language or platform via modules (written in Java -or Scala) or through external subprocesses. Mill supports a rich ecosystem of -xref:Contrib_Plugins.adoc[] and xref:Thirdparty_Plugins.adoc[]. - -If you are using Mill, you will find the following book by the Author useful in -using Mill and its supporting libraries to the fullest: - -* https://handsonscala.com/[Hands-on Scala Programming] - -If you prefer a video introduction rather than text, the following presentation -(and companion blog post) is a good introduction into what the Mill build tool is -all about: - -- https://www.youtube.com/watch?v=UsXgCeU-ovI&list=PLLMLOC3WM2r6ZFhFfVH74W-sl8LfWtOEc&index=15[Video: A Deep Dive into the Mill Build Tool] -- https://www.lihaoyi.com/post/SoWhatsSoSpecialAboutTheMillScalaBuildTool.html[Blog Post: So, What's So Special About The Mill Scala Build Tool?] - -The rest of this page contains a quick introduction to getting start with using -Mill to build a simple Scala program. The other pages of this doc-site go into -more depth, with more examples of how to use Mill and more details of how the -Mill build tool works. - -== Simple Scala Module - -include::example/basic/1-simple-scala.adoc[] - -== Custom Build Logic - -include::example/basic/2-custom-build-logic.adoc[] - -== Multi-Module Project - -include::example/basic/3-multi-module.adoc[] - == Watch and Re-evaluate diff --git a/docs/modules/ROOT/partials/Intro_to_Mill_Header.adoc b/docs/modules/ROOT/partials/Intro_to_Mill_Header.adoc new file mode 100644 index 00000000000..34c6c6d2e82 --- /dev/null +++ b/docs/modules/ROOT/partials/Intro_to_Mill_Header.adoc @@ -0,0 +1,36 @@ + +{mill-github-url}[Mill] is your shiny new Java/Scala build tool! Mill aims for +simplicity by reusing concepts you are already familiar with, borrowing ideas +from modern tools like https://maven.apache.org/[Maven], https://gradle.org/[Gradle], +https://bazel.build/[Bazel] and https://www.scala-sbt.org/[SBT]. It lets you build +your projects in a way that's simple, fast, and predictable. + +Mill automates dealing with a lot of common build-tool concerns: Caching, +incremental re-computation, parallelism, discoverability, etc. This allows you +to focus your effort on the business logic unique to your build, while letting +Mill take care of all the rest. + +Mill has built-in support for the Java and https://www.scala-lang.org/[Scala] +programming language, and can serve as a replacement for +https://maven.apache.org/[Maven], https://gradle.org/[Gradle], or +http://www.scala-sbt.org/[SBT]. It can be xref:Extending_Mill.adoc[extended] +to support any other language or platform via modules (written in Java +or Scala) or through external subprocesses. Mill supports a rich ecosystem of +xref:Contrib_Plugins.adoc[] and xref:Thirdparty_Plugins.adoc[]. + +If you are using Mill, you will find the following book by the Author useful in +using Mill and its supporting libraries to the fullest: + +* https://handsonscala.com/[Hands-on Scala Programming] + +If you prefer a video introduction rather than text, the following presentation +(and companion blog post) is a good introduction into what the Mill build tool is +all about: + +- https://www.youtube.com/watch?v=UsXgCeU-ovI&list=PLLMLOC3WM2r6ZFhFfVH74W-sl8LfWtOEc&index=15[Video: A Deep Dive into the Mill Build Tool] +- https://www.lihaoyi.com/post/SoWhatsSoSpecialAboutTheMillScalaBuildTool.html[Blog Post: So, What's So Special About The Mill Scala Build Tool?] + +The rest of this page contains a quick introduction to getting start with using +Mill to build a simple Scala program. The other pages of this doc-site go into +more depth, with more examples of how to use Mill and more details of how the +Mill build tool works. diff --git a/example/basic/1-simple-scala/build.sc b/example/basic/1-simple/build.sc similarity index 97% rename from example/basic/1-simple-scala/build.sc rename to example/basic/1-simple/build.sc index 8288ee09403..9944ceb0367 100644 --- a/example/basic/1-simple-scala/build.sc +++ b/example/basic/1-simple/build.sc @@ -1,3 +1,5 @@ +//// SNIPPET:BUILD + import mill._, scalalib._ object foo extends RootModule with ScalaModule { @@ -20,6 +22,8 @@ object foo extends RootModule with ScalaModule { // `./mill compile` or `./mill run` without needing to prefix it as // `foo.compile` or `foo.run`. // +//// SNIPPET:END +// // You can download this example project using the *download* link above // if you want to try out the commands below yourself. The only requirement is // that you have some version of the JVM installed; the `./mill` script takes @@ -29,6 +33,8 @@ object foo extends RootModule with ScalaModule { // Output for this module (compiled files, resolved dependency lists, ...) // lives in `out/`. // +//// SNIPPET:DEPENDENCIES +// // This example project uses two third-party dependencies - MainArgs for CLI // argument parsing, Scalatags for HTML generation - and uses them to wrap a // given input string in HTML templates with proper escaping. @@ -89,6 +95,8 @@ error: Missing argument: --text */ +//// SNIPPET:END + // The output of every Mill task is stored in the `out/` folder under a name // corresponding to the task that created it. e.g. The `assembly` task puts its // metadata output in `out/assembly.json`, and its output files in diff --git a/example/basic/1-simple-scala/src/Foo.scala b/example/basic/1-simple/src/Foo.scala similarity index 100% rename from example/basic/1-simple-scala/src/Foo.scala rename to example/basic/1-simple/src/Foo.scala diff --git a/example/basic/1-simple-scala/test/src/FooTests.scala b/example/basic/1-simple/test/src/FooTests.scala similarity index 100% rename from example/basic/1-simple-scala/test/src/FooTests.scala rename to example/basic/1-simple/test/src/FooTests.scala diff --git a/example/basic/2-custom-build-logic/build.sc b/example/basic/2-custom-build-logic/build.sc index aa15c6a0e7d..659ecd1570a 100644 --- a/example/basic/2-custom-build-logic/build.sc +++ b/example/basic/2-custom-build-logic/build.sc @@ -3,6 +3,8 @@ // our `ScalaModule` - normally the `resources/` folder - to instead contain a // single generated text file containing the line count of all the source files // in that module + +//// SNIPPET:BUILD import mill._, scalalib._ object foo extends RootModule with ScalaModule { @@ -20,17 +22,19 @@ object foo extends RootModule with ScalaModule { } } +//// SNIPPET:END + /** Usage > mill run ... -Line Count: 11 +Line Count: 17 > mill show lineCount -11 +17 > mill inspect lineCount -lineCount(build.sc:12) +lineCount(build.sc:...) Total number of lines in module's source files Inputs: allSourceFiles diff --git a/example/basic/2-custom-build-logic/src/Foo.scala b/example/basic/2-custom-build-logic/src/Foo.scala index 53dadee4720..5454b6b7247 100644 --- a/example/basic/2-custom-build-logic/src/Foo.scala +++ b/example/basic/2-custom-build-logic/src/Foo.scala @@ -1,11 +1,17 @@ package foo object Foo{ - def main(args: Array[String]): Unit = { - val lineCount = scala.io.Source + + def getLineCount() = { + scala.io.Source .fromResource("line-count.txt") .mkString + } + val lineCount = getLineCount() + + def main(args: Array[String]): Unit = { println(s"Line Count: $lineCount") } + } diff --git a/example/basic/2-custom-build-logic/test/src/FooTests.scala b/example/basic/2-custom-build-logic/test/src/FooTests.scala index c893d7d3f66..62dd4d901fb 100644 --- a/example/basic/2-custom-build-logic/test/src/FooTests.scala +++ b/example/basic/2-custom-build-logic/test/src/FooTests.scala @@ -3,14 +3,7 @@ import utest._ object FooTests extends TestSuite { def tests = Tests { test("simple") { - val result = Foo.generateHtml("hello") - assert(result == "

hello

") - result - } - test("escaping") { - val result = Foo.generateHtml("") - assert(result == "

<hello>

") - result + assert(Foo.lineCount == 12) } } } diff --git a/example/basic/3-multi-module/bar/src/Bar.scala b/example/basic/3-multi-module/bar/src/Bar.scala index 4d145c80562..391b8d767b2 100644 --- a/example/basic/3-multi-module/bar/src/Bar.scala +++ b/example/basic/3-multi-module/bar/src/Bar.scala @@ -1,9 +1,12 @@ package bar import scalatags.Text.all._ object Bar { - def printText(text: String): Unit = { - val value = p("world") - println("Bar.value: " + value) + def generateHtml(text: String) = { + val value = h1(text) + value.toString + } + + def main(args: Array[String]) = { + println("Bar.value: " + generateHtml(args(0))) } - def main(args: Array[String]) = printText(args(0)) } diff --git a/example/basic/3-multi-module/bar/test/src/BarTests.scala b/example/basic/3-multi-module/bar/test/src/BarTests.scala new file mode 100644 index 00000000000..9525250b5a8 --- /dev/null +++ b/example/basic/3-multi-module/bar/test/src/BarTests.scala @@ -0,0 +1,16 @@ +package bar +import utest._ +object BarTests extends TestSuite { + def tests = Tests { + test("simple") { + val result = Bar.generateHtml("hello") + assert(result == "

hello

") + result + } + test("escaping") { + val result = Bar.generateHtml("") + assert(result == "

<hello>

") + result + } + } +} diff --git a/example/basic/3-multi-module/build.sc b/example/basic/3-multi-module/build.sc index 4be89ee383c..ebffe42f0ff 100644 --- a/example/basic/3-multi-module/build.sc +++ b/example/basic/3-multi-module/build.sc @@ -1,7 +1,12 @@ +//// SNIPPET:BUILD import mill._, scalalib._ trait MyModule extends ScalaModule { def scalaVersion = "2.13.11" + object test extends ScalaTests { + def ivyDeps = Agg(ivy"com.lihaoyi::utest:0.7.11") + def testFramework = "utest.runner.Framework" + } } object foo extends MyModule { @@ -12,20 +17,23 @@ object foo extends MyModule { object bar extends MyModule { def ivyDeps = Agg(ivy"com.lihaoyi::scalatags:0.8.2") } +//// SNIPPET:END // This example contains a simple Mill build with two modules, `foo` and `bar`. -// We don't mark either module as top-level using `extends BuildFileModule`, so +// We don't mark either module as top-level using `extends RootModule`, so // running tasks needs to use the module name as the prefix e.g. `foo.run` or // `bar.run`. You can define multiple modules the same way you define a single // module, using `def moduleDeps` to define the relationship between them. // -// Note that we split out the `scalaVersion` configuration common to both +// Note that we split out the `test` submodule configuration common to both // modules into a separate `trait MyModule`. This lets us avoid the need to // copy-paste common settings, while still letting us define any per-module // configuration such as `ivyDeps` specific to a particular module. // // The above builds expect the following project layout: // +//// SNIPPET:TREE +// // ---- // build.sc // foo/ @@ -49,6 +57,7 @@ object bar extends MyModule { // ... // ---- // +//// SNIPPET:END // Typically, both source code and output files in Mill follow the module // hierarchy, so e.g. input to the `foo` module lives in `foo/src/` and // compiled output files live in `out/foo/compile.dest`. @@ -61,10 +70,15 @@ bar.run > mill foo.run --foo-text hello --bar-text world Foo.value: hello -Bar.value:

world

+Bar.value:

world

> mill bar.run world -Bar.value:

world

+Bar.value:

world

+ +> mill bar.test +... +...bar.BarTests.simple... +...bar.BarTests.escaping... */ diff --git a/example/basic/3-multi-module/foo/src/Foo.scala b/example/basic/3-multi-module/foo/src/Foo.scala index bc1ef1e8b66..952d4d41dbc 100644 --- a/example/basic/3-multi-module/foo/src/Foo.scala +++ b/example/basic/3-multi-module/foo/src/Foo.scala @@ -1,13 +1,11 @@ package foo import mainargs.{main, ParserForMethods, arg} object Foo { - val value = "hello" - @main def main(@arg(name = "foo-text") fooText: String, @arg(name = "bar-text") barText: String): Unit = { - println("Foo.value: " + Foo.value) - bar.Bar.printText(barText) + println("Foo.value: " + fooText) + println("Bar.value: " + bar.Bar.generateHtml(barText)) } def main(args: Array[String]): Unit = ParserForMethods(this).runOrExit(args) diff --git a/example/basic/4-builtin-commands/build.sc b/example/basic/4-builtin-commands/build.sc index 1413089adcb..d3e30027f87 100644 --- a/example/basic/4-builtin-commands/build.sc +++ b/example/basic/4-builtin-commands/build.sc @@ -2,6 +2,7 @@ // // The following examples will be assuming the `build.sc` file given below: +//// SNIPPET:BUILD import mill._, scalalib._ trait MyModule extends ScalaModule { @@ -17,6 +18,8 @@ object bar extends MyModule { def ivyDeps = Agg(ivy"com.lihaoyi::scalatags:0.8.2") } +//// SNIPPET:END + // == resolve // `resolve` lists the tasks that match a particular query, without running them. @@ -46,8 +49,6 @@ foo.compile > mill resolve foo._ foo.allSourceFiles foo.allSources -foo.ammoniteReplClasspath -foo.ammoniteVersion foo.artifactId foo.artifactName ... @@ -82,7 +83,7 @@ foo.artifactName /** Usage > mill inspect foo.run -foo.run(RunModule.scala:...) +foo.run(RunModule...) Runs this module's code in a subprocess and waits for it to finish Inputs: foo.finalMainClass @@ -107,8 +108,15 @@ Inputs: /** Usage -> mill show foo.scalaVersion -"2.13.11" +> mill show foo.sources +[ + ".../foo/src" +] + +> mill show foo.allSourceFiles +[ + ".../foo/src/Foo..." +] */ @@ -137,7 +145,6 @@ Inputs: > mill show foo.compileClasspath [ - ".../org/scala-lang/scala-library/2.13.11/scala-library-2.13.11.jar", ... ".../foo/compile-resources" ] @@ -158,7 +165,6 @@ Inputs: ".../foo/src" ], "foo.compileClasspath": [ - ".../org/scala-lang/scala-library/2.13.11/scala-library-2.13.11.jar", ... ".../foo/compile-resources" ] @@ -179,7 +185,6 @@ Inputs: ".../foo/src" ], "foo.compileClasspath": [ - ".../org/scala-lang/scala-library/2.13.11/scala-library-2.13.11.jar", ... ".../foo/compile-resources" ] @@ -226,11 +231,9 @@ foo.assembly foo.transitiveCompileClasspath foo.compileResources foo.unmanagedClasspath -foo.scalaVersion -foo.platformSuffix +... foo.compileIvyDeps -foo.scalaOrganization -foo.scalaLibraryIvyDeps +... foo.ivyDeps foo.transitiveIvyDeps foo.compileClasspath diff --git a/example/basicjava/1-simple/build.sc b/example/basicjava/1-simple/build.sc new file mode 100644 index 00000000000..3a0cb29d168 --- /dev/null +++ b/example/basicjava/1-simple/build.sc @@ -0,0 +1,88 @@ +//// SNIPPET:BUILD + +import mill._, javalib._ + +object foo extends RootModule with JavaModule { + def ivyDeps = Agg( + ivy"net.sourceforge.argparse4j:argparse4j:0.9.0", + ivy"org.apache.commons:commons-text:1.12.0" + ) + + object test extends JavaModuleTests with TestModule.Junit4{ + def ivyDeps = super.ivyDeps() ++ Agg( + ivy"com.google.guava:guava:33.2.1-jre" + ) + } +} + + +// This is a basic Mill build for a single `JavaModule`, with two +// third-party dependencies and a test suite using the JUnit framework. As a +// single-module project, it `extends RootModule` to mark `object foo` as the +// top-level module in the build. This lets us directly perform operations +// `./mill compile` or `./mill run` without needing to prefix it as +// `foo.compile` or `foo.run`. +// +//// SNIPPET:DEPENDENCIES +// +// This example project uses two third-party dependencies - ArgParse4J for CLI +// argument parsing, Apache Commons Text for HTML escaping - and uses them to wrap a +// given input string in HTML templates with proper escaping. +// +// You can run `assembly` to generate a standalone executable jar, which then +// can be run from the command line or deployed to be run elsewhere. + +/** Usage + +> ./mill resolve _ # List what tasks are available to run +assembly +... +clean +... +compile +... +run +... +show +... +inspect +... + +> ./mill inspect compile # Show documentation and inputs of a task +compile(JavaModule...) + Compiles the current module to generate compiled classfiles/bytecode. +Inputs: + upstreamCompileOutput + allSourceFiles + compileClasspath +... + +> ./mill compile # compile sources into classfiles +... +compiling 1 Java source to... + +> ./mill run # run the main method, if any +error: argument -t/--text is required +... + +> ./mill run --text hello +

hello

+ +> ./mill test +... +Test foo.FooTest.testEscaping finished, ... +Test foo.FooTest.testSimple finished, ... +Test run finished: 0 failed, 0 ignored, 2 total, ... + +> ./mill assembly # bundle classfiles and libraries into a jar for deployment + +> ./mill show assembly # show the output of the assembly task +".../out/assembly.dest/out.jar" + +> java -jar ./out/assembly.dest/out.jar --text hello +

hello

+ +> ./out/assembly.dest/out.jar --text hello # mac/linux +

hello

+ +*/ diff --git a/example/basicjava/1-simple/src/Foo.java b/example/basicjava/1-simple/src/Foo.java new file mode 100644 index 00000000000..530b4b8e76c --- /dev/null +++ b/example/basicjava/1-simple/src/Foo.java @@ -0,0 +1,33 @@ +package foo; + +import org.apache.commons.text.StringEscapeUtils; +import net.sourceforge.argparse4j.ArgumentParsers; +import net.sourceforge.argparse4j.inf.ArgumentParser; +import net.sourceforge.argparse4j.inf.ArgumentParserException; +import net.sourceforge.argparse4j.inf.Namespace; + + +public class Foo{ + public static String generateHtml(String text){ + return "

" + StringEscapeUtils.escapeHtml4(text) + "

"; + } + public static void main(String[] args) { + ArgumentParser parser = ArgumentParsers.newFor("template").build() + .defaultHelp(true) + .description("Inserts text into a HTML template"); + + parser.addArgument("-t", "--text") + .required(true) + .help("text to insert"); + + Namespace ns = null; + try { + ns = parser.parseArgs(args); + }catch(Exception e){ + System.out.println(e.getMessage()); + System.exit(1); + } + + System.out.println(generateHtml(ns.getString("text"))); + } +} diff --git a/example/basicjava/1-simple/test/src/FooTest.java b/example/basicjava/1-simple/test/src/FooTest.java new file mode 100644 index 00000000000..41571709223 --- /dev/null +++ b/example/basicjava/1-simple/test/src/FooTest.java @@ -0,0 +1,15 @@ +package foo; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +public class FooTest { + @Test + public void testSimple() { + assertEquals(Foo.generateHtml("hello"), "

hello

"); + } + + @Test + public void testEscaping() { + assertEquals(Foo.generateHtml(""), "

<hello>

"); + } +} diff --git a/example/basicjava/2-custom-build-logic/build.sc b/example/basicjava/2-custom-build-logic/build.sc new file mode 100644 index 00000000000..b7d92780dea --- /dev/null +++ b/example/basicjava/2-custom-build-logic/build.sc @@ -0,0 +1,16 @@ +//// SNIPPET:BUILD + +import mill._, javalib._ + +object foo extends RootModule with JavaModule { + /** Total number of lines in module's source files */ + def lineCount = T{ + allSourceFiles().map(f => os.read.lines(f.path).size).sum + } + + /** Generate resources using lineCount of sources */ + override def resources = T{ + os.write(T.dest / "line-count.txt", "" + lineCount()) + Seq(PathRef(T.dest)) + } +} diff --git a/example/basicjava/2-custom-build-logic/src/Foo.java b/example/basicjava/2-custom-build-logic/src/Foo.java new file mode 100644 index 00000000000..12dcba2b7ab --- /dev/null +++ b/example/basicjava/2-custom-build-logic/src/Foo.java @@ -0,0 +1,17 @@ +package foo; + +public class Foo { + public static String getLineCount(){ + try{ + return new String( + Foo.class.getClassLoader().getResourceAsStream("line-count.txt").readAllBytes() + ); + }catch(java.io.IOException e){ return null; } + } + + static String lineCount = getLineCount(); + + public static void main(String[] args) throws Exception { + System.out.println("Line Count: " + lineCount); + } +} diff --git a/example/basicjava/2-custom-build-logic/test/src/FooTests.java b/example/basicjava/2-custom-build-logic/test/src/FooTests.java new file mode 100644 index 00000000000..a94710a2367 --- /dev/null +++ b/example/basicjava/2-custom-build-logic/test/src/FooTests.java @@ -0,0 +1,14 @@ +package foo; + +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +public class FooTests { + + @Test + public void testSimple() { + int expectedLineCount = 12; + int actualLineCount = Integer.parseInt(Foo.lineCount.trim()); + assertEquals(expectedLineCount, actualLineCount); + } +} \ No newline at end of file diff --git a/example/basicjava/3-multi-module/bar/src/Bar.java b/example/basicjava/3-multi-module/bar/src/Bar.java new file mode 100644 index 00000000000..26305693e32 --- /dev/null +++ b/example/basicjava/3-multi-module/bar/src/Bar.java @@ -0,0 +1,17 @@ +package bar; + +import org.apache.commons.text.StringEscapeUtils; +import net.sourceforge.argparse4j.ArgumentParsers; +import net.sourceforge.argparse4j.inf.ArgumentParser; +import net.sourceforge.argparse4j.inf.Namespace; + +public class Bar { + public static String generateHtml(String text) { + String value = "

" + StringEscapeUtils.escapeHtml4(text) + "

"; + return value; + } + + public static void main(String[] args) { + System.out.println("Bar.value: " + generateHtml(args[0])); + } +} \ No newline at end of file diff --git a/example/basicjava/3-multi-module/bar/test/src/BarTests.java b/example/basicjava/3-multi-module/bar/test/src/BarTests.java new file mode 100644 index 00000000000..c50bcd9e1c6 --- /dev/null +++ b/example/basicjava/3-multi-module/bar/test/src/BarTests.java @@ -0,0 +1,19 @@ +package bar; + +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +public class BarTests { + + @Test + public void simple() { + String result = Bar.generateHtml("hello"); + assertEquals("

hello

", result); + } + + @Test + public void escaping() { + String result = Bar.generateHtml(""); + assertEquals("

<hello>

", result); + } +} \ No newline at end of file diff --git a/example/basicjava/3-multi-module/build.sc b/example/basicjava/3-multi-module/build.sc new file mode 100644 index 00000000000..5397b6c420a --- /dev/null +++ b/example/basicjava/3-multi-module/build.sc @@ -0,0 +1,46 @@ +//// SNIPPET:BUILD + +import mill._, javalib._ + +trait MyModule extends JavaModule{ + object test extends JavaModuleTests with TestModule.Junit4 +} + +object foo extends MyModule{ + def moduleDeps = Seq(bar) + def ivyDeps = Agg( + ivy"net.sourceforge.argparse4j:argparse4j:0.9.0", + ) +} + +object bar extends MyModule{ + def ivyDeps = Agg( + ivy"net.sourceforge.argparse4j:argparse4j:0.9.0", + ivy"org.apache.commons:commons-text:1.12.0" + ) +} + +//// SNIPPET:TREE +// ---- +// build.sc +// foo/ +// src/ +// Foo.java +// resources/ +// ... +// bar/ +// src/ +// Bar.java +// resources/ +// ... +// out/ +// foo/ +// compile.json +// compile.dest/ +// ... +// bar/ +// compile.json +// compile.dest/ +// ... +// ---- +// diff --git a/example/basicjava/3-multi-module/foo/src/Foo.java b/example/basicjava/3-multi-module/foo/src/Foo.java new file mode 100644 index 00000000000..a57f5f830fd --- /dev/null +++ b/example/basicjava/3-multi-module/foo/src/Foo.java @@ -0,0 +1,29 @@ +package foo; + +import net.sourceforge.argparse4j.ArgumentParsers; +import net.sourceforge.argparse4j.inf.ArgumentParser; +import net.sourceforge.argparse4j.inf.Namespace; + +public class Foo { + + public static final String VALUE = "hello"; + + public static void mainFunction(String fooText, String barText) { + System.out.println("Foo.value: " + Foo.VALUE); + System.out.println("Bar.value: " + bar.Bar.generateHtml(barText)); + } + + public static void main(String[] args) throws Exception { + ArgumentParser parser = ArgumentParsers.newFor("Foo").build(); + parser.addArgument("--foo-text").required(true); + parser.addArgument("--bar-text").required(true); + + Namespace res = parser.parseArgs(args); + + String fooText = res.getString("foo_text"); + String barText = res.getString("bar_text"); + + mainFunction(fooText, barText); + } +} + diff --git a/example/basicjava/4-builtin-commands/bar/src/Bar.java b/example/basicjava/4-builtin-commands/bar/src/Bar.java new file mode 100644 index 00000000000..68c52c19f78 --- /dev/null +++ b/example/basicjava/4-builtin-commands/bar/src/Bar.java @@ -0,0 +1,17 @@ +package bar; + +import org.apache.commons.text.StringEscapeUtils; +import net.sourceforge.argparse4j.ArgumentParsers; +import net.sourceforge.argparse4j.inf.ArgumentParser; +import net.sourceforge.argparse4j.inf.Namespace; + +public class Bar { + public static String generateHtml(String text) { + String value = "

" + StringEscapeUtils.escapeHtml4("world") + "

"; + return value; + } + + public static void main(String[] args) { + System.out.println("Bar.value: " + generateHtml(args[0])); + } +} \ No newline at end of file diff --git a/example/basicjava/4-builtin-commands/bar/test/src/BarTest.java b/example/basicjava/4-builtin-commands/bar/test/src/BarTest.java new file mode 100644 index 00000000000..d790eb94f27 --- /dev/null +++ b/example/basicjava/4-builtin-commands/bar/test/src/BarTest.java @@ -0,0 +1,19 @@ +package bar; + +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +public class BarTests { + + @Test + public void testSimple() { + String result = Bar.generateHtml("hello"); + assertEquals("

hello

", result); + } + + @Test + public void testEscaping() { + String result = Bar.generateHtml(""); + assertEquals("

<hello>

", result); + } +} \ No newline at end of file diff --git a/example/basicjava/4-builtin-commands/build.sc b/example/basicjava/4-builtin-commands/build.sc new file mode 100644 index 00000000000..922f80b7936 --- /dev/null +++ b/example/basicjava/4-builtin-commands/build.sc @@ -0,0 +1,21 @@ +//// SNIPPET:BUILD +import mill._, javalib._ + +trait MyModule extends JavaModule{ + object test extends JavaModuleTests with TestModule.Junit4 +} + +object foo extends MyModule{ + def moduleDeps = Seq(bar) + def ivyDeps = Agg( + ivy"net.sourceforge.argparse4j:argparse4j:0.9.0", + ) +} + +object bar extends MyModule{ + def ivyDeps = Agg( + ivy"net.sourceforge.argparse4j:argparse4j:0.9.0", + ivy"org.apache.commons:commons-text:1.12.0" + ) +} + diff --git a/example/basicjava/4-builtin-commands/foo/src/Foo.java b/example/basicjava/4-builtin-commands/foo/src/Foo.java new file mode 100644 index 00000000000..a57f5f830fd --- /dev/null +++ b/example/basicjava/4-builtin-commands/foo/src/Foo.java @@ -0,0 +1,29 @@ +package foo; + +import net.sourceforge.argparse4j.ArgumentParsers; +import net.sourceforge.argparse4j.inf.ArgumentParser; +import net.sourceforge.argparse4j.inf.Namespace; + +public class Foo { + + public static final String VALUE = "hello"; + + public static void mainFunction(String fooText, String barText) { + System.out.println("Foo.value: " + Foo.VALUE); + System.out.println("Bar.value: " + bar.Bar.generateHtml(barText)); + } + + public static void main(String[] args) throws Exception { + ArgumentParser parser = ArgumentParsers.newFor("Foo").build(); + parser.addArgument("--foo-text").required(true); + parser.addArgument("--bar-text").required(true); + + Namespace res = parser.parseArgs(args); + + String fooText = res.getString("foo_text"); + String barText = res.getString("bar_text"); + + mainFunction(fooText, barText); + } +} + diff --git a/example/javabuilds/1-common-config/build.sc b/example/javabuilds/1-common-config/build.sc new file mode 100644 index 00000000000..7d3c030dadd --- /dev/null +++ b/example/javabuilds/1-common-config/build.sc @@ -0,0 +1,48 @@ +//// SNIPPET:BUILD +import mill._, javalib._ + +object foo extends RootModule with JavaModule { + // You can have arbitrary numbers of third-party dependencies + def ivyDeps = Agg( + ivy"org.apache.commons:commons-text:1.12.0" + ) + + // Choose a main class to use for `.run` if there are multiple present + def mainClass: T[Option[String]] = Some("foo.Foo2") + + // Add (or replace) source folders for the module to use + def sources = T.sources{ + super.sources() ++ Seq(PathRef(millSourcePath / "custom-src")) + } + + // Add (or replace) resource folders for the module to use + def resources = T.sources{ + super.resources() ++ Seq(PathRef(millSourcePath / "custom-resources")) + } + + // Generate sources at build time + def generatedSources: T[Seq[PathRef]] = T { + for(name <- Seq("A", "B", "C")) os.write( + T.dest / s"Foo$name.java", + s""" + |package foo; + |public class Foo$name { + | public static String value = "hello $name"; + |} + """.stripMargin + ) + + Seq(PathRef(T.dest)) + } + + // Pass additional JVM flags when `.run` is called or in the executable + // generated by `.assembly` + def forkArgs: T[Seq[String]] = Seq("-Dmy.custom.property=my-prop-value") + + // Pass additional environmental variables when `.run` is called. Note that + // this does not apply to running externally via `.assembly + def forkEnv: T[Map[String, String]] = Map("MY_CUSTOM_ENV" -> "my-env-value") +} + +//// SNIPPET:FATAL_WARNINGS +// \ No newline at end of file diff --git a/example/javabuilds/1-common-config/custom-resources/MyOtherResource.txt b/example/javabuilds/1-common-config/custom-resources/MyOtherResource.txt new file mode 100644 index 00000000000..8c584b77885 --- /dev/null +++ b/example/javabuilds/1-common-config/custom-resources/MyOtherResource.txt @@ -0,0 +1 @@ +My Other Resource Contents \ No newline at end of file diff --git a/example/javabuilds/1-common-config/custom-src/Foo2.java b/example/javabuilds/1-common-config/custom-src/Foo2.java new file mode 100644 index 00000000000..7e9e79d3351 --- /dev/null +++ b/example/javabuilds/1-common-config/custom-src/Foo2.java @@ -0,0 +1,40 @@ +package foo; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Properties; +import org.apache.commons.text.StringEscapeUtils; + +public class Foo2 { + public static final String value = "

" + StringEscapeUtils.escapeHtml4("hello2") + "

"; + + public static void main(String[] args) { + System.out.println("Foo2.value: " + Foo2.value); + System.out.println("Foo.value: " + Foo.value); + + System.out.println("FooA.value: " + FooA.value); + System.out.println("FooB.value: " + FooB.value); + System.out.println("FooC.value: " + FooC.value); + + System.out.println("MyResource: " + readResource("MyResource.txt")); + System.out.println("MyOtherResource: " + readResource("MyOtherResource.txt")); + + Properties properties = System.getProperties(); + System.out.println("my.custom.property: " + properties.getProperty("my.custom.property")); + + String myCustomEnv = System.getenv("MY_CUSTOM_ENV"); + if (myCustomEnv != null) { + System.out.println("MY_CUSTOM_ENV: " + myCustomEnv); + } + } + + private static String readResource(String resourceName) { + try { + return new String( + Foo2.class.getClassLoader().getResourceAsStream(resourceName).readAllBytes() + ); + }catch (IOException e) { return null; } + } +} \ No newline at end of file diff --git a/example/javabuilds/1-common-config/resources/MyResource.txt b/example/javabuilds/1-common-config/resources/MyResource.txt new file mode 100644 index 00000000000..697537075e4 --- /dev/null +++ b/example/javabuilds/1-common-config/resources/MyResource.txt @@ -0,0 +1 @@ +My Resource Contents \ No newline at end of file diff --git a/example/javabuilds/1-common-config/src/Foo.java b/example/javabuilds/1-common-config/src/Foo.java new file mode 100644 index 00000000000..9dce97d3e27 --- /dev/null +++ b/example/javabuilds/1-common-config/src/Foo.java @@ -0,0 +1,10 @@ +package foo; +import org.apache.commons.text.StringEscapeUtils; + +public class Foo { + public static final String value = "

" + StringEscapeUtils.escapeHtml4("hello") + "

"; + + public static void main(String[] args) { + System.out.println("Foo.value: " + Foo.value); + } +} \ No newline at end of file diff --git a/example/javabuilds/2-custom-tasks/build.sc b/example/javabuilds/2-custom-tasks/build.sc new file mode 100644 index 00000000000..d51e9be4a18 --- /dev/null +++ b/example/javabuilds/2-custom-tasks/build.sc @@ -0,0 +1,56 @@ +//// SNIPPET:BUILD + +import mill._, javalib._ + +object foo extends RootModule with JavaModule { + def ivyDeps = Agg(ivy"net.sourceforge.argparse4j:argparse4j:0.9.0") + + def generatedSources: T[Seq[PathRef]] = T { + val prettyIvyDeps = for(ivyDep <- ivyDeps()) yield { + val org = ivyDep.dep.module.organization.value + val name = ivyDep.dep.module.name.value + val version = ivyDep.dep.version + s""" "$org:$name:$version" """ + } + os.write( + T.dest / s"MyDeps.java", + s""" + |package foo; + |public class MyDeps { + | public static String value = + | ${prettyIvyDeps.mkString(" + \"\\n\" + \n")}; + |} + """.stripMargin + ) + + Seq(PathRef(T.dest)) + } + + def lineCount: T[Int] = T { + sources() + .flatMap(pathRef => os.walk(pathRef.path)) + .filter(_.ext == "java") + .map(os.read.lines(_).size) + .sum + } + + def forkArgs: T[Seq[String]] = Seq(s"-Dmy.line.count=${lineCount()}") + + def printLineCount() = T.command { println(lineCount()) } +} + +//// SNIPPET:COMMANDS + +/** Usage + +> mill run --text hello +text: hello +MyDeps.value: net.sourceforge.argparse4j:argparse4j:0.9.0 +my.line.count: 24 + +> mill show lineCount +24 + +> mill printLineCount +24 +*/ \ No newline at end of file diff --git a/example/javabuilds/2-custom-tasks/src/Foo.java b/example/javabuilds/2-custom-tasks/src/Foo.java new file mode 100644 index 00000000000..532f98b1536 --- /dev/null +++ b/example/javabuilds/2-custom-tasks/src/Foo.java @@ -0,0 +1,24 @@ +package foo; + +import net.sourceforge.argparse4j.ArgumentParsers; +import net.sourceforge.argparse4j.inf.ArgumentParser; +import net.sourceforge.argparse4j.inf.ArgumentParserException; +import net.sourceforge.argparse4j.inf.Namespace; + +public class Foo { + public static void main(String[] args) throws Exception { + ArgumentParser parser = ArgumentParsers.newFor("Foo").build() + .defaultHelp(true) + .description("Process some integers."); + parser.addArgument("-t", "--text") + .required(true) + .help("input text"); + + Namespace res = parser.parseArgs(args); + String text = res.getString("text"); + + System.out.println("text: " + text); + System.out.println("MyDeps.value: " + MyDeps.value); + System.out.println("my.line.count: " + System.getProperty("my.line.count")); + } +} diff --git a/example/javabuilds/3-override-tasks/build.sc b/example/javabuilds/3-override-tasks/build.sc new file mode 100644 index 00000000000..f6023f2c2c9 --- /dev/null +++ b/example/javabuilds/3-override-tasks/build.sc @@ -0,0 +1,45 @@ +//// SNIPPET:BUILD1 +import mill._, javalib._ + +object foo extends JavaModule { + + def sources = T{ + os.write( + T.dest / "Foo.java", + """package foo; + | + |public class Foo { + | public static void main(String[] args) { + | System.out.println("Hello World"); + | } + |} + """.stripMargin + ) + Seq(PathRef(T.dest)) + } + + def compile = T { + println("Compiling...") + super.compile() + } + + def run(args: Task[Args] = T.task(Args())) = T.command { + println("Running..." + args().value.mkString(" ")) + super.run(args)() + } +} +//// SNIPPET:BUILD2 + +object foo2 extends JavaModule { + def generatedSources = T{ + os.write(T.dest / "Foo.java", """...""") + Seq(PathRef(T.dest)) + } +} + +object foo3 extends JavaModule { + def sources = T{ + os.write(T.dest / "Foo.java", """...""") + super.sources() ++ Seq(PathRef(T.dest)) + } +} diff --git a/example/javabuilds/4-nested-modules/baz/src/Baz.java b/example/javabuilds/4-nested-modules/baz/src/Baz.java new file mode 100644 index 00000000000..629c0b3fdd7 --- /dev/null +++ b/example/javabuilds/4-nested-modules/baz/src/Baz.java @@ -0,0 +1,28 @@ +package baz; + +import org.apache.commons.text.StringEscapeUtils; +import net.sourceforge.argparse4j.ArgumentParsers; +import net.sourceforge.argparse4j.inf.ArgumentParser; +import net.sourceforge.argparse4j.inf.Namespace; +import foo.Foo; + +public class Baz { + + public static void main(String barText, String quxText, String fooText, String bazText) { + Foo.main(barText, quxText, fooText); + + String value = "

" + StringEscapeUtils.escapeHtml4(bazText) + "

"; + System.out.println("Baz.value: " + value); + } + + public static void main(String[] args) throws Exception { + ArgumentParser parser = ArgumentParsers.newFor("Baz").build(); + parser.addArgument("--bar-text").required(true); + parser.addArgument("--qux-text").required(true); + parser.addArgument("--foo-text").required(true); + parser.addArgument("--baz-text").required(true); + + Namespace res = parser.parseArgs(args); + main(res.getString("bar_text"), res.getString("qux_text"), res.getString("foo_text"), res.getString("baz_text")); + } +} \ No newline at end of file diff --git a/example/javabuilds/4-nested-modules/build.sc b/example/javabuilds/4-nested-modules/build.sc new file mode 100644 index 00000000000..3982a3cd61c --- /dev/null +++ b/example/javabuilds/4-nested-modules/build.sc @@ -0,0 +1,22 @@ +//// SNIPPET:BUILD +import mill._, javalib._ + +trait MyModule extends JavaModule { + def ivyDeps = Agg( + ivy"net.sourceforge.argparse4j:argparse4j:0.9.0", + ivy"org.apache.commons:commons-text:1.12.0" + ) +} + +object foo extends MyModule { + def moduleDeps = Seq(bar, qux) + + object bar extends MyModule + object qux extends MyModule { + def moduleDeps = Seq(bar) + } +} + +object baz extends MyModule { + def moduleDeps = Seq(foo.bar, foo.qux, foo) +} diff --git a/example/javabuilds/4-nested-modules/foo/bar/src/Bar.java b/example/javabuilds/4-nested-modules/foo/bar/src/Bar.java new file mode 100644 index 00000000000..af1b448de9c --- /dev/null +++ b/example/javabuilds/4-nested-modules/foo/bar/src/Bar.java @@ -0,0 +1,21 @@ +package foo.bar; + +import org.apache.commons.text.StringEscapeUtils; +import net.sourceforge.argparse4j.ArgumentParsers; +import net.sourceforge.argparse4j.inf.ArgumentParser; +import net.sourceforge.argparse4j.inf.Namespace; + +public class Bar { + public static void main(String text){ + String value = "

" + StringEscapeUtils.escapeHtml4(text) + "

"; + System.out.println("Bar.value: " + value); + } + + public static void main(String[] args) throws Exception { + ArgumentParser parser = ArgumentParsers.newFor("Bar").build(); + parser.addArgument("--text").required(true); + + Namespace res = parser.parseArgs(args); + main(res.getString("text")); + } +} \ No newline at end of file diff --git a/example/javabuilds/4-nested-modules/foo/qux/src/Qux.java b/example/javabuilds/4-nested-modules/foo/qux/src/Qux.java new file mode 100644 index 00000000000..7e4551909b2 --- /dev/null +++ b/example/javabuilds/4-nested-modules/foo/qux/src/Qux.java @@ -0,0 +1,27 @@ +package foo.qux; + +import org.apache.commons.text.StringEscapeUtils; +import net.sourceforge.argparse4j.ArgumentParsers; +import net.sourceforge.argparse4j.inf.ArgumentParser; +import net.sourceforge.argparse4j.inf.Namespace; +import foo.bar.Bar; + +public class Qux { + + + public static void main(String barText, String quxText){ + Bar.main(barText); + + String value = "

" + StringEscapeUtils.escapeHtml4(quxText) + "

"; + System.out.println("Qux.value: " + value); + } + public static void main(String[] args) throws Exception { + ArgumentParser parser = ArgumentParsers.newFor("Qux").build(); + parser.addArgument("--bar-text").required(true); + parser.addArgument("--qux-text").required(true); + + Namespace res = parser.parseArgs(args); + + main(res.getString("bar_text"), res.getString("qux_text")); + } +} \ No newline at end of file diff --git a/example/javabuilds/4-nested-modules/foo/src/Foo.java b/example/javabuilds/4-nested-modules/foo/src/Foo.java new file mode 100644 index 00000000000..1cae06967bb --- /dev/null +++ b/example/javabuilds/4-nested-modules/foo/src/Foo.java @@ -0,0 +1,27 @@ +package foo; + +import org.apache.commons.text.StringEscapeUtils; +import net.sourceforge.argparse4j.ArgumentParsers; +import net.sourceforge.argparse4j.inf.ArgumentParser; +import net.sourceforge.argparse4j.inf.Namespace; +import foo.qux.Qux; + +public class Foo { + + public static void main(String barText, String quxText, String fooText) { + Qux.main(barText, quxText); + + String value = "

" + StringEscapeUtils.escapeHtml4(fooText) + "

"; + System.out.println("Foo.value: " + value); + } + + public static void main(String[] args) throws Exception { + ArgumentParser parser = ArgumentParsers.newFor("Foo").build(); + parser.addArgument("--bar-text").required(true); + parser.addArgument("--qux-text").required(true); + parser.addArgument("--foo-text").required(true); + + Namespace res = parser.parseArgs(args); + main(res.getString("bar_text"), res.getString("qux_text"), res.getString("foo_text")); + } +} \ No newline at end of file diff --git a/example/javabuilds/5-test-suite/bar/src/Bar.java b/example/javabuilds/5-test-suite/bar/src/Bar.java new file mode 100644 index 00000000000..d457b8c1e97 --- /dev/null +++ b/example/javabuilds/5-test-suite/bar/src/Bar.java @@ -0,0 +1,11 @@ +package bar; + +public class Bar { + public static void main(String[] args) { + System.out.println(hello()); + } + + public static String hello() { + return "Hello World"; + } +} \ No newline at end of file diff --git a/example/javabuilds/5-test-suite/bar/test/src/BarTests.java b/example/javabuilds/5-test-suite/bar/test/src/BarTests.java new file mode 100644 index 00000000000..7a68f25fa6d --- /dev/null +++ b/example/javabuilds/5-test-suite/bar/test/src/BarTests.java @@ -0,0 +1,19 @@ +package bar; + +import static org.junit.Assert.assertTrue; +import org.junit.Test; + +public class BarTests { + + @Test + public void hello() { + String result = Bar.hello(); + assertTrue(result.startsWith("Hello")); + } + + @Test + public void world() { + String result = Bar.hello(); + assertTrue(result.endsWith("World")); + } +} \ No newline at end of file diff --git a/example/javabuilds/5-test-suite/build.sc b/example/javabuilds/5-test-suite/build.sc new file mode 100644 index 00000000000..eab63a07f71 --- /dev/null +++ b/example/javabuilds/5-test-suite/build.sc @@ -0,0 +1,23 @@ +//// SNIPPET:BUILD1 +import mill._, javalib._ + +object foo extends JavaModule { + object test extends JavaModuleTests { + def testFramework = "com.novocode.junit.JUnitFramework" + def ivyDeps = T { + super.ivyDeps() ++ Agg(ivy"com.novocode:junit-interface:0.11") + } + } +} + +//// SNIPPET:BUILD2 + +object bar extends JavaModule { + object test extends JavaModuleTests with TestModule.Junit4 +} + +//// SNIPPET:BUILD3 +object qux extends JavaModule { + object test extends JavaModuleTests with TestModule.Junit4 + object integration extends JavaModuleTests with TestModule.Junit4 +} diff --git a/example/javabuilds/5-test-suite/foo/src/Foo.java b/example/javabuilds/5-test-suite/foo/src/Foo.java new file mode 100644 index 00000000000..2a23172eb1d --- /dev/null +++ b/example/javabuilds/5-test-suite/foo/src/Foo.java @@ -0,0 +1,11 @@ +package foo; + +public class Foo { + public static void main(String[] args) { + System.out.println(hello()); + } + + public static String hello() { + return "Hello World"; + } +} \ No newline at end of file diff --git a/example/javabuilds/5-test-suite/foo/test/src/FooTests.java b/example/javabuilds/5-test-suite/foo/test/src/FooTests.java new file mode 100644 index 00000000000..f91561c1e7a --- /dev/null +++ b/example/javabuilds/5-test-suite/foo/test/src/FooTests.java @@ -0,0 +1,19 @@ +package foo; + +import static org.junit.Assert.assertTrue; +import org.junit.Test; + +public class FooTests { + + @Test + public void hello() { + String result = Foo.hello(); + assertTrue(result.startsWith("Hello")); + } + + @Test + public void world() { + String result = Foo.hello(); + assertTrue(result.endsWith("World")); + } +} \ No newline at end of file diff --git a/example/javabuilds/5-test-suite/qux/integration/src/QuxIntegrationTests.java b/example/javabuilds/5-test-suite/qux/integration/src/QuxIntegrationTests.java new file mode 100644 index 00000000000..c2854bcf960 --- /dev/null +++ b/example/javabuilds/5-test-suite/qux/integration/src/QuxIntegrationTests.java @@ -0,0 +1,13 @@ +package qux; + +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +public class QuxIntegrationTests { + + @Test + public void helloworld() { + String result = Qux.hello(); + assertEquals("Hello World", result); + } +} \ No newline at end of file diff --git a/example/javabuilds/5-test-suite/qux/src/Qux.java b/example/javabuilds/5-test-suite/qux/src/Qux.java new file mode 100644 index 00000000000..54c78cdb82e --- /dev/null +++ b/example/javabuilds/5-test-suite/qux/src/Qux.java @@ -0,0 +1,11 @@ +package qux; + +public class Qux { + public static void main(String[] args) { + System.out.println(hello()); + } + + public static String hello() { + return "Hello World"; + } +} \ No newline at end of file diff --git a/example/javabuilds/5-test-suite/qux/test/src/QuxTests.java b/example/javabuilds/5-test-suite/qux/test/src/QuxTests.java new file mode 100644 index 00000000000..7d0ac5ae12b --- /dev/null +++ b/example/javabuilds/5-test-suite/qux/test/src/QuxTests.java @@ -0,0 +1,19 @@ +package qux; + +import static org.junit.Assert.assertTrue; +import org.junit.Test; + +public class QuxTests { + + @Test + public void hello() { + String result = Qux.hello(); + assertTrue(result.startsWith("Hello")); + } + + @Test + public void world() { + String result = Qux.hello(); + assertTrue(result.endsWith("World")); + } +} \ No newline at end of file diff --git a/example/javabuilds/6-publish-module/build.sc b/example/javabuilds/6-publish-module/build.sc new file mode 100644 index 00000000000..dae3bdc2b5e --- /dev/null +++ b/example/javabuilds/6-publish-module/build.sc @@ -0,0 +1,30 @@ +//// SNIPPET:BUILD +import mill._, javalib._, publish._ + +object foo extends JavaModule with PublishModule { + def publishVersion = "0.0.1" + + def pomSettings = PomSettings( + description = "Hello", + organization = "com.lihaoyi", + url = "https://github.com/lihaoyi/example", + licenses = Seq(License.MIT), + versionControl = VersionControl.github("lihaoyi", "example"), + developers = Seq( + Developer("lihaoyi", "Li Haoyi", "https://github.com/lihaoyi") + ) + ) +} + +// This is an example `JavaModule` with added publishing capabilities via +// `PublishModule`. This requires that you define an additional +// `publishVersion` and `pomSettings` with the relevant metadata, and provides +// the `.publishLocal` and `publishSigned` tasks for publishing locally to the +// machine or to the central maven repository + +/** Usage + +> mill foo.publishLocal +Publishing Artifact(com.lihaoyi,foo,0.0.1) to ivy repo... + +*/ diff --git a/example/javabuilds/6-publish-module/foo/src/Foo.java b/example/javabuilds/6-publish-module/foo/src/Foo.java new file mode 100644 index 00000000000..8a80fa42a25 --- /dev/null +++ b/example/javabuilds/6-publish-module/foo/src/Foo.java @@ -0,0 +1,7 @@ +package foo; + +public class Foo { + public static void main(String[] args) { + System.out.println("Hello World"); + } +} \ No newline at end of file diff --git a/example/javabuilds/8-compat-modules/bar/src/main/java/Bar.java b/example/javabuilds/8-compat-modules/bar/src/main/java/Bar.java new file mode 100644 index 00000000000..c309ec7b2b1 --- /dev/null +++ b/example/javabuilds/8-compat-modules/bar/src/main/java/Bar.java @@ -0,0 +1,7 @@ +package bar; + +public class Bar { + public static void main(String[] args) { + System.out.println("Bar.value: " + Bar.value); + } +} \ No newline at end of file diff --git a/example/javabuilds/8-compat-modules/build.sc b/example/javabuilds/8-compat-modules/build.sc new file mode 100644 index 00000000000..9c98ae927f1 --- /dev/null +++ b/example/javabuilds/8-compat-modules/build.sc @@ -0,0 +1,38 @@ +//// SNIPPET:ALL +import mill._, javalib._ + +object foo extends MavenModule { + object test extends MavenModuleTests with TestModule.Junit4 +} + + +// `MavenModule` is a variant of `JavaModule` +// that uses the more verbose folder layout of Maven, SBT, and other tools: +// +// - `foo/src/main/java` +// - `foo/src/test/java` +// +// Rather than Mill's +// +// - `foo/src` +// - `foo/test/src` +// +// This is especially useful if you are migrating from Maven to Mill (or vice +// versa), during which a particular module may be built using both Maven and +// Mill at the same time + +/** Usage + +> mill foo.compile +compiling 1 Java source... + +> mill foo.test.compile +compiling 1 Java source... + +> mill foo.test.test +...foo.FooTests.hello ... + +> mill foo.test +...foo.FooTests.hello ... + +*/ \ No newline at end of file diff --git a/example/javabuilds/8-compat-modules/foo/src/main/java/Foo.java b/example/javabuilds/8-compat-modules/foo/src/main/java/Foo.java new file mode 100644 index 00000000000..2a23172eb1d --- /dev/null +++ b/example/javabuilds/8-compat-modules/foo/src/main/java/Foo.java @@ -0,0 +1,11 @@ +package foo; + +public class Foo { + public static void main(String[] args) { + System.out.println(hello()); + } + + public static String hello() { + return "Hello World"; + } +} \ No newline at end of file diff --git a/example/javabuilds/8-compat-modules/foo/src/test/java/FooTests.java b/example/javabuilds/8-compat-modules/foo/src/test/java/FooTests.java new file mode 100644 index 00000000000..fde78a85abf --- /dev/null +++ b/example/javabuilds/8-compat-modules/foo/src/test/java/FooTests.java @@ -0,0 +1,14 @@ +package foo; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class FooTests { + + @Test + public void hello() { + String result = Foo.hello(); + assertEquals("Hello World", result); + } +} \ No newline at end of file diff --git a/example/javabuilds/9-realistic/bar/src/Bar.java b/example/javabuilds/9-realistic/bar/src/Bar.java new file mode 100644 index 00000000000..679015f7a57 --- /dev/null +++ b/example/javabuilds/9-realistic/bar/src/Bar.java @@ -0,0 +1,9 @@ +package bar; + +import org.apache.commons.text.StringEscapeUtils; + +public class Bar { + public static String value() { + return "

" + StringEscapeUtils.escapeHtml4("world") + "

"; + } +} \ No newline at end of file diff --git a/example/javabuilds/9-realistic/bar/test/src/BarTests.java b/example/javabuilds/9-realistic/bar/test/src/BarTests.java new file mode 100644 index 00000000000..3ce9410123a --- /dev/null +++ b/example/javabuilds/9-realistic/bar/test/src/BarTests.java @@ -0,0 +1,12 @@ +package bar; + +import org.junit.Test; +import static org.junit.Assert.assertEquals; + +public class BarTests { + + @Test + public void test() { + assertEquals(Bar.value(), "

world

"); + } +} \ No newline at end of file diff --git a/example/javabuilds/9-realistic/build.sc b/example/javabuilds/9-realistic/build.sc new file mode 100644 index 00000000000..6a841839866 --- /dev/null +++ b/example/javabuilds/9-realistic/build.sc @@ -0,0 +1,111 @@ +//// SNIPPET:ALL +import mill._, javalib._, publish._ + +trait MyModule extends JavaModule with PublishModule { + def publishVersion = "0.0.1" + + def pomSettings = PomSettings( + description = "Hello", + organization = "com.lihaoyi", + url = "https://github.com/lihaoyi/example", + licenses = Seq(License.MIT), + versionControl = VersionControl.github("lihaoyi", "example"), + developers = Seq(Developer("lihaoyi", "Li Haoyi", "https://github.com/lihaoyi")) + ) + + def ivyDeps = Agg(ivy"org.apache.commons:commons-text:1.12.0") + + object test extends JavaModuleTests with TestModule.Junit4 +} + +object foo extends MyModule { + def moduleDeps = Seq(bar, qux) + + def generatedSources = T { + os.write( + T.dest / "Version.java", + s""" + |package foo; + |public class Version { + | public static String value() { + | return "${publishVersion()}"; + | } + |} + """.stripMargin + ) + Seq(PathRef(T.dest)) + } +} + +object bar extends MyModule { + def moduleDeps = Seq(qux) +} + +object qux extends MyModule + +// A semi-realistic build setup, combining all the individual Mill concepts: +// +// - Three `JavaModule`s that depend on each other +// +// - With unit testing and publishing set up +// +// - With generated sources to include the `publishVersion` as a string in the +// code, so it can be printed at runtime +// +// Note that for multi-module builds like this, using queries to run tasks on +// multiple targets at once can be very convenient: +// +// ---- +// __.test +// __.publishLocal +// ---- +// +// Also note how you can use ``trait``s to bundle together common combinations of +// modules: `My=Module` not only defines a `JavaModule` with some common +// configuration, but it also defines a `object test` module within it with its +// own configuration. This is a very useful technique for managing the often +// repetitive module structure in a typical project + +/** Usage + +> mill resolve __.run +bar.run +bar.test.run +foo.run +foo.test.run +qux.run + +> mill foo.run +foo version 0.0.1 +Foo.value:

hello

+Bar.value:

world

+Qux.value: 31337 + +> mill bar.test +...bar.BarTests.test ... + +> mill qux.run +Qux.value: 31337 + +> mill __.compile + +> mill __.test +...bar.BarTests.test ... +...foo.FooTests.test ... + +> mill __.publishLocal +Publishing Artifact(com.lihaoyi,foo,0.0.1) to ivy repo... +Publishing Artifact(com.lihaoyi,bar,0.0.1) to ivy repo... +Publishing Artifact(com.lihaoyi,qux,0.0.1) to ivy repo... +... + +> mill show foo.assembly # mac/linux +".../out/foo/assembly.dest/out.jar" + +> ./out/foo/assembly.dest/out.jar # mac/linux +foo version 0.0.1 +Foo.value:

hello

+Bar.value:

world

+Qux.value: 31337 + +*/ \ No newline at end of file diff --git a/example/javabuilds/9-realistic/foo/src/Foo.java b/example/javabuilds/9-realistic/foo/src/Foo.java new file mode 100644 index 00000000000..9ae1b46164a --- /dev/null +++ b/example/javabuilds/9-realistic/foo/src/Foo.java @@ -0,0 +1,12 @@ +package foo; + +public class Foo { + public static String value = "

hello

"; + + public static void main(String[] args) { + System.out.println("foo version " + Version.value()); + System.out.println("Foo.value: " + Foo.value); + System.out.println("Bar.value: " + bar.Bar.value()); + System.out.println("Qux.value: " + qux.Qux.value); + } +} \ No newline at end of file diff --git a/example/javabuilds/9-realistic/foo/test/src/FooTests.java b/example/javabuilds/9-realistic/foo/test/src/FooTests.java new file mode 100644 index 00000000000..a568625f695 --- /dev/null +++ b/example/javabuilds/9-realistic/foo/test/src/FooTests.java @@ -0,0 +1,12 @@ +package foo; + +import org.junit.Test; +import static org.junit.Assert.assertEquals; + +public class FooTests { + + @Test + public void test() { + assertEquals(Foo.value, "

hello

"); + } +} \ No newline at end of file diff --git a/example/scalabuilds/10-scala-realistic/qux/src/Qux.java b/example/javabuilds/9-realistic/qux/src/Qux.java similarity index 100% rename from example/scalabuilds/10-scala-realistic/qux/src/Qux.java rename to example/javabuilds/9-realistic/qux/src/Qux.java diff --git a/example/javamodule/1-compilation-execution-flags/build.sc b/example/javamodule/1-compilation-execution-flags/build.sc new file mode 100644 index 00000000000..7ce611d1fb9 --- /dev/null +++ b/example/javamodule/1-compilation-execution-flags/build.sc @@ -0,0 +1,9 @@ +//// SNIPPET:BUILD +import mill._, javalib._ + +object foo extends RootModule with JavaModule{ + def forkArgs = Seq("-Xmx4g", "-Dmy.jvm.property=hello") + def forkEnv = Map("MY_ENV_VAR" -> "WORLD") +} + +//// SNIPPET:END \ No newline at end of file diff --git a/example/javamodule/1-compilation-execution-flags/src/Foo.java b/example/javamodule/1-compilation-execution-flags/src/Foo.java new file mode 100644 index 00000000000..caa2414cbea --- /dev/null +++ b/example/javamodule/1-compilation-execution-flags/src/Foo.java @@ -0,0 +1,9 @@ +package foo; + +public class Foo { + public static void main(String[] args) { + String jvmProperty = System.getProperty("my.jvm.property"); + String envVar = System.getenv("MY_ENV_VAR"); + System.out.println(jvmProperty + " " + envVar); + } +} \ No newline at end of file diff --git a/example/javamodule/10-assembly-config/bar/resources/application.conf b/example/javamodule/10-assembly-config/bar/resources/application.conf new file mode 100644 index 00000000000..9341faacf2a --- /dev/null +++ b/example/javamodule/10-assembly-config/bar/resources/application.conf @@ -0,0 +1 @@ +Bar Application Conf diff --git a/example/javamodule/10-assembly-config/build.sc b/example/javamodule/10-assembly-config/build.sc new file mode 100644 index 00000000000..d4dc9b10c88 --- /dev/null +++ b/example/javamodule/10-assembly-config/build.sc @@ -0,0 +1,20 @@ +//// SNIPPET:BUILD +import mill._, javalib._ +import mill.javalib.Assembly._ + +object foo extends JavaModule { + def moduleDeps = Seq(bar) + def assemblyRules = Seq( + // all application.conf files will be concatenated into single file + Rule.Append("application.conf"), + // all *.conf files will be concatenated into single file + Rule.AppendPattern(".*\\.conf"), + // all *.temp files will be excluded from a final jar + Rule.ExcludePattern(".*\\.temp"), + // the `shapeless` package will be shaded under the `shade` package + Rule.Relocate("shapeless.**", "shade.shapless.@1") + ) +} + +object bar extends JavaModule { +} diff --git a/example/javamodule/10-assembly-config/foo/resources/application.conf b/example/javamodule/10-assembly-config/foo/resources/application.conf new file mode 100644 index 00000000000..482e5cf3347 --- /dev/null +++ b/example/javamodule/10-assembly-config/foo/resources/application.conf @@ -0,0 +1 @@ +Foo Application Conf diff --git a/example/javamodule/10-assembly-config/foo/src/Foo.java b/example/javamodule/10-assembly-config/foo/src/Foo.java new file mode 100644 index 00000000000..26874749137 --- /dev/null +++ b/example/javamodule/10-assembly-config/foo/src/Foo.java @@ -0,0 +1,12 @@ +package foo; + +import java.io.IOException; +import java.io.InputStream; + +public class Foo { + public static void main(String[] args) throws IOException{ + InputStream inputStream = Foo.class.getClassLoader().getResourceAsStream("application.conf"); + String conf = new String(inputStream.readAllBytes()); + System.out.println("Loaded application.conf from resources: " + conf); + } +} \ No newline at end of file diff --git a/example/javamodule/11-repository-config/build.sc b/example/javamodule/11-repository-config/build.sc new file mode 100644 index 00000000000..d95f35beaec --- /dev/null +++ b/example/javamodule/11-repository-config/build.sc @@ -0,0 +1,32 @@ +//// SNIPPET:BUILD1 + +import mill._, javalib._ +import mill.define.ModuleRef +import coursier.maven.MavenRepository + +val sonatypeReleases = Seq( + MavenRepository("https://oss.sonatype.org/content/repositories/releases") +) + +object foo extends JavaModule { + + def ivyDeps = Agg( + ivy"net.sourceforge.argparse4j:argparse4j:0.9.0", + ivy"org.apache.commons:commons-text:1.12.0" + ) + + def repositoriesTask = T.task { super.repositoriesTask() ++ sonatypeReleases } +} + +//// SNIPPET:BUILD2 + +object CustomZincWorkerModule extends ZincWorkerModule with CoursierModule { + def repositoriesTask = T.task { super.repositoriesTask() ++ sonatypeReleases } +} + +object bar extends JavaModule { + def zincWorker = ModuleRef(CustomZincWorkerModule) + // ... rest of your build definitions + + def repositoriesTask = T.task { super.repositoriesTask() ++ sonatypeReleases } +} diff --git a/example/javamodule/11-repository-config/foo/src/Foo.java b/example/javamodule/11-repository-config/foo/src/Foo.java new file mode 100644 index 00000000000..5b26afdcbd2 --- /dev/null +++ b/example/javamodule/11-repository-config/foo/src/Foo.java @@ -0,0 +1,24 @@ +package foo; + +import org.apache.commons.text.StringEscapeUtils; +import net.sourceforge.argparse4j.ArgumentParsers; +import net.sourceforge.argparse4j.inf.ArgumentParser; +import net.sourceforge.argparse4j.inf.Namespace; + +public class Foo { + + public static void main(String[] args) throws Exception{ + ArgumentParser parser = ArgumentParsers.newFor("Foo").build() + .defaultHelp(true); + + parser.addArgument("--text"); + + Namespace res = parser.parseArgs(args); + String text = res.getString("text"); + main(text); + } + + public static void main(String text) { + System.out.println("

" + StringEscapeUtils.escapeHtml4(text) + "

"); + } +} \ No newline at end of file diff --git a/example/javamodule/2-ivy-deps/build.sc b/example/javamodule/2-ivy-deps/build.sc new file mode 100644 index 00000000000..28443c10dba --- /dev/null +++ b/example/javamodule/2-ivy-deps/build.sc @@ -0,0 +1,18 @@ +//// SNIPPET:BUILD +import mill._, javalib._ + +object foo extends RootModule with JavaModule { + def ivyDeps = Agg( + ivy"com.fasterxml.jackson.core:jackson-databind:2.13.4", + ) +} + +//// SNIPPET:SCALAIVY + +//// SNIPPET:USAGE +/** Usage + +> ./mill run i am cow +JSONified using Jackson: ["i","am","cow"] + +*/ diff --git a/example/javamodule/2-ivy-deps/src/Foo.java b/example/javamodule/2-ivy-deps/src/Foo.java new file mode 100644 index 00000000000..033f55cd3ca --- /dev/null +++ b/example/javamodule/2-ivy-deps/src/Foo.java @@ -0,0 +1,10 @@ +package foo; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + +public class Foo { + public static void main(String[] args) throws Exception{ + System.out.println("JSONified using Jackson: " + new ObjectMapper().writeValueAsString(args)); + } +} \ No newline at end of file diff --git a/example/javamodule/3-run-compile-deps/bar/src/Bar.java b/example/javamodule/3-run-compile-deps/bar/src/Bar.java new file mode 100644 index 00000000000..6cd8c366bc7 --- /dev/null +++ b/example/javamodule/3-run-compile-deps/bar/src/Bar.java @@ -0,0 +1,31 @@ +package bar; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; + +class BarServlet extends HttpServlet { + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + response.setContentType("text/html"); + response.setStatus(HttpServletResponse.SC_OK); + response.getWriter().println("Hello World!"); + } +} + +public class Bar { + public static void main(String[] args) throws Exception { + Server server = new Server(8079); + ServletContextHandler context = new ServletContextHandler(); + context.setContextPath("/"); + server.setHandler(context); + context.addServlet(new ServletHolder(new BarServlet()), "/*"); + server.start(); + server.join(); + } +} \ No newline at end of file diff --git a/example/javamodule/3-run-compile-deps/build.sc b/example/javamodule/3-run-compile-deps/build.sc new file mode 100644 index 00000000000..42539399fc8 --- /dev/null +++ b/example/javamodule/3-run-compile-deps/build.sc @@ -0,0 +1,26 @@ +//// SNIPPET:BUILD1 + +import mill._, javalib._ + +object foo extends JavaModule { + def moduleDeps = Seq(bar) + def runIvyDeps = Agg( + ivy"javax.servlet:servlet-api:2.5", + ivy"org.eclipse.jetty:jetty-server:9.4.42.v20210604", + ivy"org.eclipse.jetty:jetty-servlet:9.4.42.v20210604" + ) + def mainClass = Some("bar.Bar") +} + +//// SNIPPET:BUILD2 + +object bar extends JavaModule { + def compileIvyDeps = Agg( + ivy"javax.servlet:servlet-api:2.5", + ivy"org.eclipse.jetty:jetty-server:9.4.42.v20210604", + ivy"org.eclipse.jetty:jetty-servlet:9.4.42.v20210604" + ) +} + +//// SNIPPET:SCALASTEWARD + diff --git a/example/javamodule/3-run-compile-deps/foo/src/Foo.java b/example/javamodule/3-run-compile-deps/foo/src/Foo.java new file mode 100644 index 00000000000..8a80fa42a25 --- /dev/null +++ b/example/javamodule/3-run-compile-deps/foo/src/Foo.java @@ -0,0 +1,7 @@ +package foo; + +public class Foo { + public static void main(String[] args) { + System.out.println("Hello World"); + } +} \ No newline at end of file diff --git a/example/javamodule/4-test-deps/baz/src/Baz.java b/example/javamodule/4-test-deps/baz/src/Baz.java new file mode 100644 index 00000000000..67a1378168e --- /dev/null +++ b/example/javamodule/4-test-deps/baz/src/Baz.java @@ -0,0 +1,7 @@ +package baz; + +public class Baz { + public static int getValue() { + return 123; + } +} \ No newline at end of file diff --git a/example/javamodule/4-test-deps/baz/test/src/BazTestUtils.java b/example/javamodule/4-test-deps/baz/test/src/BazTestUtils.java new file mode 100644 index 00000000000..81caf360735 --- /dev/null +++ b/example/javamodule/4-test-deps/baz/test/src/BazTestUtils.java @@ -0,0 +1,11 @@ +package baz; + +public class BazTestUtils { + + public static void bazAssertEquals(Object x, Object y) { + System.out.println("Using BazTestUtils.bazAssertEquals"); + if (!x.equals(y)) { + throw new AssertionError("Expected " + y + " but got " + x); + } + } +} \ No newline at end of file diff --git a/example/javamodule/4-test-deps/baz/test/src/BazTests.java b/example/javamodule/4-test-deps/baz/test/src/BazTests.java new file mode 100644 index 00000000000..ebc0284808a --- /dev/null +++ b/example/javamodule/4-test-deps/baz/test/src/BazTests.java @@ -0,0 +1,12 @@ +package baz; + +import org.junit.Test; +import static org.junit.Assert.*; + +public class BazTests { + + @Test + public void simple() { + BazTestUtils.bazAssertEquals(Baz.getValue(), 123); + } +} \ No newline at end of file diff --git a/example/javamodule/4-test-deps/build.sc b/example/javamodule/4-test-deps/build.sc new file mode 100644 index 00000000000..59598bd83e8 --- /dev/null +++ b/example/javamodule/4-test-deps/build.sc @@ -0,0 +1,16 @@ +//// SNIPPET:BUILD + +import mill._, javalib._ + +object qux extends JavaModule { + def moduleDeps = Seq(baz) + + object test extends JavaModuleTests with TestModule.Junit4 { + def moduleDeps = super.moduleDeps ++ Seq(baz.test) + } +} + + +object baz extends JavaModule { + object test extends JavaModuleTests with TestModule.Junit4 +} diff --git a/example/javamodule/4-test-deps/qux/src/Qux.java b/example/javamodule/4-test-deps/qux/src/Qux.java new file mode 100644 index 00000000000..0fd963e6e88 --- /dev/null +++ b/example/javamodule/4-test-deps/qux/src/Qux.java @@ -0,0 +1,7 @@ +package qux; + +public class Qux { + public static String getValue() { + return "xyz"; + } +} \ No newline at end of file diff --git a/example/javamodule/4-test-deps/qux/test/src/QuxTests.java b/example/javamodule/4-test-deps/qux/test/src/QuxTests.java new file mode 100644 index 00000000000..471d2e1208a --- /dev/null +++ b/example/javamodule/4-test-deps/qux/test/src/QuxTests.java @@ -0,0 +1,11 @@ +package qux; + +import org.junit.Test; + +public class QuxTests { + + @Test + public void simple() { + baz.BazTestUtils.bazAssertEquals("xyz", Qux.getValue()); + } +} \ No newline at end of file diff --git a/example/javamodule/6-docjar/build.sc b/example/javamodule/6-docjar/build.sc new file mode 100644 index 00000000000..89bf822c4c1 --- /dev/null +++ b/example/javamodule/6-docjar/build.sc @@ -0,0 +1,11 @@ +//// SNIPPET:BUILD + +import mill._, javalib._ + +object foo extends JavaModule { + def javadocOptions = Seq("-quiet") +} + + +//// SNIPPET:SCALA3 + diff --git a/example/javamodule/6-docjar/foo/src/Foo.java b/example/javamodule/6-docjar/foo/src/Foo.java new file mode 100644 index 00000000000..f06f5982322 --- /dev/null +++ b/example/javamodule/6-docjar/foo/src/Foo.java @@ -0,0 +1,10 @@ +package foo; + +/** + * My Awesome Docs for class Foo + */ +public class Foo { + public void run() { + System.out.println("running Foo"); + } +} \ No newline at end of file diff --git a/example/javamodule/7-unmanaged-jars/build.sc b/example/javamodule/7-unmanaged-jars/build.sc new file mode 100644 index 00000000000..8d1449ccd96 --- /dev/null +++ b/example/javamodule/7-unmanaged-jars/build.sc @@ -0,0 +1,9 @@ +//// SNIPPET:BUILD +import mill._, javalib._ + +object foo extends RootModule with JavaModule { + def unmanagedClasspath = T { + if (!os.exists(millSourcePath / "lib")) Agg() + else Agg.from(os.list(millSourcePath / "lib").map(PathRef(_))) + } +} diff --git a/example/javamodule/7-unmanaged-jars/lib/nanojson-1.8.jar b/example/javamodule/7-unmanaged-jars/lib/nanojson-1.8.jar new file mode 100644 index 00000000000..7274f3f17a6 Binary files /dev/null and b/example/javamodule/7-unmanaged-jars/lib/nanojson-1.8.jar differ diff --git a/example/javamodule/7-unmanaged-jars/src/Foo.java b/example/javamodule/7-unmanaged-jars/src/Foo.java new file mode 100644 index 00000000000..85cea22a4b7 --- /dev/null +++ b/example/javamodule/7-unmanaged-jars/src/Foo.java @@ -0,0 +1,17 @@ +package foo; + +import com.grack.nanojson.JsonParser; +import com.grack.nanojson.JsonObject; +import java.util.Map; + +public class Foo { + + public static void main(String[] args) throws Exception{ + String jsonString = args[0]; + JsonObject jsonObj = JsonParser.object().from(jsonString); + + for (Map.Entry entry : jsonObj.entrySet()) { + System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue()); + } + } +} \ No newline at end of file diff --git a/example/javamodule/8-main-class/build.sc b/example/javamodule/8-main-class/build.sc new file mode 100644 index 00000000000..f53ea93d822 --- /dev/null +++ b/example/javamodule/8-main-class/build.sc @@ -0,0 +1,6 @@ +//// SNIPPET:BUILD +import mill._, javalib._ + +object foo extends RootModule with JavaModule { + def mainClass = Some("foo.Qux") +} diff --git a/example/javamodule/8-main-class/src/Bar.java b/example/javamodule/8-main-class/src/Bar.java new file mode 100644 index 00000000000..956ad303180 --- /dev/null +++ b/example/javamodule/8-main-class/src/Bar.java @@ -0,0 +1,8 @@ +package foo; + +public class Bar { + + public static void main(String[] args) { + System.out.println("Hello Bar"); + } +} \ No newline at end of file diff --git a/example/javamodule/8-main-class/src/Foo.java b/example/javamodule/8-main-class/src/Foo.java new file mode 100644 index 00000000000..b3203a05717 --- /dev/null +++ b/example/javamodule/8-main-class/src/Foo.java @@ -0,0 +1,8 @@ +package foo; + +public class Foo { + + public static void main(String[] args) { + System.out.println("Hello Foo"); + } +} \ No newline at end of file diff --git a/example/javamodule/8-main-class/src/Qux.java b/example/javamodule/8-main-class/src/Qux.java new file mode 100644 index 00000000000..29d510b9c6f --- /dev/null +++ b/example/javamodule/8-main-class/src/Qux.java @@ -0,0 +1,8 @@ +package foo; + +public class Qux { + + public static void main(String[] args) { + System.out.println("Hello Qux"); + } +} \ No newline at end of file diff --git a/example/javamodule/9-downloading-non-maven-jars/build.sc b/example/javamodule/9-downloading-non-maven-jars/build.sc new file mode 100644 index 00000000000..611c4319f85 --- /dev/null +++ b/example/javamodule/9-downloading-non-maven-jars/build.sc @@ -0,0 +1,15 @@ +//// SNIPPET:BUILD +import mill._, javalib._ + +object foo extends RootModule with JavaModule { + def unmanagedClasspath = T { + os.write( + T.dest / "fastjavaio.jar", + requests.get.stream( + "https://github.com/williamfiset/FastJavaIO/releases/download/1.1/fastjavaio.jar" + ) + ) + Agg(PathRef(T.dest / "fastjavaio.jar")) + } +} + diff --git a/example/javamodule/9-downloading-non-maven-jars/src/Foo.java b/example/javamodule/9-downloading-non-maven-jars/src/Foo.java new file mode 100644 index 00000000000..b81404077c5 --- /dev/null +++ b/example/javamodule/9-downloading-non-maven-jars/src/Foo.java @@ -0,0 +1,31 @@ +package foo; + +import com.williamfiset.fastjavaio.InputReader; + +import java.io.FileInputStream; +import java.io.IOException; + +public class Foo { + + public static void main(String[] args) { + String filePath = args[0]; + InputReader fi = null; + try { + fi = new InputReader(new FileInputStream(filePath)); + String line; + while ((line = fi.nextLine()) != null) { + System.out.println(line); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (fi != null) { + try { + fi.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } +} \ No newline at end of file diff --git a/example/javamodule/9-downloading-non-maven-jars/textfile.txt b/example/javamodule/9-downloading-non-maven-jars/textfile.txt new file mode 100644 index 00000000000..cfe70740b42 --- /dev/null +++ b/example/javamodule/9-downloading-non-maven-jars/textfile.txt @@ -0,0 +1,3 @@ +I am cow +hear me moo +I weigh twice as much as you \ No newline at end of file diff --git a/example/misc/4-mill-build-folder/mill-build/build.sc b/example/misc/4-mill-build-folder/mill-build/build.sc index f7b600970de..6cbf953c3ca 100644 --- a/example/misc/4-mill-build-folder/mill-build/build.sc +++ b/example/misc/4-mill-build-folder/mill-build/build.sc @@ -7,11 +7,12 @@ object millbuild extends MillBuildRootModule{ def generatedSources = T { os.write( T.dest / "DepVersions.scala", - s"""package millbuild + s""" + |package millbuild |object DepVersions{ | def scalatagsVersion = "$scalatagsVersion" |} - |""".stripMargin + """.stripMargin ) super.generatedSources() ++ Seq(PathRef(T.dest)) } diff --git a/example/scalabuilds/1-common-config/build.sc b/example/scalabuilds/1-common-config/build.sc index 886c86fb053..4751ff3379a 100644 --- a/example/scalabuilds/1-common-config/build.sc +++ b/example/scalabuilds/1-common-config/build.sc @@ -3,6 +3,7 @@ // sources/resources, generating resources, and setting compilation/run // options. +//// SNIPPET:BUILD import mill._, scalalib._ object foo extends RootModule with ScalaModule { @@ -30,12 +31,13 @@ object foo extends RootModule with ScalaModule { // Generate sources at build time def generatedSources: T[Seq[PathRef]] = T { for(name <- Seq("A", "B", "C")) os.write( - T.dest / s"$name.scala", - s"""package foo - |object Foo${name} { + T.dest / s"Foo$name.scala", + s""" + |package foo + |object Foo$name { | val value = "hello $name" |} - |""".stripMargin + """.stripMargin ) Seq(PathRef(T.dest)) @@ -52,6 +54,7 @@ object foo extends RootModule with ScalaModule { // Additional Scala compiler options, e.g. to turn warnings into errors def scalacOptions: T[Seq[String]] = Seq("-deprecation", "-Xfatal-warnings") } +//// SNIPPET:END // // Note the use of `millSourcePath`, `T.dest`, and `PathRef` when preforming @@ -98,10 +101,17 @@ MyResource: My Resource Contents MyOtherResource: My Other Resource Contents my.custom.property: my-prop-value +*/ + +//// SNIPPET:FATAL_WARNINGS + +/** Usage + > sed -i 's/Foo2 {/Foo2 { println(this + "hello")/g' custom-src/Foo2.scala > mill compile # demonstrate -deprecation/-Xfatal-warnings flags error: object Foo2 { println(this + "hello") error: ^ error: ...Implicit injection of + is deprecated. Convert to String to call +... + */ diff --git a/example/scalabuilds/2-custom-tasks/build.sc b/example/scalabuilds/2-custom-tasks/build.sc index 00f59871f67..669268b2815 100644 --- a/example/scalabuilds/2-custom-tasks/build.sc +++ b/example/scalabuilds/2-custom-tasks/build.sc @@ -8,6 +8,8 @@ // and then override `forkArgs` to use it. That lets us access the line // count at runtime using `sys.props` and print it when the program runs +//// SNIPPET:BUILD + import mill._, scalalib._ object foo extends RootModule with ScalaModule { @@ -23,13 +25,14 @@ object foo extends RootModule with ScalaModule { } os.write( T.dest / s"MyDeps.scala", - s"""package foo + s""" + |package foo |object MyDeps { | val value = List( | ${prettyIvyDeps.mkString(",\n")} | ) |} - |""".stripMargin + """.stripMargin ) Seq(PathRef(T.dest)) @@ -48,6 +51,8 @@ object foo extends RootModule with ScalaModule { def printLineCount() = T.command { println(lineCount()) } } +//// SNIPPET:END + // Mill lets you define new cached Targets using the `T {...}` syntax, // depending on existing Targets e.g. `foo.sources` via the `foo.sources()` // syntax to extract their current value, as shown in `lineCount` above. The @@ -64,20 +69,24 @@ object foo extends RootModule with ScalaModule { // // This example can be run as follows: +//// SNIPPET:COMMANDS + /** Usage > mill run --text hello text: hello MyDeps.value: List((com.lihaoyi,mainargs,0.4.0)) -my.line.count: 12 +my.line.count: 14 > mill show lineCount -12 +14 > mill printLineCount -12 +14 */ +//// SNIPPET:END + // Custom targets and commands can contain arbitrary code. Whether you want to // download files using `requests.get`, shell-out to Webpack // to compile some Javascript, generate sources to feed into a compiler, or diff --git a/example/scalabuilds/2-custom-tasks/src/Foo.scala b/example/scalabuilds/2-custom-tasks/src/Foo.scala index 8d5896e5286..aab0144445b 100644 --- a/example/scalabuilds/2-custom-tasks/src/Foo.scala +++ b/example/scalabuilds/2-custom-tasks/src/Foo.scala @@ -1,5 +1,7 @@ package foo + import mainargs.{main, ParserForMethods} + object Foo { @main def main(text: String): Unit = { diff --git a/example/scalabuilds/3-override-tasks/build.sc b/example/scalabuilds/3-override-tasks/build.sc index a88f1f00305..8ecca2454a3 100644 --- a/example/scalabuilds/3-override-tasks/build.sc +++ b/example/scalabuilds/3-override-tasks/build.sc @@ -1,3 +1,4 @@ +//// SNIPPET:BUILD1 import mill._, scalalib._ object foo extends ScalaModule { @@ -11,7 +12,8 @@ object foo extends ScalaModule { | def main(args: Array[String]): Unit = { | println("Hello World") | } - |}""".stripMargin + |} + """.stripMargin ) Seq(PathRef(T.dest)) } @@ -27,6 +29,8 @@ object foo extends ScalaModule { } } +//// SNIPPET:END + // You can re-define targets and commands to override them, and use `super` if you // want to refer to the originally defined task. The above example shows how to // override `compile` and `run` to add additional logging messages, and we @@ -38,6 +42,8 @@ object foo extends ScalaModule { // `generatedSources`, or you can override `sources` and use `super` to // include the original source folder: +//// SNIPPET:BUILD2 + object foo2 extends ScalaModule { def scalaVersion = "2.13.8" @@ -56,6 +62,8 @@ object foo3 extends ScalaModule { } } +//// SNIPPET:END + // In Mill builds the `override` keyword is optional. /** Usage diff --git a/example/scalabuilds/4-nested-modules/build.sc b/example/scalabuilds/4-nested-modules/build.sc index 8931377dcbe..60cc6a25ac2 100644 --- a/example/scalabuilds/4-nested-modules/build.sc +++ b/example/scalabuilds/4-nested-modules/build.sc @@ -1,3 +1,4 @@ +//// SNIPPET:BUILD import mill._, scalalib._ trait MyModule extends ScalaModule { @@ -21,6 +22,8 @@ object baz extends MyModule { def moduleDeps = Seq(foo.bar, foo.qux, foo) } +//// SNIPPET:END + // Modules can be nested arbitrarily deeply within each other. The outer module // can be the same kind of module as the ones within, or it can be a plain // `Module` if we just need a wrapper to put the modules in without any tasks diff --git a/example/scalabuilds/5-test-suite/build.sc b/example/scalabuilds/5-test-suite/build.sc index a2b722b17ef..b818cf32856 100644 --- a/example/scalabuilds/5-test-suite/build.sc +++ b/example/scalabuilds/5-test-suite/build.sc @@ -1,3 +1,4 @@ +//// SNIPPET:BUILD1 import mill._, scalalib._ object foo extends ScalaModule { @@ -7,7 +8,7 @@ object foo extends ScalaModule { def testFramework = "utest.runner.Framework" } } - +//// SNIPPET:END // This build defines a single module with a test suite, configured to use // "uTest" as the testing framework. Test suites are themselves ``ScalaModule``s, // nested within the enclosing module, and have all the normal tasks like @@ -18,18 +19,18 @@ object foo extends ScalaModule { /** Usage > mill foo.compile -compiling 1 Scala source... +compiling 1 ... source... > mill foo.test.compile -compiling 1 Scala source... +compiling 1 ... source... > mill foo.test.test -+ foo.FooTests.hello ... -+ foo.FooTests.world ... +...foo.FooTests.hello ... +...foo.FooTests.world ... > mill foo.test -+ foo.FooTests.hello ... -+ foo.FooTests.world ... +...foo.FooTests.hello ... +...foo.FooTests.world ... */ @@ -44,6 +45,7 @@ compiling 1 Scala source... // * `TestModule.Utest` // * `TestModule.ZioTest` +//// SNIPPET:BUILD2 object bar extends ScalaModule { def scalaVersion = "2.13.8" @@ -51,12 +53,12 @@ object bar extends ScalaModule { def ivyDeps = Agg(ivy"com.lihaoyi::utest:0.7.11") } } - +//// SNIPPET:END /** Usage > mill bar.test -+ bar.BarTests.hello ... -+ bar.BarTests.world ... +...bar.BarTests.hello ... +...bar.BarTests.world ... */ @@ -78,12 +80,12 @@ object bar extends ScalaModule { /** Usage > mill bar.test bar.BarTests.hello -+ bar.BarTests.hello ... +...bar.BarTests.hello ... */ // You can also define multiple test suites if you want, e.g.: - +//// SNIPPET:BUILD3 object qux extends ScalaModule { def scalaVersion = "2.13.8" @@ -94,22 +96,22 @@ object qux extends ScalaModule { def ivyDeps = Agg(ivy"com.lihaoyi::utest:0.7.11") } } - +//// SNIPPET:END // Each of which will expect their sources to be in their respective `foo/test` and // `foo/integration` folder. /** Usage > mill qux.test -+ qux.QuxTests.hello ... -+ qux.QuxTests.world ... +...qux.QuxTests.hello ... +...qux.QuxTests.world ... > mill qux.integration -+ qux.QuxIntegrationTests.helloworld ... +...qux.QuxIntegrationTests.helloworld ... > mill qux.{test,integration} -+ qux.QuxTests.hello ... -+ qux.QuxTests.world ... -+ qux.QuxIntegrationTests.helloworld ... +...qux.QuxTests.hello ... +...qux.QuxTests.world ... +...qux.QuxIntegrationTests.helloworld ... */ \ No newline at end of file diff --git a/example/scalabuilds/6-publish-module/build.sc b/example/scalabuilds/6-publish-module/build.sc index 2d089ab4585..e705af93680 100644 --- a/example/scalabuilds/6-publish-module/build.sc +++ b/example/scalabuilds/6-publish-module/build.sc @@ -1,3 +1,4 @@ +//// SNIPPET:BUILD import mill._, scalalib._, publish._ object foo extends ScalaModule with PublishModule { @@ -29,6 +30,8 @@ Publishing Artifact(com.lihaoyi,foo_2.13,0.0.1) to ivy repo... */ +//// SNIPPET:END + // The `artifactName` defaults to the name of your module (in this case `foo`) // but can be overridden. The `organization` is defined in `pomSettings`. // diff --git a/example/scalabuilds/8-sbt-compat-modules/bar/src/main/scala-2.12/MinorVersionSpecific.scala b/example/scalabuilds/8-compat-modules/bar/src/main/scala-2.12/MinorVersionSpecific.scala similarity index 100% rename from example/scalabuilds/8-sbt-compat-modules/bar/src/main/scala-2.12/MinorVersionSpecific.scala rename to example/scalabuilds/8-compat-modules/bar/src/main/scala-2.12/MinorVersionSpecific.scala diff --git a/example/scalabuilds/8-sbt-compat-modules/bar/src/main/scala-2.13/MinorVersionSpecific.scala b/example/scalabuilds/8-compat-modules/bar/src/main/scala-2.13/MinorVersionSpecific.scala similarity index 100% rename from example/scalabuilds/8-sbt-compat-modules/bar/src/main/scala-2.13/MinorVersionSpecific.scala rename to example/scalabuilds/8-compat-modules/bar/src/main/scala-2.13/MinorVersionSpecific.scala diff --git a/example/scalabuilds/8-sbt-compat-modules/bar/src/main/scala/Bar.scala b/example/scalabuilds/8-compat-modules/bar/src/main/scala/Bar.scala similarity index 100% rename from example/scalabuilds/8-sbt-compat-modules/bar/src/main/scala/Bar.scala rename to example/scalabuilds/8-compat-modules/bar/src/main/scala/Bar.scala diff --git a/example/scalabuilds/8-sbt-compat-modules/build.sc b/example/scalabuilds/8-compat-modules/build.sc similarity index 98% rename from example/scalabuilds/8-sbt-compat-modules/build.sc rename to example/scalabuilds/8-compat-modules/build.sc index f5592847158..3de51bae93a 100644 --- a/example/scalabuilds/8-sbt-compat-modules/build.sc +++ b/example/scalabuilds/8-compat-modules/build.sc @@ -1,3 +1,4 @@ +//// SNIPPET:ALL import mill._, scalalib._ object foo extends SbtModule { diff --git a/example/scalabuilds/8-sbt-compat-modules/foo/src/main/scala/Foo.scala b/example/scalabuilds/8-compat-modules/foo/src/main/scala/Foo.scala similarity index 100% rename from example/scalabuilds/8-sbt-compat-modules/foo/src/main/scala/Foo.scala rename to example/scalabuilds/8-compat-modules/foo/src/main/scala/Foo.scala diff --git a/example/scalabuilds/8-sbt-compat-modules/foo/src/test/scala/FooTests.scala b/example/scalabuilds/8-compat-modules/foo/src/test/scala/FooTests.scala similarity index 100% rename from example/scalabuilds/8-sbt-compat-modules/foo/src/test/scala/FooTests.scala rename to example/scalabuilds/8-compat-modules/foo/src/test/scala/FooTests.scala diff --git a/example/scalabuilds/9-java-modules/bar/src/Bar.java b/example/scalabuilds/9-java-modules/bar/src/Bar.java deleted file mode 100644 index 440673606ae..00000000000 --- a/example/scalabuilds/9-java-modules/bar/src/Bar.java +++ /dev/null @@ -1,4 +0,0 @@ -package bar; -public class Bar{ - public static final int value = 271828; -} diff --git a/example/scalabuilds/9-java-modules/bar/test/src/BarTest.java b/example/scalabuilds/9-java-modules/bar/test/src/BarTest.java deleted file mode 100644 index 491d0d441b6..00000000000 --- a/example/scalabuilds/9-java-modules/bar/test/src/BarTest.java +++ /dev/null @@ -1,11 +0,0 @@ -package bar; -import static org.junit.Assert.assertEquals; -import org.junit.Test; - -public class BarTest { - - @Test - public void testValue() { - assertEquals(271828, Bar.value); - } -} diff --git a/example/scalabuilds/9-java-modules/build.sc b/example/scalabuilds/9-java-modules/build.sc deleted file mode 100644 index d876daeb642..00000000000 --- a/example/scalabuilds/9-java-modules/build.sc +++ /dev/null @@ -1,36 +0,0 @@ -import mill._, scalalib._ - -trait MyJavaModule extends JavaModule{ - object test extends JavaModuleTests with TestModule.Junit4 -} - -object foo extends MyJavaModule{ - def moduleDeps = Seq(bar) -} - -object bar extends JavaModule - -// Mill also supports ``JavaModule``s, which can only contain pure Java code -// without any Scala. These have the same set of tasks as `ScalaModules`: -// `compile`, `run`, etc., and can similarly depend on each other and have -// their own test suites. - -/** Usage - -> mill resolve __.run -foo.run -bar.run - -> mill foo.compile -compiling 1 Java source... - -> mill foo.run -Foo.value: 31337 -Bar.value: 271828 - -> mill foo.test -Test run started -... -Test run finished: 0 failed, 0 ignored, 2 total... - -*/ \ No newline at end of file diff --git a/example/scalabuilds/9-java-modules/foo/src/Foo.java b/example/scalabuilds/9-java-modules/foo/src/Foo.java deleted file mode 100644 index 76441de015e..00000000000 --- a/example/scalabuilds/9-java-modules/foo/src/Foo.java +++ /dev/null @@ -1,8 +0,0 @@ -package foo; -public class Foo{ - public static final int value = 31337; - public static void main(String[] args){ - System.out.println("Foo.value: " + foo.Foo.value); - System.out.println("Bar.value: " + bar.Bar.value); - } -} diff --git a/example/scalabuilds/9-java-modules/foo/test/src/FooTest.java b/example/scalabuilds/9-java-modules/foo/test/src/FooTest.java deleted file mode 100644 index 31ecf3f349b..00000000000 --- a/example/scalabuilds/9-java-modules/foo/test/src/FooTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package foo; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertEquals; -import org.junit.Test; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; - -public class FooTest { - - @Test - public void testValue() { - assertEquals(31337, Foo.value); - } - - @Test - public void testMain() { - ByteArrayOutputStream outContent = new ByteArrayOutputStream(); - System.setOut(new PrintStream(outContent)); - - Foo.main(new String[]{}); - - String outString = outContent.toString(); - assertTrue(outString.contains("Foo.value: 31337")); - assertTrue(outString.contains("Bar.value: 271828")); - } -} diff --git a/example/scalabuilds/10-scala-realistic/bar/src-2/BarVersionSpecific.scala b/example/scalabuilds/9-realistic/bar/src-2/BarVersionSpecific.scala similarity index 100% rename from example/scalabuilds/10-scala-realistic/bar/src-2/BarVersionSpecific.scala rename to example/scalabuilds/9-realistic/bar/src-2/BarVersionSpecific.scala diff --git a/example/scalabuilds/10-scala-realistic/bar/src-3/BarVersionSpecific.scala b/example/scalabuilds/9-realistic/bar/src-3/BarVersionSpecific.scala similarity index 100% rename from example/scalabuilds/10-scala-realistic/bar/src-3/BarVersionSpecific.scala rename to example/scalabuilds/9-realistic/bar/src-3/BarVersionSpecific.scala diff --git a/example/scalabuilds/10-scala-realistic/bar/src/Bar.scala b/example/scalabuilds/9-realistic/bar/src/Bar.scala similarity index 100% rename from example/scalabuilds/10-scala-realistic/bar/src/Bar.scala rename to example/scalabuilds/9-realistic/bar/src/Bar.scala diff --git a/example/scalabuilds/10-scala-realistic/bar/test/src-2/BarVersionSpecificTests.scala b/example/scalabuilds/9-realistic/bar/test/src-2/BarVersionSpecificTests.scala similarity index 100% rename from example/scalabuilds/10-scala-realistic/bar/test/src-2/BarVersionSpecificTests.scala rename to example/scalabuilds/9-realistic/bar/test/src-2/BarVersionSpecificTests.scala diff --git a/example/scalabuilds/10-scala-realistic/bar/test/src-3/BarVersionSpecificTests.scala b/example/scalabuilds/9-realistic/bar/test/src-3/BarVersionSpecificTests.scala similarity index 100% rename from example/scalabuilds/10-scala-realistic/bar/test/src-3/BarVersionSpecificTests.scala rename to example/scalabuilds/9-realistic/bar/test/src-3/BarVersionSpecificTests.scala diff --git a/example/scalabuilds/10-scala-realistic/bar/test/src/BarTests.scala b/example/scalabuilds/9-realistic/bar/test/src/BarTests.scala similarity index 100% rename from example/scalabuilds/10-scala-realistic/bar/test/src/BarTests.scala rename to example/scalabuilds/9-realistic/bar/test/src/BarTests.scala diff --git a/example/scalabuilds/10-scala-realistic/build.sc b/example/scalabuilds/9-realistic/build.sc similarity index 98% rename from example/scalabuilds/10-scala-realistic/build.sc rename to example/scalabuilds/9-realistic/build.sc index bab450804bb..6e7a0c66e74 100644 --- a/example/scalabuilds/10-scala-realistic/build.sc +++ b/example/scalabuilds/9-realistic/build.sc @@ -1,3 +1,4 @@ +//// SNIPPET:ALL import mill._, scalalib._, publish._ trait MyModule extends PublishModule { @@ -30,11 +31,12 @@ trait FooModule extends MyScalaModule { def generatedSources = T { os.write( T.dest / "Version.scala", - s"""package foo + s""" + |package foo |object Version{ | def value = "${publishVersion()}" |} - |""".stripMargin + """.stripMargin ) Seq(PathRef(T.dest)) } diff --git a/example/scalabuilds/10-scala-realistic/foo/src/Foo.scala b/example/scalabuilds/9-realistic/foo/src/Foo.scala similarity index 100% rename from example/scalabuilds/10-scala-realistic/foo/src/Foo.scala rename to example/scalabuilds/9-realistic/foo/src/Foo.scala diff --git a/example/scalabuilds/10-scala-realistic/foo/test/src/FooTests.scala b/example/scalabuilds/9-realistic/foo/test/src/FooTests.scala similarity index 100% rename from example/scalabuilds/10-scala-realistic/foo/test/src/FooTests.scala rename to example/scalabuilds/9-realistic/foo/test/src/FooTests.scala diff --git a/example/scalabuilds/9-realistic/qux/src/Qux.java b/example/scalabuilds/9-realistic/qux/src/Qux.java new file mode 100644 index 00000000000..bf88526d57c --- /dev/null +++ b/example/scalabuilds/9-realistic/qux/src/Qux.java @@ -0,0 +1,7 @@ +package qux; +public class Qux{ + public static final int value = 31337; + public static void main(String[] args){ + System.out.println("Qux.value: " + Qux.value); + } +} diff --git a/example/scalamodule/1-compilation-execution-flags/build.sc b/example/scalamodule/1-compilation-execution-flags/build.sc index 548694613aa..53f42a097af 100644 --- a/example/scalamodule/1-compilation-execution-flags/build.sc +++ b/example/scalamodule/1-compilation-execution-flags/build.sc @@ -1,3 +1,4 @@ +//// SNIPPET:BUILD import mill._, scalalib._ object foo extends RootModule with ScalaModule{ @@ -7,7 +8,11 @@ object foo extends RootModule with ScalaModule{ def forkEnv = Map("MY_ENV_VAR" -> "WORLD") } -// You can pass flags to the Scala compiler via `scalacOptions`. By default, +// You can pass flags to the Scala compiler via `scalacOptions`. + +//// SNIPPET:END + +// By default, // `run` runs the compiled code in a subprocess, and you can pass in JVM flags // via `forkArgs` or environment-variables via `forkEnv`. // diff --git a/example/scalamodule/10-assembly-config/build.sc b/example/scalamodule/10-assembly-config/build.sc index 2ac91b0f4a5..818e8c730bd 100644 --- a/example/scalamodule/10-assembly-config/build.sc +++ b/example/scalamodule/10-assembly-config/build.sc @@ -1,3 +1,4 @@ +//// SNIPPET:BUILD import mill._, scalalib._ import mill.scalalib.Assembly._ @@ -20,6 +21,7 @@ object foo extends ScalaModule { object bar extends ScalaModule { def scalaVersion = "2.13.8" } +//// SNIPPET:END // When you make a runnable jar of your project with `assembly` command, // you may want to exclude some files from a final jar (like signature files, diff --git a/example/scalamodule/11-repository-config/build.sc b/example/scalamodule/11-repository-config/build.sc index 0968e56a130..b24690e8a5a 100644 --- a/example/scalamodule/11-repository-config/build.sc +++ b/example/scalamodule/11-repository-config/build.sc @@ -1,6 +1,8 @@ // By default, dependencies are resolved from maven central, but you can add // your own resolvers by overriding the `repositoriesTask` task in the module: +//// SNIPPET:BUILD1 + import mill._, scalalib._ import mill.define.ModuleRef import coursier.maven.MavenRepository @@ -12,11 +14,18 @@ val sonatypeReleases = Seq( object foo extends ScalaModule { def scalaVersion = "2.13.8" + def ivyDeps = Agg( + ivy"com.lihaoyi::scalatags:0.12.0", + ivy"com.lihaoyi::mainargs:0.6.2" + ) + def repositoriesTask = T.task { super.repositoriesTask() ++ sonatypeReleases } } +//// SNIPPET:END + // Mill read https://get-coursier.io/[coursier] config files automatically. // // It is possible to setup mirror with `mirror.properties` @@ -39,6 +48,8 @@ object foo extends ScalaModule { // custom `ZincWorkerModule`, and override the `zincWorker` method in your // `ScalaModule` by pointing it to that custom object: +//// SNIPPET:BUILD2 + object CustomZincWorkerModule extends ZincWorkerModule with CoursierModule { def repositoriesTask = T.task { super.repositoriesTask() ++ sonatypeReleases } } @@ -51,8 +62,12 @@ object bar extends ScalaModule { def repositoriesTask = T.task {super.repositoriesTask() ++ sonatypeReleases} } +//// SNIPPET:END + /** Usage +> ./mill foo.run --text hello + > ./mill bar.compile */ diff --git a/example/scalamodule/11-repository-config/src/Foo.scala b/example/scalamodule/11-repository-config/foo/src/Foo.scala similarity index 100% rename from example/scalamodule/11-repository-config/src/Foo.scala rename to example/scalamodule/11-repository-config/foo/src/Foo.scala diff --git a/example/scalamodule/12-backticked-names/src/Foo.scala b/example/scalamodule/12-backticked-names/src/Foo.scala deleted file mode 100644 index 7ea07c24412..00000000000 --- a/example/scalamodule/12-backticked-names/src/Foo.scala +++ /dev/null @@ -1,12 +0,0 @@ -package foo -import scalatags.Text.all._ -import mainargs.{main, ParserForMethods} -object Foo { - @main - def main(text: String) = { - val value = h1(text) - println(value) - } - - def main(args: Array[String]): Unit = ParserForMethods(this).runOrExit(args) -} diff --git a/example/misc/7-contrib-scoverage/build.sc b/example/scalamodule/12-contrib-scoverage/build.sc similarity index 100% rename from example/misc/7-contrib-scoverage/build.sc rename to example/scalamodule/12-contrib-scoverage/build.sc diff --git a/example/misc/7-contrib-scoverage/src/Foo.scala b/example/scalamodule/12-contrib-scoverage/src/Foo.scala similarity index 100% rename from example/misc/7-contrib-scoverage/src/Foo.scala rename to example/scalamodule/12-contrib-scoverage/src/Foo.scala diff --git a/example/misc/7-contrib-scoverage/test/src/FooTests.scala b/example/scalamodule/12-contrib-scoverage/test/src/FooTests.scala similarity index 100% rename from example/misc/7-contrib-scoverage/test/src/FooTests.scala rename to example/scalamodule/12-contrib-scoverage/test/src/FooTests.scala diff --git a/example/scalamodule/2-ivy-deps/build.sc b/example/scalamodule/2-ivy-deps/build.sc index 081c26d280b..431da0585a8 100644 --- a/example/scalamodule/2-ivy-deps/build.sc +++ b/example/scalamodule/2-ivy-deps/build.sc @@ -1,3 +1,4 @@ +//// SNIPPET:BUILD import mill._, scalalib._ object foo extends RootModule with ScalaModule { @@ -8,12 +9,15 @@ object foo extends RootModule with ScalaModule { ivy"${scalaOrganization()}:scala-reflect:${scalaVersion()}" ) } +//// SNIPPET:END // You can define the `ivyDeps` field to add ivy dependencies to your module. // // * Single `:` syntax (e.g. `"ivy"org.testng:testng:6.11"`) defines Java // dependencies // +//// SNIPPET:SCALAIVY +// // * Double `::` syntax (e.g. `ivy"com.lihaoyi::upickle:0.5.1"`) defines Scala // dependencies // @@ -22,12 +26,16 @@ object foo extends RootModule with ScalaModule { // instead of just `2.12`. These are typically Scala compiler plugins or // similar. // +//// SNIPPET:END +// // To select the test-jars from a dependency use the following syntax: // // * `ivy"org.apache.spark::spark-sql:2.4.0;classifier=tests`. // // Please consult the xref:Library_Dependencies.adoc[] section for even more details. +//// SNIPPET:USAGE + /** Usage > ./mill run i am cow diff --git a/example/scalamodule/3-run-compile-deps/build.sc b/example/scalamodule/3-run-compile-deps/build.sc index 20595179f91..7c0c4eab6e2 100644 --- a/example/scalamodule/3-run-compile-deps/build.sc +++ b/example/scalamodule/3-run-compile-deps/build.sc @@ -2,6 +2,8 @@ // dependencies and their versions at runtime, you can do so with // `runIvyDeps`. +//// SNIPPET:BUILD1 + import mill._, scalalib._ object foo extends ScalaModule { @@ -15,10 +17,14 @@ object foo extends ScalaModule { def mainClass = Some("bar.Bar") } +//// SNIPPET:END + // You can also declare compile-time-only dependencies with `compileIvyDeps`. // These are present in the compile classpath, but will not propagated to the // transitive dependencies. +//// SNIPPET:BUILD2 + object bar extends ScalaModule { def scalaVersion = "2.13.8" def compileIvyDeps = Agg( @@ -28,6 +34,7 @@ object bar extends ScalaModule { ) } +//// SNIPPET:END // Typically, Mill assumes that a module with compile-time dependencies will // only be run after someone includes the equivalent run-time dependencies in // a later build step. e.g. in the case above, `bar` defines the compile-time @@ -47,6 +54,7 @@ object bar extends ScalaModule { // NOTE: Compile-time dependencies are translated to `provided`-scoped // dependencies when publish to Maven or Ivy-Repositories. // +//// SNIPPET:SCALASTEWARD // === Keeping up-to-date with Scala Steward // // It's always a good idea to keep your dependencies up-to-date. diff --git a/example/scalamodule/4-test-deps/build.sc b/example/scalamodule/4-test-deps/build.sc index 0e6eb8bfd08..ea8bc797801 100644 --- a/example/scalamodule/4-test-deps/build.sc +++ b/example/scalamodule/4-test-deps/build.sc @@ -9,6 +9,8 @@ // and `runIvyDeps` to declare dependencies in test modules, and test modules // can use their `moduleDeps` to also depend on each other +//// SNIPPET:BUILD + import mill._, scalalib._ object qux extends ScalaModule { @@ -32,6 +34,8 @@ object baz extends ScalaModule { } } +//// SNIPPET:END + // In this example, not only does `qux` depend on `baz`, but we also make // `qux.test` depend on `baz.test`. That lets `qux.test` make use of the // `BazTestUtils` class that `baz.test` defines, allowing us to re-use this @@ -40,13 +44,13 @@ object baz extends ScalaModule { /** Usage > ./mill qux.test --------------------------------- Running Tests -------------------------------- Using BazTestUtils.bazAssertEquals -+ qux.QuxTests.simple ... +... qux.QuxTests.simple ... +... > ./mill baz.test --------------------------------- Running Tests -------------------------------- Using BazTestUtils.bazAssertEquals -+ baz.BazTests.simple ... +... baz.BazTests.simple ... +... */ diff --git a/example/scalamodule/6-scaladoc/bar/src/Bar.scala b/example/scalamodule/6-docjar/bar/src/Bar.scala similarity index 68% rename from example/scalamodule/6-scaladoc/bar/src/Bar.scala rename to example/scalamodule/6-docjar/bar/src/Bar.scala index b3bd1607445..4cbcfb9ea99 100644 --- a/example/scalamodule/6-scaladoc/bar/src/Bar.scala +++ b/example/scalamodule/6-docjar/bar/src/Bar.scala @@ -1,6 +1,6 @@ package bar /** - * My Awesome Scaladoc for class Bar + * My Awesome Docs for class Bar */ class Bar { def run(): Unit = { println("running Bar") } diff --git a/example/scalamodule/6-scaladoc/build.sc b/example/scalamodule/6-docjar/build.sc similarity index 94% rename from example/scalamodule/6-scaladoc/build.sc rename to example/scalamodule/6-docjar/build.sc index aba6acf1f65..cec22b5d295 100644 --- a/example/scalamodule/6-scaladoc/build.sc +++ b/example/scalamodule/6-docjar/build.sc @@ -2,6 +2,8 @@ // like to create the documenation for, configured via `scalaDocOptions` or // `javadocOptions`: +//// SNIPPET:BUILD + import mill._, scalalib._ object foo extends ScalaModule { @@ -10,6 +12,7 @@ object foo extends ScalaModule { def scalaDocOptions = Seq("-siteroot", "mydocs", "-no-link-warnings") } +//// SNIPPET:END /** Usage @@ -17,11 +20,12 @@ object foo extends ScalaModule { > unzip -p out/foo/docJar.dest/out.jar foo/Foo.html ... -...

My Awesome Scaladoc for class Foo

... - +...My Awesome Docs for class Foo... */ +//// SNIPPET:SCALA3 + // When using Scala 3 you're also able to use Scaladoc to generate a full static // site next to your API documention. This can include general documenation for // your project and even a blog. While you can find the full documenation for this @@ -71,6 +75,6 @@ object bar extends ScalaModule { > unzip -p out/bar/docJar.dest/out.jar bar/Bar.html ... -...

My Awesome Scaladoc for class Bar

... +...

My Awesome Docs for class Bar

... */ \ No newline at end of file diff --git a/example/scalamodule/6-scaladoc/foo/src/Foo.scala b/example/scalamodule/6-docjar/foo/src/Foo.scala similarity index 68% rename from example/scalamodule/6-scaladoc/foo/src/Foo.scala rename to example/scalamodule/6-docjar/foo/src/Foo.scala index 2e8acc5a551..6d6cb54a803 100644 --- a/example/scalamodule/6-scaladoc/foo/src/Foo.scala +++ b/example/scalamodule/6-docjar/foo/src/Foo.scala @@ -1,7 +1,7 @@ package foo /** - * My Awesome Scaladoc for class Foo + * My Awesome Docs for class Foo */ class Foo { def run(): Unit = { println("running Foo") } diff --git a/example/scalamodule/7-unmanaged-jars/build.sc b/example/scalamodule/7-unmanaged-jars/build.sc index 348c7f474ae..7b8df2c0fb5 100644 --- a/example/scalamodule/7-unmanaged-jars/build.sc +++ b/example/scalamodule/7-unmanaged-jars/build.sc @@ -1,3 +1,4 @@ +//// SNIPPET:BUILD import mill._, scalalib._ object foo extends RootModule with ScalaModule { @@ -8,6 +9,8 @@ object foo extends RootModule with ScalaModule { } } +//// SNIPPET:END + // You can override `unmanagedClasspath` to point it at any jars you place on the // filesystem, e.g. in the above snippet any jars that happen to live in the // `lib/` folder. diff --git a/example/scalamodule/8-main-class/build.sc b/example/scalamodule/8-main-class/build.sc index fdb21ac8a2e..4e0cb28b8a8 100644 --- a/example/scalamodule/8-main-class/build.sc +++ b/example/scalamodule/8-main-class/build.sc @@ -1,3 +1,4 @@ +//// SNIPPET:BUILD import mill._, scalalib._ object foo extends RootModule with ScalaModule { @@ -5,6 +6,8 @@ object foo extends RootModule with ScalaModule { def mainClass = Some("foo.Qux") } +//// SNIPPET:END + // Mill's `foo.run` by default will discover which main class to run from your // compilation output, but if there is more than one or the main class comes from // some library you can explicitly specify which one to use. This also adds the diff --git a/example/scalamodule/9-downloading-non-maven-jars/build.sc b/example/scalamodule/9-downloading-non-maven-jars/build.sc index 533ac56ecdf..c069d836be0 100644 --- a/example/scalamodule/9-downloading-non-maven-jars/build.sc +++ b/example/scalamodule/9-downloading-non-maven-jars/build.sc @@ -1,3 +1,4 @@ +//// SNIPPET:BUILD import mill._, scalalib._ object foo extends RootModule with ScalaModule { @@ -13,6 +14,7 @@ object foo extends RootModule with ScalaModule { } } +//// SNIPPET:END // You can also override `unmanagedClasspath` to point it at jars that you want to // download from arbitrary URLs. Note that targets like `unmanagedClasspath` are // cached, so your jar is downloaded only once and re-used indefinitely after that. diff --git a/example/src/mill/integration/ExampleTestSuite.scala b/example/src/mill/integration/ExampleTestSuite.scala index 1d7d7f59c5e..d0f7e3109a6 100644 --- a/example/src/mill/integration/ExampleTestSuite.scala +++ b/example/src/mill/integration/ExampleTestSuite.scala @@ -6,7 +6,6 @@ import utest._ import java.util.concurrent.{Executors, TimeoutException} import scala.annotation.tailrec import scala.concurrent.duration.DurationInt -import scala.util.chaining.scalaUtilChainingOps /** * Shared implementation for the tests in `example/`. @@ -113,15 +112,14 @@ object ExampleTestSuite extends IntegrationTestSuite { expectedSnippets: Vector[String], commandStr: String ): Unit = { - BashTokenizer.tokenize(commandStr) - .tap { cmd => - Console.err.println( - s"""$workspaceRoot> ${cmd.mkString("'", "' '", "'")} - |--- Expected output -------- - |${expectedSnippets.mkString("\n")} - |----------------------------""".stripMargin - ) - } match { + val cmd = BashTokenizer.tokenize(commandStr) + Console.err.println( + s"""$workspaceRoot> ${cmd.mkString("'", "' '", "'")} + |--- Expected output -------- + |${expectedSnippets.mkString("\n")} + |----------------------------""".stripMargin + ) + cmd match { case Seq("cp", "-r", from, to) => os.copy(os.Path(from, workspaceRoot), os.Path(to, workspaceRoot)) diff --git a/example/scalamodule/12-backticked-names/build.sc b/example/tasks/9-backticked-names/build.sc similarity index 100% rename from example/scalamodule/12-backticked-names/build.sc rename to example/tasks/9-backticked-names/build.sc diff --git a/example/thirdparty/commons-io/build.sc b/example/thirdparty/commons-io/build.sc new file mode 100644 index 00000000000..143e60dac5f --- /dev/null +++ b/example/thirdparty/commons-io/build.sc @@ -0,0 +1,70 @@ +import mill._, javalib._, publish._ +import $ivy.`com.lihaoyi::mill-contrib-jmh:$MILL_VERSION` +import contrib.jmh.JmhModule + +object commonsio extends RootModule with PublishModule with MavenModule { + def publishVersion = "2.17.0-SNAPSHOT" + + def pomSettings = PomSettings( + description = artifactName(), + organization = "org.apache.commons", + url = "https://github.com/apache/commons-io", + licenses = Seq(License.`Apache-2.0`), + versionControl = VersionControl.github(owner = "apache", repo = "commons-io"), + developers = Nil + ) + + object test extends MavenModuleTests with TestModule.Junit5 with JmhModule{ + def jmhCoreVersion = "1.37" + def ivyDeps = super.ivyDeps() ++ Agg( + ivy"org.junit.jupiter:junit-jupiter:5.10.3", + ivy"org.junit-pioneer:junit-pioneer:1.9.1", + ivy"net.bytebuddy:byte-buddy:1.14.18", + ivy"net.bytebuddy:byte-buddy-agent:1.14.18", + ivy"org.mockito:mockito-inline:4.11.0", + ivy"com.google.jimfs:jimfs:1.3.0", + ivy"org.apache.commons:commons-lang3:3.14.0", + ivy"commons-codec:commons-codec:1.17.1", + ivy"org.openjdk.jmh:jmh-core:1.37", + ivy"org.openjdk.jmh:jmh-generator-annprocess:1.37", + ) + } +} + +// The Apache Commons IO library contains utility classes, stream implementations, file filters, +// file comparators, endian transformation classes, and much more. +// +// The core library `commonsio` is dependency-free, but the test suite `commonsio.test` +// as a number of libraries included. It also ships with JMH benchmarks, which Mill +// supports via the built in JMH plugin +// +// Project home: https://github.com/apache/commons-io + +/** Usage + +> ./mill compile +compiling 254 Java sources... +... + +> ./mill test.compile +compiling 261 Java sources... +... + +> ./mill test.testOnly org.apache.commons.io.FileUtilsTest +Test org.apache.commons.io.FileUtilsTest#testCopyFile1() started +Test org.apache.commons.io.FileUtilsTest#testCopyFile1() finished, took ... +... + +> ./mill test.testOnly org.apache.commons.io.FileSystemTest +Test org.apache.commons.io.FileSystemTest#testIsLegalName() started +Test org.apache.commons.io.FileSystemTest#testIsLegalName() finished, took ... +... + +> ./mill test.runJmh '.*PathUtilsContentEqualsBenchmark' -bm SingleShotTime +Benchmark Mode Cnt ... +PathUtilsContentEqualsBenchmark.testCurrent_fileContentEquals ss 5 ... +PathUtilsContentEqualsBenchmark.testCurrent_fileContentEquals_Blackhole ss 5 ... +PathUtilsContentEqualsBenchmark.testProposal_contentEquals ss 5 ... +PathUtilsContentEqualsBenchmark.testProposal_contentEquals_Blackhole ss 5 ... + +*/ \ No newline at end of file diff --git a/example/thirdparty/jimfs/build.sc b/example/thirdparty/jimfs/build.sc index 839f3ff4353..00efc46254c 100644 --- a/example/thirdparty/jimfs/build.sc +++ b/example/thirdparty/jimfs/build.sc @@ -41,7 +41,15 @@ object jimfs extends PublishModule with MavenModule { } } -// JimFS is a small Java library +// JimFS is a small Java library implementing an in-memory filesystem. It is commonly +// used in test suites to validate filesystem operations without needing to write +// to disk. +// +// It has a relatively simple codebase structure, a single module and test suite. +// It has a number of compile-time-only dependencies shared between the library and +// test suite. One wrinkle is that it uses annotation processors as part of its build, +// which Mill supports by providing the relevant `ivyDeps` of the annotation processor +// and providing `javacOptions` to invoke it. // // Project home: https://github.com/google/jimfs diff --git a/readme.adoc b/readme.adoc index 4b1f2065b51..6d84a1e2e1b 100644 --- a/readme.adoc +++ b/readme.adoc @@ -137,21 +137,21 @@ You can reproduce any of the tests manually using `dev.run`, e.g. [source,bash] ---- -./mill "example.basic[1-simple-scala].local" +./mill "example.basic[1-simple].local" ---- **Manual Test** [source,bash] ---- -./mill dev.run example/basic/1-simple-scala run --text hello +./mill dev.run example/basic/1-simple run --text hello ---- **Manual Test using Launcher Script** [source,bash] ---- -./mill dev.launcher && (cd example/basic/1-simple-scala && ../../../out/dev/launcher.dest/run run --text hello) +./mill dev.launcher && (cd example/basic/1-simple && ../../../out/dev/launcher.dest/run run --text hello) ---- === Sub-Process Tests *with* Packaging/Publishing @@ -164,7 +164,7 @@ You can reproduce these tests manually using `dev.assembly`: [source,bash] ---- -./mill dev.assembly && (cd example/basic/1-simple-scala && ../../../out/dev/assembly.dest/mill run --text hello) +./mill dev.assembly && (cd example/basic/1-simple && ../../../out/dev/assembly.dest/mill run --text hello) ---- There are two flavors of these tests: diff --git a/scalalib/src/mill/javalib/package.scala b/scalalib/src/mill/javalib/package.scala new file mode 100644 index 00000000000..7a921e1585e --- /dev/null +++ b/scalalib/src/mill/javalib/package.scala @@ -0,0 +1,39 @@ +package mill + +import mill.scalalib.Dep + +package object javalib extends mill.scalalib.JsonFormatters { + implicit class DepSyntax(ctx: StringContext) { + def ivy(args: Any*): Dep = Dep.parse { + ( + ctx.parts.take(args.length).zip(args).flatMap { case (p, a) => Seq(p, a) } ++ + ctx.parts.drop(args.length) + ).mkString + } + } + + val Assembly = mill.scalalib.Assembly + type Assembly = mill.scalalib.Assembly + + type JavaModule = mill.scalalib.JavaModule + + val ZincWorkerModule = mill.scalalib.ZincWorkerModule + type ZincWorkerModule = mill.scalalib.ZincWorkerModule + + type CoursierModule = mill.scalalib.CoursierModule + + type JsonFormatters = mill.scalalib.JsonFormatters + val JsonFormatters = mill.scalalib.JsonFormatters + + val Lib = mill.scalalib.Lib + + type RunModule = mill.scalalib.RunModule + + type TestModule = mill.scalalib.TestModule + val TestModule = mill.scalalib.TestModule + + type MavenModule = mill.scalalib.MavenModule + + type PublishModule = mill.scalalib.PublishModule + val PublishModule = mill.scalalib.PublishModule +} diff --git a/scalalib/src/mill/javalib/publish/package.scala b/scalalib/src/mill/javalib/publish/package.scala new file mode 100644 index 00000000000..0da4f548240 --- /dev/null +++ b/scalalib/src/mill/javalib/publish/package.scala @@ -0,0 +1,50 @@ +package mill.javalib + +package object publish extends mill.scalalib.publish.JsonFormatters { + val Ivy = mill.scalalib.publish.Ivy + + type JsonFormatters = mill.scalalib.JsonFormatters + val JsonFormatters = mill.scalalib.JsonFormatters + + type License = mill.scalalib.publish.License + val License = mill.scalalib.publish.License + + type LocalIvyPublisher = mill.scalalib.publish.LocalIvyPublisher + val LocalIvyPublisher = mill.scalalib.publish.LocalIvyPublisher + + type LocalM2Publisher = mill.scalalib.publish.LocalM2Publisher + + val Pom = mill.scalalib.publish.Pom + + type PublishInfo = mill.scalalib.publish.PublishInfo + val PublishInfo = mill.scalalib.publish.PublishInfo + + type Artifact = mill.scalalib.publish.Artifact + val Artifact = mill.scalalib.publish.Artifact + + type Scope = mill.scalalib.publish.Scope + val Scope = mill.scalalib.publish.Scope + + type Dependency = mill.scalalib.publish.Dependency + val Dependency = mill.scalalib.publish.Dependency + + type Developer = mill.scalalib.publish.Developer + val Developer = mill.scalalib.publish.Developer + + type PomSettings = mill.scalalib.publish.PomSettings + val PomSettings = mill.scalalib.publish.PomSettings + + val PackagingType = mill.scalalib.publish.PackagingType + + val SonatypeHelpers = mill.scalalib.publish.SonatypeHelpers + type SonatypeHttpApi = mill.scalalib.publish.SonatypeHttpApi + type SonatypePublisher = mill.scalalib.publish.SonatypePublisher + + type VersionControl = mill.scalalib.publish.VersionControl + val VersionControl = mill.scalalib.publish.VersionControl + + val VersionControlConnection = mill.scalalib.publish.VersionControlConnection + + type VersionScheme = mill.scalalib.publish.VersionScheme + val VersionScheme = mill.scalalib.publish.VersionScheme +}