diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index ed862f35a90..9517e040b30 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -152,4 +152,6 @@ jobs: uses: ./.github/workflows/run-mill-action.yml with: java-version: '11' - buildcmd: ./mill -i mill.scalalib.scalafmt.ScalafmtModule/checkFormatAll __.sources + __.mimaReportBinaryIssues + __.fix --check + buildcmd: | + ci/scalafmt.sh --test + ./mill -i __.mimaReportBinaryIssues + __.fix --check diff --git a/.scalafmt.conf b/.scalafmt.conf index 94752dfaa01..83f8f3ea9fb 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -22,3 +22,11 @@ project.git = true runner.dialect = scala213 +project.excludeFilters = [ + # can't get fileOverride to work to specify scala3 as dialect for these + "scalalib/test/resources/hello-dotty/*" + # these have scaladoc comments with a particular shape that we don't want to reformat + "example/depth/large/*" + # these need to have a wrong format, tests check that Mill can reformat them + "scalalib/test/resources/scalafmt/*" +] diff --git a/ci/scalafmt.sh b/ci/scalafmt.sh new file mode 100755 index 00000000000..dc583438098 --- /dev/null +++ b/ci/scalafmt.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash + +# This is the launcher script of scalafmt-native-image (https://github.com/VirtusLab/scalafmt-native-image). +# This script downloads and runs scalafmt-native-image version set by SCALAFMT_VERSION below. +# +# Download the latest version of this script at https://github.com/VirtusLab/scalafmt-native-image/raw/main/scalafmt.sh + +set -eu + +DEFAULT_SCALAFMT_VERSION="3.8.3" + +SCALAFMT_VERSION="" +if test -e .scalafmt.conf; then + SCALAFMT_VERSION="$(cat .scalafmt.conf | grep '^version\s*=\s*"[0-9.A-Z-]*"$' | sed 's/^version[ \t]*=[ \t]*"\([0-9.A-Z-]*\)"$/\1/g')" +fi + +if [ "$SCALAFMT_VERSION" == "" ]; then + SCALAFMT_VERSION="$DEFAULT_SCALAFMT_VERSION" + if test -e .scalafmt.conf; then + echo "Warning: no scalafmt version found in .scalafmt.conf, using $SCALAFMT_VERSION" 1>&2 + else + echo "Warning: no .scalafmt.conf found, using scalafmt version $SCALAFMT_VERSION" 1>&2 + fi +fi + +GH_ORG="VirtusLab" +GH_NAME="scalafmt-native-image" + +TAG="v$SCALAFMT_VERSION" + +if [ "$(expr substr $(uname -s) 1 5 2>/dev/null)" == "Linux" ]; then + arch=$(uname -m) + if [[ "$arch" == "aarch64" ]] || [[ "$arch" == "x86_64" ]]; then + SCALAFMT_URL="https://github.com/$GH_ORG/$GH_NAME/releases/download/$TAG/scalafmt-${arch}-pc-linux.gz" + else + echo "scalafmt-native-image is not supported on $arch" 1>&2 + exit 2 + fi + CACHE_BASE="$HOME/.cache/coursier/v1" +elif [ "$(uname)" == "Darwin" ]; then + arch=$(uname -m) + CACHE_BASE="$HOME/Library/Caches/Coursier/v1" + if [[ "$arch" == "x86_64" ]]; then + SCALAFMT_URL="https://github.com/$GH_ORG/$GH_NAME/releases/download/$TAG/scalafmt-x86_64-apple-darwin.gz" + elif [[ "$arch" == "arm64" ]]; then + SCALAFMT_URL="https://github.com/$GH_ORG/$GH_NAME/releases/download/$TAG/scalafmt-aarch64-apple-darwin.gz" + else + echo "scalafmt-native-image is not supported on $arch" 1>&2 + exit 2 + fi +else + echo "This standalone scalafmt-native-image launcher is supported only in Linux and macOS." 1>&2 + exit 1 +fi + +CACHE_DEST="$CACHE_BASE/$(echo "$SCALAFMT_URL" | sed 's@://@/@')" +SCALAFMT_BIN_PATH=${CACHE_DEST%.gz} + +if [ ! -f "$CACHE_DEST" ]; then + mkdir -p "$(dirname "$CACHE_DEST")" + TMP_DEST="$CACHE_DEST.tmp-setup" + echo "Downloading $SCALAFMT_URL" 1>&2 + curl -fLo "$TMP_DEST" "$SCALAFMT_URL" + mv "$TMP_DEST" "$CACHE_DEST" +fi + +if [ ! -f "$SCALAFMT_BIN_PATH" ]; then + gunzip -k "$CACHE_DEST" +fi + +if [ ! -x "$SCALAFMT_BIN_PATH" ]; then + chmod +x "$SCALAFMT_BIN_PATH" +fi + +exec "$SCALAFMT_BIN_PATH" "$@" diff --git a/example/depth/tasks/11-module-run-task/bar/src/Bar.scala b/example/depth/tasks/11-module-run-task/bar/src/Bar.scala index c47ffa7f1fd..12b6bd5eab0 100644 --- a/example/depth/tasks/11-module-run-task/bar/src/Bar.scala +++ b/example/depth/tasks/11-module-run-task/bar/src/Bar.scala @@ -2,9 +2,9 @@ package bar object Bar { def main(args: Array[String]) = { val dest = os.pwd - for(sourceStr <- args){ + for (sourceStr <- args) { val sourcePath = os.Path(sourceStr) - for(p <- os.walk(sourcePath) if p.ext == "scala"){ + for (p <- os.walk(sourcePath) if p.ext == "scala") { val text = os.read(p) val mangledText = text.replace("hello", "HELLO") val fileDest = dest / (p.subRelativeTo(sourcePath)) diff --git a/example/extending/imports/6-contrib-import/foo/src/Foo.scala b/example/extending/imports/6-contrib-import/foo/src/Foo.scala index 0a2c6b82ca3..6fb98e135ff 100644 --- a/example/extending/imports/6-contrib-import/foo/src/Foo.scala +++ b/example/extending/imports/6-contrib-import/foo/src/Foo.scala @@ -1,5 +1,5 @@ package foo -object Foo{ +object Foo { def main(args: Array[String]): Unit = { println("foo.BuildInfo.scalaVersion: " + foo.BuildInfo.scalaVersion) } diff --git a/example/extending/metabuild/5-meta-shared-sources/mill-build/src/ScalaVersion.scala b/example/extending/metabuild/5-meta-shared-sources/mill-build/src/ScalaVersion.scala index a735fddfea8..489a1fbdb84 100644 --- a/example/extending/metabuild/5-meta-shared-sources/mill-build/src/ScalaVersion.scala +++ b/example/extending/metabuild/5-meta-shared-sources/mill-build/src/ScalaVersion.scala @@ -1,4 +1,4 @@ package millbuild -object ScalaVersion{ +object ScalaVersion { def myScalaVersion = "2.13.10" } diff --git a/example/extending/plugins/7-writing-mill-plugins/myplugin/src/LineCountJavaModule.scala b/example/extending/plugins/7-writing-mill-plugins/myplugin/src/LineCountJavaModule.scala index f8fbc2ca147..173efb8d750 100644 --- a/example/extending/plugins/7-writing-mill-plugins/myplugin/src/LineCountJavaModule.scala +++ b/example/extending/plugins/7-writing-mill-plugins/myplugin/src/LineCountJavaModule.scala @@ -1,21 +1,23 @@ package myplugin import mill._ + /** * Example Mill plugin trait that adds a `line-count.txt` * to the resources of your `JavaModule` */ -trait LineCountJavaModule extends mill.javalib.JavaModule{ +trait LineCountJavaModule extends mill.javalib.JavaModule { + /** Name of the file containing the line count that we create in the resource path */ def lineCountResourceFileName: T[String] /** Total number of lines in module's source files */ - def lineCount = T{ + def lineCount = T { allSourceFiles().map(f => os.read.lines(f.path).size).sum } /** Generate resources using lineCount of sources */ - override def resources = T{ + override def resources = T { os.write(T.dest / lineCountResourceFileName(), "" + lineCount()) super.resources() ++ Seq(PathRef(T.dest)) } -} \ No newline at end of file +} diff --git a/example/extending/plugins/7-writing-mill-plugins/myplugin/test/src/mill/testkit/UnitTests.scala b/example/extending/plugins/7-writing-mill-plugins/myplugin/test/src/mill/testkit/UnitTests.scala index 8c122f9802b..e77512e6e70 100644 --- a/example/extending/plugins/7-writing-mill-plugins/myplugin/test/src/mill/testkit/UnitTests.scala +++ b/example/extending/plugins/7-writing-mill-plugins/myplugin/test/src/mill/testkit/UnitTests.scala @@ -12,7 +12,6 @@ object UnitTests extends TestSuite { val resourceFolder = os.Path(sys.env("MILL_TEST_RESOURCE_FOLDER")) UnitTester(build, resourceFolder / "unit-test-project").scoped { eval => - // Evaluating tasks by direct reference val Right(result) = eval(build.resources) assert( diff --git a/example/scalalib/basic/3-multi-module/foo/src/Foo.scala b/example/scalalib/basic/3-multi-module/foo/src/Foo.scala index 952d4d41dbc..6b3f89a904a 100644 --- a/example/scalalib/basic/3-multi-module/foo/src/Foo.scala +++ b/example/scalalib/basic/3-multi-module/foo/src/Foo.scala @@ -2,8 +2,10 @@ package foo import mainargs.{main, ParserForMethods, arg} object Foo { @main - def main(@arg(name = "foo-text") fooText: String, - @arg(name = "bar-text") barText: String): Unit = { + def main( + @arg(name = "foo-text") fooText: String, + @arg(name = "bar-text") barText: String + ): Unit = { println("Foo.value: " + fooText) println("Bar.value: " + bar.Bar.generateHtml(barText)) } diff --git a/example/scalalib/basic/4-builtin-commands/foo/src/Foo.scala b/example/scalalib/basic/4-builtin-commands/foo/src/Foo.scala index bc1ef1e8b66..799f75557d8 100644 --- a/example/scalalib/basic/4-builtin-commands/foo/src/Foo.scala +++ b/example/scalalib/basic/4-builtin-commands/foo/src/Foo.scala @@ -4,8 +4,10 @@ object Foo { val value = "hello" @main - def main(@arg(name = "foo-text") fooText: String, - @arg(name = "bar-text") barText: String): Unit = { + def main( + @arg(name = "foo-text") fooText: String, + @arg(name = "bar-text") barText: String + ): Unit = { println("Foo.value: " + Foo.value) bar.Bar.printText(barText) } diff --git a/example/scalalib/builds/1-common-config/custom-src/Foo2.scala b/example/scalalib/builds/1-common-config/custom-src/Foo2.scala index 622b2c9fe1f..67b70c4314b 100644 --- a/example/scalalib/builds/1-common-config/custom-src/Foo2.scala +++ b/example/scalalib/builds/1-common-config/custom-src/Foo2.scala @@ -18,4 +18,3 @@ object Foo2 { if (sys.env.contains("MY_CUSTOM_ENV")) println("MY_CUSTOM_ENV: " + sys.env("MY_CUSTOM_ENV")) } } - diff --git a/example/scalalib/builds/4-nested-modules/baz/src/Baz.scala b/example/scalalib/builds/4-nested-modules/baz/src/Baz.scala index 8dc985f2c7b..707ee109d8e 100644 --- a/example/scalalib/builds/4-nested-modules/baz/src/Baz.scala +++ b/example/scalalib/builds/4-nested-modules/baz/src/Baz.scala @@ -4,10 +4,12 @@ import mainargs.{main, ParserForMethods, arg} object Baz { @main - def main(@arg(name = "bar-text") barText: String, - @arg(name = "qux-text") quxText: String, - @arg(name = "foo-text") fooText: String, - @arg(name = "baz-text") bazText: String): Unit = { + def main( + @arg(name = "bar-text") barText: String, + @arg(name = "qux-text") quxText: String, + @arg(name = "foo-text") fooText: String, + @arg(name = "baz-text") bazText: String + ): Unit = { foo.Foo.main(barText, quxText, fooText) val value = p(bazText) diff --git a/example/scalalib/builds/4-nested-modules/foo/qux/src/Qux.scala b/example/scalalib/builds/4-nested-modules/foo/qux/src/Qux.scala index 1819642053e..d03d77231f2 100644 --- a/example/scalalib/builds/4-nested-modules/foo/qux/src/Qux.scala +++ b/example/scalalib/builds/4-nested-modules/foo/qux/src/Qux.scala @@ -4,8 +4,10 @@ import mainargs.{main, ParserForMethods, arg} object Qux { @main - def main(@arg(name = "bar-text") barText: String, - @arg(name = "qux-text") quxText: String): Unit = { + def main( + @arg(name = "bar-text") barText: String, + @arg(name = "qux-text") quxText: String + ): Unit = { foo.bar.Bar.main(barText) val value = p(quxText) diff --git a/example/scalalib/builds/4-nested-modules/foo/src/Foo.scala b/example/scalalib/builds/4-nested-modules/foo/src/Foo.scala index dc082afd7cb..f800c03f232 100644 --- a/example/scalalib/builds/4-nested-modules/foo/src/Foo.scala +++ b/example/scalalib/builds/4-nested-modules/foo/src/Foo.scala @@ -4,9 +4,11 @@ import mainargs.{main, ParserForMethods, arg} object Foo { @main - def main(@arg(name = "bar-text") barText: String, - @arg(name = "qux-text") quxText: String, - @arg(name = "foo-text") fooText: String): Unit = { + def main( + @arg(name = "bar-text") barText: String, + @arg(name = "qux-text") quxText: String, + @arg(name = "foo-text") fooText: String + ): Unit = { foo.qux.Qux.main(barText, quxText) val value = p(fooText) diff --git a/example/scalalib/module/5-resources/foo/test/src/FooTests.scala b/example/scalalib/module/5-resources/foo/test/src/FooTests.scala index 81fcf07b561..2ff893c3232 100644 --- a/example/scalalib/module/5-resources/foo/test/src/FooTests.scala +++ b/example/scalalib/module/5-resources/foo/test/src/FooTests.scala @@ -19,7 +19,7 @@ object FooTests extends TestSuite { // Use `MILL_TEST_RESOURCE_FOLDER` to list files available in resource folder assert( os.list(testFileResourceDir).sorted == - Seq(testFileResourceDir / "test-file-a.txt", testFileResourceDir / "test-file-b.txt") + Seq(testFileResourceDir / "test-file-a.txt", testFileResourceDir / "test-file-b.txt") ) // Use the `OTHER_FILES_FOLDER` configured in your build to access the diff --git a/example/scalalib/module/7-docjar/bar/src/Bar.scala b/example/scalalib/module/7-docjar/bar/src/Bar.scala index 4cbcfb9ea99..5c8666afd0e 100644 --- a/example/scalalib/module/7-docjar/bar/src/Bar.scala +++ b/example/scalalib/module/7-docjar/bar/src/Bar.scala @@ -1,4 +1,5 @@ package bar + /** * My Awesome Docs for class Bar */ diff --git a/example/scalalib/web/4-webapp-scalajs/client/src/ClientApp.scala b/example/scalalib/web/4-webapp-scalajs/client/src/ClientApp.scala index f26a43f3409..5aa78c6a4aa 100644 --- a/example/scalalib/web/4-webapp-scalajs/client/src/ClientApp.scala +++ b/example/scalalib/web/4-webapp-scalajs/client/src/ClientApp.scala @@ -1,6 +1,6 @@ package client import org.scalajs.dom -object ClientApp{ +object ClientApp { var state = "all" var todoApp = dom.document.getElementsByClassName("todoapp")(0) @@ -11,7 +11,7 @@ object ClientApp{ method = dom.HttpMethod.POST } ).then[String](response => response.text()) - .then[Unit]{ text => + .then[Unit] { text => todoApp.innerHTML = text initListeners() } @@ -45,11 +45,12 @@ object ClientApp{ bindEvent("todo-completed", s"/list/completed", Some("completed")) bindEvent("clear-completed", s"/clear-completed/$state", None) - val newTodoInput = dom.document.getElementsByClassName("new-todo")(0).asInstanceOf[dom.HTMLInputElement] + val newTodoInput = + dom.document.getElementsByClassName("new-todo")(0).asInstanceOf[dom.HTMLInputElement] newTodoInput.addEventListener( "keydown", (evt: dom.KeyboardEvent) => { - if (evt.keyCode == 13){ + if (evt.keyCode == 13) { dom.fetch( s"/add/$state", new dom.RequestInit { @@ -57,7 +58,7 @@ object ClientApp{ body = newTodoInput.value } ).then[String](response => response.text()) - .then[Unit]{text => + .then[Unit] { text => newTodoInput.value = "" todoApp.innerHTML = text initListeners() diff --git a/example/scalalib/web/5-webapp-scalajs-shared/client/src/ClientApp.scala b/example/scalalib/web/5-webapp-scalajs-shared/client/src/ClientApp.scala index 53be9ddc64f..20e268655d8 100644 --- a/example/scalalib/web/5-webapp-scalajs-shared/client/src/ClientApp.scala +++ b/example/scalalib/web/5-webapp-scalajs-shared/client/src/ClientApp.scala @@ -1,7 +1,7 @@ package client import org.scalajs.dom import shared.{Todo, Shared} -object ClientApp{ +object ClientApp { var state = "all" var todoApp = dom.document.getElementsByClassName("todoapp")(0) @@ -12,7 +12,7 @@ object ClientApp{ method = dom.HttpMethod.POST } ).`then`[String](response => response.text()) - .`then`[Unit]{ text => + .`then`[Unit] { text => todoApp.innerHTML = Shared .renderBody(upickle.default.read[Seq[Todo]](text), state) .render @@ -49,11 +49,12 @@ object ClientApp{ bindEvent("todo-completed", s"/list/completed", Some("completed")) bindEvent("clear-completed", s"/clear-completed/$state", None) - val newTodoInput = dom.document.getElementsByClassName("new-todo")(0).asInstanceOf[dom.HTMLInputElement] + val newTodoInput = + dom.document.getElementsByClassName("new-todo")(0).asInstanceOf[dom.HTMLInputElement] newTodoInput.addEventListener( "keydown", (evt: dom.KeyboardEvent) => { - if (evt.keyCode == 13){ + if (evt.keyCode == 13) { dom.fetch( s"/add/$state", new dom.RequestInit { @@ -61,7 +62,7 @@ object ClientApp{ body = newTodoInput.value } ).`then`[String](response => response.text()) - .`then`[Unit]{text => + .`then`[Unit] { text => newTodoInput.value = "" todoApp.innerHTML = Shared @@ -75,6 +76,5 @@ object ClientApp{ ) } - def main(args: Array[String]): Unit = initListeners() } diff --git a/example/scalalib/web/5-webapp-scalajs-shared/shared/src/Shared.scala b/example/scalalib/web/5-webapp-scalajs-shared/shared/src/Shared.scala index 062d32979eb..6597725430f 100644 --- a/example/scalalib/web/5-webapp-scalajs-shared/shared/src/Shared.scala +++ b/example/scalalib/web/5-webapp-scalajs-shared/shared/src/Shared.scala @@ -8,7 +8,7 @@ object Todo { implicit def todoRW: upickle.default.ReadWriter[Todo] = upickle.default.macroRW[Todo] } -object Shared{ +object Shared { def renderBody(todos: Seq[Todo], state: String) = { val filteredTodos = state match { case "all" => todos.zipWithIndex diff --git a/scalajslib/test/resources/esModuleRemap/src/app/App.scala b/scalajslib/test/resources/esModuleRemap/src/app/App.scala index d2cc0b36475..404abef2645 100644 --- a/scalajslib/test/resources/esModuleRemap/src/app/App.scala +++ b/scalajslib/test/resources/esModuleRemap/src/app/App.scala @@ -1,9 +1,9 @@ package app import scala.scalajs.js -import scala.scalajs.js.annotation._ +import scala.scalajs.js.annotation._ -object App { +object App { def main(args: Array[String]): Unit = { println(linspace(-10.0, 10.0, 10)) } diff --git a/scalalib/test/resources/assembly/src/Main.scala b/scalalib/test/resources/assembly/src/Main.scala index 26021a35dca..5ba36647ba4 100644 --- a/scalalib/test/resources/assembly/src/Main.scala +++ b/scalalib/test/resources/assembly/src/Main.scala @@ -14,4 +14,4 @@ object Main { } def main(args: Array[String]): Unit = ParserForMethods(this).runOrExit(args) -} \ No newline at end of file +} diff --git a/scalanativelib/test/resources/hello-native-world/build/test/src/utest/tests/MainTests.scala b/scalanativelib/test/resources/hello-native-world/build/test/src/utest/tests/MainTests.scala index de075077b7f..739c1b978a0 100644 --- a/scalanativelib/test/resources/hello-native-world/build/test/src/utest/tests/MainTests.scala +++ b/scalanativelib/test/resources/hello-native-world/build/test/src/utest/tests/MainTests.scala @@ -21,11 +21,14 @@ object MainTests extends TestSuite { test("resource") { val expected = new java.util.ArrayList[Path]() expected.add(Paths.get(sys.env("MILL_TEST_RESOURCE_FOLDER") + "/hello-resource.txt")) - val listed = Files.list(Paths.get(sys.env("MILL_TEST_RESOURCE_FOLDER"))).collect(Collectors.toList()) + val listed = + Files.list(Paths.get(sys.env("MILL_TEST_RESOURCE_FOLDER"))).collect(Collectors.toList()) assert(listed == expected) assert( - Files.readString(Paths.get(sys.env("MILL_TEST_RESOURCE_FOLDER") + "/hello-resource.txt")) == - "hello world resource text" + Files.readString( + Paths.get(sys.env("MILL_TEST_RESOURCE_FOLDER") + "/hello-resource.txt") + ) == + "hello world resource text" ) } }