From 045457655153c509ceab4291338794af35d54fb7 Mon Sep 17 00:00:00 2001 From: Piotr Chabelski Date: Tue, 23 Dec 2025 11:47:26 +0100 Subject: [PATCH 1/5] Add support for Mill 1.x.y syntax in `export` --- .../scala/cli/commands/export0/Export.scala | 43 +++++++++++++------ .../scala/cli/exportCmd/MillProject.scala | 41 +++++++++++++----- 2 files changed, 59 insertions(+), 25 deletions(-) diff --git a/modules/cli/src/main/scala/scala/cli/commands/export0/Export.scala b/modules/cli/src/main/scala/scala/cli/commands/export0/Export.scala index f0a9c70b3b..d760d89290 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/export0/Export.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/export0/Export.scala @@ -98,6 +98,7 @@ object Export extends ScalaCommand[ExportOptions] { def millProjectDescriptor( cache: FileCache[Task], projectName: Option[String], + millVersion: String, logger: Logger ): MillProjectDescriptor = { val launcherArtifacts = Seq( @@ -117,7 +118,12 @@ object Export extends ScalaCommand[ExportOptions] { } val launchersTask = cache.logger.using(Task.gather.gather(launcherTasks)) val launchers = launchersTask.unsafeRun()(using cache.ec) - MillProjectDescriptor(Constants.millVersion, projectName, launchers, logger) + MillProjectDescriptor( + millVersion = millVersion, + projectName = projectName, + launchers = launchers, + logger = logger + ) } def jsonProjectDescriptor( @@ -261,21 +267,30 @@ object Export extends ScalaCommand[ExportOptions] { sbtProjectDescriptor(options.sbtSetting.map(_.trim).filter(_.nonEmpty), sbtVersion, logger) val projectDescriptor = - if (shouldExportToMill) - millProjectDescriptor(options.shared.coursierCache, options.project, logger) - else if (shouldExportToMaven) + if shouldExportToMill then + millProjectDescriptor( + cache = options.shared.coursierCache, + projectName = options.project, + millVersion = Constants.millVersion, // TODO: Allow to pass the Mill version + logger = logger + ) + else if shouldExportToMaven then mavenProjectDescriptor( - defaultMavenCompilerVersion, - defaultScalaMavenCompilerVersion, - defaultMavenExecPluginVersion, - Nil, - defaultMavenGroupId, - defaultMavenArtifactId, - defaultMavenVersion, - logger + mavenPluginVersion = defaultMavenCompilerVersion, + mavenScalaPluginVersion = defaultScalaMavenCompilerVersion, + mavenExecPluginVersion = defaultMavenExecPluginVersion, + extraSettings = Nil, + mavenGroupId = defaultMavenGroupId, + mavenArtifactId = defaultMavenArtifactId, + mavenVersion = defaultMavenVersion, + logger = logger + ) + else if shouldExportToJson then + jsonProjectDescriptor( + projectName = options.project, + workspace = inputs.workspace, + logger = logger ) - else if (shouldExportToJson) - jsonProjectDescriptor(options.project, inputs.workspace, logger) else // shouldExportToSbt isn't checked, as it's treated as default sbtProjectDescriptor0 diff --git a/modules/cli/src/main/scala/scala/cli/exportCmd/MillProject.scala b/modules/cli/src/main/scala/scala/cli/exportCmd/MillProject.scala index 835520cd9e..7ad097bc81 100644 --- a/modules/cli/src/main/scala/scala/cli/exportCmd/MillProject.scala +++ b/modules/cli/src/main/scala/scala/cli/exportCmd/MillProject.scala @@ -27,6 +27,7 @@ final case class MillProject( extraTestDecls: Seq[String] = Nil, mainClass: Option[String] = None ) extends Project { + private lazy val isMill1OrNewer: Boolean = !millVersion.exists(_.startsWith("0.")) def +(other: MillProject): MillProject = MillProject.monoid.orElse(this, other) @@ -82,24 +83,37 @@ final case class MillProject( Some(s"""def scalacOptions = super.scalacOptions() ++ Seq($optsString)""") } def maybeDeps(deps: Seq[String], isCompileOnly: Boolean = false) = { - val depsDefinition = if (isCompileOnly) - Seq("def compileIvyDeps = super.compileIvyDeps() ++ Seq(") - else Seq("def ivyDeps = super.ivyDeps() ++ Seq(") - if (deps.isEmpty) Seq.empty[String] + val depsDefinition = isCompileOnly -> isMill1OrNewer match { + case (true, true) => Seq("def compileMvnDeps = super.compileMvnDeps() ++ Seq(") + case (true, false) => Seq("def compileIvyDeps = super.compileIvyDeps() ++ Seq(") + case (false, true) => Seq("def mvnDeps = super.mvnDeps() ++ Seq(") + case (false, false) => Seq("def ivyDeps = super.ivyDeps() ++ Seq(") + } + if deps.isEmpty then Seq.empty[String] else depsDefinition ++ deps - .map(dep => """ ivy"""" + dep + "\"") + .map { + case dep if isMill1OrNewer => s""" mvn"$dep"""" + case dep => s""" ivy"$dep"""" + } .appendOnInit(",") ++ Seq(")") } val maybeScalaCompilerPlugins = - if (scalaCompilerPlugins.isEmpty) Seq.empty + if scalaCompilerPlugins.isEmpty then Seq.empty else - Seq("def scalacPluginIvyDeps = super.scalacPluginIvyDeps() ++ Seq(") ++ + Seq( + if isMill1OrNewer + then "def scalacPluginMvnDeps = super.scalacPluginMvnDeps() ++ Seq(" + else "def scalacPluginIvyDeps = super.scalacPluginIvyDeps() ++ Seq(" + ) ++ scalaCompilerPlugins - .map(dep => s" ivy\"$dep\"") + .map { + case dep if isMill1OrNewer => s" mvn\"$dep\"" + case dep => s" ivy\"$dep\"" + } .appendOnInit(",") ++ Seq(")") @@ -110,7 +124,11 @@ final case class MillProject( if (resourcesDirs.isEmpty) Nil else { val resources = - resourcesDirs.map(p => s"""T.workspace / os.RelPath("${p.relativeTo(dir)}")""") + resourcesDirs.map { + case p if isMill1OrNewer => + s"""mill.api.BuildCtx.workspaceRoot / os.RelPath("${p.relativeTo(dir)}")""" + case p => s"""T.workspace / os.RelPath("${p.relativeTo(dir)}")""" + } Seq("def runClasspath = super.runClasspath() ++ Seq(") ++ resources.map(resource => s" $resource").appendOnInit(",") ++ Seq(").map(PathRef(_))") @@ -128,7 +146,7 @@ final case class MillProject( extraTestDecls.map(s => s" $s") ++ Seq(" }") else Seq.empty - val buildSc: String = { + val buildFileContent: String = { val parts: Seq[String] = Seq( "import mill._", "import mill.scalalib._" @@ -158,7 +176,8 @@ final case class MillProject( os.write(path0, content, createFolders = true) } - os.write(dir / "build.sc", buildSc.getBytes(charSet)) + val outputBuildFile = if isMill1OrNewer then dir / "build.mill.scala" else dir / "build.sc" + os.write(outputBuildFile, buildFileContent.getBytes(charSet)) } } From 73b1921c6368f3ad527b92b4d2f2231179d95d64 Mon Sep 17 00:00:00 2001 From: Piotr Chabelski Date: Tue, 23 Dec 2025 14:26:18 +0100 Subject: [PATCH 2/5] Allow to override `export`-ed Mill version with `--mill-version` --- build.mill.scala | 6 ++- .../scala/cli/commands/export0/Export.scala | 2 +- .../cli/commands/export0/ExportOptions.scala | 4 ++ .../ExportCommonTestDefinitions.scala | 16 ++++-- .../ExportMillTestDefinitions.scala | 50 +++++++++++-------- ...alaOrientedBuildToolsTestDefinitions.scala | 12 +++-- project/deps/package.mill.scala | 11 ++++ 7 files changed, 66 insertions(+), 35 deletions(-) diff --git a/build.mill.scala b/build.mill.scala index b4f3637883..7c8c35136e 100644 --- a/build.mill.scala +++ b/build.mill.scala @@ -36,7 +36,7 @@ import java.util.Locale import de.tobiasroeser.mill.vcs.version.VcsVersion import io.github.alexarchambault.millnativeimage.upload.Upload import mill._ -import mill.api.{BuildCtx, Loose} +import mill.api.{BuildCtx, BuildInfo, Loose} import scalalib.{publish => _, _} import mill.contrib.bloop.Bloop import mill.define.Task.Simple @@ -492,7 +492,7 @@ trait Core extends ScalaCliCrossSbtModule | | def ammoniteVersion = "${Deps.Versions.ammonite}" | def ammoniteVersionForScala3Lts = "${Deps.Versions.ammoniteForScala3Lts}" - | def millVersion = "${_root_.mill.main.BuildInfo.millVersion}" + | def millVersion = "${BuildInfo.millVersion}" | def maxScalaNativeForMillExport = "${Deps.Versions.maxScalaNativeForMillExport}" | | def scalafmtOrganization = "${Deps.scalafmtCli.dep.module.organization.value}" @@ -1089,6 +1089,8 @@ trait CliIntegration extends SbtModule with ScalaCliPublishModule with HasTests | def jmhOrg = "${Deps.jmhCore.dep.module.organization.value}" | def jmhCoreModule = "${Deps.jmhCore.dep.module.name.value}" | def jmhGeneratorBytecodeModule = "${Deps.jmhGeneratorBytecode.dep.module.name.value}" + | def defaultMillVersion = "${BuildInfo.millVersion}" + | def supportedMillVersions = Seq("${Deps.supportedMillVersions.mkString("\", \"")}") |} |""".stripMargin if (!os.isFile(dest) || os.read(dest) != code) diff --git a/modules/cli/src/main/scala/scala/cli/commands/export0/Export.scala b/modules/cli/src/main/scala/scala/cli/commands/export0/Export.scala index d760d89290..2c09090944 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/export0/Export.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/export0/Export.scala @@ -271,7 +271,7 @@ object Export extends ScalaCommand[ExportOptions] { millProjectDescriptor( cache = options.shared.coursierCache, projectName = options.project, - millVersion = Constants.millVersion, // TODO: Allow to pass the Mill version + millVersion = options.millVersion.getOrElse(Constants.millVersion), logger = logger ) else if shouldExportToMaven then diff --git a/modules/cli/src/main/scala/scala/cli/commands/export0/ExportOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/export0/ExportOptions.scala index 7e652d399d..063e040940 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/export0/ExportOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/export0/ExportOptions.scala @@ -57,6 +57,10 @@ final case class ExportOptions( @HelpMessage("Version of SBT to be used for the export") sbtVersion: Option[String] = None, @Group(HelpGroup.BuildToolExport.toString) + @Tag(tags.restricted) + @HelpMessage("Version of Mill to be used for the export") + millVersion: Option[String] = None, + @Group(HelpGroup.BuildToolExport.toString) @Tag(tags.experimental) @HelpMessage("Version of Maven Compiler Plugin to be used for the export") mvnVersion: Option[String] = None, diff --git a/modules/integration/src/test/scala/scala/cli/integration/ExportCommonTestDefinitions.scala b/modules/integration/src/test/scala/scala/cli/integration/ExportCommonTestDefinitions.scala index 82ace5f3a9..4597e3024f 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/ExportCommonTestDefinitions.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/ExportCommonTestDefinitions.scala @@ -10,6 +10,8 @@ trait ExportCommonTestDefinitions { this: ScalaCliSuite & TestScalaVersionArgs = protected lazy val extraOptions: Seq[String] = scalaVersionArgs ++ TestUtil.extraOptions ++ Seq("--suppress-experimental-warning") + protected def commonTestDescriptionSuffix: String = "" + protected def runExportTests: Boolean = Properties.isMac protected def exportCommand(args: String*): os.proc @@ -98,30 +100,34 @@ trait ExportCommonTestDefinitions { this: ScalaCliSuite & TestScalaVersionArgs = private val scalaVersionsInDir: Seq[String] = Seq("2.12", "2.13", "2", "3", "3.lts") if (runExportTests) { - test("JVM") { + test(s"JVM$commonTestDescriptionSuffix") { TestUtil.retryOnCi() { jvmTest(runMainArgs(Some("Main")), runTestsArgs(Some("Main")), mainClassName = "Main") } } - test("extra source from a directive introducing a dependency") { + test(s"extra source from a directive introducing a dependency$commonTestDescriptionSuffix") { TestUtil.retryOnCi() { extraSourceFromDirectiveWithExtraDependency("Main", "Main.scala") } } - test("extra source passed both via directive and from command line") { + test( + s"extra source passed both via directive and from command line$commonTestDescriptionSuffix" + ) { TestUtil.retryOnCi() { extraSourceFromDirectiveWithExtraDependency("Main", ".") } } scalaVersionsInDir.foreach { scalaV => - test(s"check export for project with scala version in directive as $scalaV") { + test( + s"check export for project with scala version in directive as $scalaV$commonTestDescriptionSuffix" + ) { TestUtil.retryOnCi() { scalaVersionTest(scalaV, "Main") } } } - test("just test scope") { + test(s"just test scope$commonTestDescriptionSuffix") { // Keeping the test name ends with Test to support maven convention TestUtil.retryOnCi() { justTestScope("MyTest") diff --git a/modules/integration/src/test/scala/scala/cli/integration/ExportMillTestDefinitions.scala b/modules/integration/src/test/scala/scala/cli/integration/ExportMillTestDefinitions.scala index 1a595b1e5f..6e2bd61d02 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/ExportMillTestDefinitions.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/ExportMillTestDefinitions.scala @@ -11,6 +11,7 @@ abstract class ExportMillTestDefinitions extends ScalaCliSuite with ExportScalaOrientedBuildToolsTestDefinitions with MillTestHelper { this: TestScalaVersion => override val prepareTestInputs: TestInputs => TestInputs = _.withMillJvmOpts + override def commonTestDescriptionSuffix = s" (Mill ${Constants.defaultMillVersion})" override val outputDir: RelPath = millOutputDir override def exportCommand(args: String*): os.proc = @@ -34,9 +35,9 @@ abstract class ExportMillTestDefinitions extends ScalaCliSuite override def runTestsArgs(mainClass: Option[String]): Seq[String] = Seq(s"$millDefaultProjectName.test") - def jvmTestScalacOptions(className: String): Unit = + def jvmTestScalacOptions(className: String, exportArgs: Seq[String]): Unit = ExportTestProjects.jvmTest(actualScalaVersion, className).withMillJvmOpts.fromRoot { root => - exportCommand(".").call(cwd = root, stdout = os.Inherit) + exportCommand(exportArgs :+ "."*).call(cwd = root, stdout = os.Inherit) val res = buildToolCommand( root, @@ -50,9 +51,9 @@ abstract class ExportMillTestDefinitions extends ScalaCliSuite expect(output.filterNot(_.isWhitespace) == "[\"-deprecation\"]") } - def jvmTestCompilerPlugin(mainClass: String): Unit = + def jvmTestCompilerPlugin(mainClass: String, exportArgs: Seq[String]): Unit = ExportTestProjects.jvmTest(actualScalaVersion, mainClass).withMillJvmOpts.fromRoot { root => - exportCommand(".").call(cwd = root, stdout = os.Inherit) + exportCommand(exportArgs :+ "."*).call(cwd = root, stdout = os.Inherit) locally { // scalacPluginIvyDeps val res = @@ -79,38 +80,43 @@ abstract class ExportMillTestDefinitions extends ScalaCliSuite } } - if (runExportTests) { - test("JVM custom project name") { + for { + millVersion <- Constants.supportedMillVersions + millVersionArgs = Seq("--mill-version", millVersion) + if runExportTests + } { + test(s"JVM custom project name (Mill $millVersion)") { TestUtil.retryOnCi() { val customProjectName = "newproject" jvmTest( mainArgs = Seq(s"$customProjectName.run"), testArgs = Seq(s"$customProjectName.test"), - extraExportArgs = Seq("-p", customProjectName), + extraExportArgs = Seq("-p", customProjectName) ++ millVersionArgs, mainClassName = "Hello" ) } } - test("JVM scalac options") { + test(s"JVM scalac options (Mill $millVersion)") { TestUtil.retryOnCi() { - jvmTestScalacOptions("Hello") + jvmTestScalacOptions(className = "Hello", exportArgs = millVersionArgs) } } - } - if (runExportTests && !actualScalaVersion.startsWith("3.")) - test("JVM with compiler plugin") { - TestUtil.retryOnCi() { - jvmTestCompilerPlugin("Hello") + if !actualScalaVersion.startsWith("3.") then + test(s"JVM with compiler plugin (Mill $millVersion)") { + TestUtil.retryOnCi() { + jvmTestCompilerPlugin(mainClass = "Hello", exportArgs = millVersionArgs) + } } - } - test("Scala Native") { - // FIXME this should be adjusted to Scala Native 0.5.x syntax once Mill gets support for it - TestUtil.retryOnCi() { - simpleTest( - ExportTestProjects.nativeTest(actualScalaVersion), - mainClass = None - ) + test(s"Scala Native (Mill $millVersion)") { + // FIXME this should be adjusted to Scala Native 0.5.x syntax once Mill gets support for it + TestUtil.retryOnCi() { + simpleTest( + inputs = ExportTestProjects.nativeTest(actualScalaVersion), + mainClass = None, + extraExportArgs = millVersionArgs + ) + } } } } diff --git a/modules/integration/src/test/scala/scala/cli/integration/ExportScalaOrientedBuildToolsTestDefinitions.scala b/modules/integration/src/test/scala/scala/cli/integration/ExportScalaOrientedBuildToolsTestDefinitions.scala index f37dc71da8..dccafbed2f 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/ExportScalaOrientedBuildToolsTestDefinitions.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/ExportScalaOrientedBuildToolsTestDefinitions.scala @@ -70,23 +70,25 @@ trait ExportScalaOrientedBuildToolsTestDefinitions { expect(output.contains("Hello")) } - if (runExportTests) { - test("compile-time only for jsoniter macros") { + if runExportTests then { + test(s"compile-time only for jsoniter macros$commonTestDescriptionSuffix") { TestUtil.retryOnCi() { compileOnlyTest("main") } } - test("Scala.js") { + test(s"Scala.js$commonTestDescriptionSuffix") { TestUtil.retryOnCi() { simpleTest(ExportTestProjects.jsTest(actualScalaVersion), mainClass = None) } } - test("zio test") { + test(s"zio test$commonTestDescriptionSuffix") { TestUtil.retryOnCi() { testZioTest("ZioSpec") } } - test("Ensure test framework NPE is not thrown when depending on logback") { + test( + s"Ensure test framework NPE is not thrown when depending on logback$commonTestDescriptionSuffix" + ) { TestUtil.retryOnCi() { logbackBugCase("main") } diff --git a/project/deps/package.mill.scala b/project/deps/package.mill.scala index 09d100048f..7d3bbdef1c 100644 --- a/project/deps/package.mill.scala +++ b/project/deps/package.mill.scala @@ -1,6 +1,7 @@ package build.project.deps import coursier.version.Version import mill._ +import mill.api.BuildInfo import scalalib._ object Cli { @@ -142,6 +143,8 @@ object Deps { def javaClassName = "0.1.9" def bloop = "2.0.17" def sbtVersion = "1.11.7" + def mill012Version = "0.12.17" + def mill10Version = "1.0.6" def mavenVersion = "3.8.1" def mavenScalaCompilerPluginVersion = "4.9.1" def mavenExecPluginVersion = "3.3.0" @@ -150,6 +153,14 @@ object Deps { def mavenAppVersion = "0.1-SNAPSHOT" def scalafix = "0.14.4" } + + // Supported Mill versions for exported builds as covered by integration tests + def supportedMillVersions = Seq( + BuildInfo.millVersion, + Deps.Versions.mill012Version, + Deps.Versions.mill10Version + ).distinct + // DO NOT hardcode a Scala version in this dependency string // This dependency is used to ensure that Ammonite is available for Scala versions // that Scala CLI supports. From 77ad17e15397d830e718185fc8c674c05ae1cb89 Mon Sep 17 00:00:00 2001 From: Piotr Chabelski Date: Tue, 23 Dec 2025 15:31:55 +0100 Subject: [PATCH 3/5] Run Mill tests for both Mill 0.12.x & Mill 1.0.y --- build.mill.scala | 3 +- .../ExportCommonTestDefinitions.scala | 50 ++++++++++++++----- .../integration/ExportMill012Tests212.scala | 3 ++ .../integration/ExportMill012Tests213.scala | 27 ++++++++++ .../integration/ExportMill012Tests3Lts.scala | 3 ++ .../ExportMill012Tests3NextRc.scala | 3 ++ .../ExportMill012TestsDefault.scala | 3 ++ .../integration/ExportMill10Tests212.scala | 3 ++ .../integration/ExportMill10Tests213.scala | 27 ++++++++++ .../integration/ExportMill10Tests3Lts.scala | 3 ++ .../ExportMill10Tests3NextRc.scala | 3 ++ .../ExportMill10TestsDefault.scala | 3 ++ .../ExportMillTestDefinitions.scala | 46 +++++++---------- .../cli/integration/ExportMillTests212.scala | 3 -- .../cli/integration/ExportMillTests213.scala | 15 ------ .../cli/integration/ExportMillTests3Lts.scala | 3 -- .../integration/ExportMillTests3NextRc.scala | 3 -- .../integration/ExportMillTestsDefault.scala | 3 -- ...alaOrientedBuildToolsTestDefinitions.scala | 24 +++++---- project/deps/package.mill.scala | 11 +--- 20 files changed, 152 insertions(+), 87 deletions(-) create mode 100644 modules/integration/src/test/scala/scala/cli/integration/ExportMill012Tests212.scala create mode 100644 modules/integration/src/test/scala/scala/cli/integration/ExportMill012Tests213.scala create mode 100644 modules/integration/src/test/scala/scala/cli/integration/ExportMill012Tests3Lts.scala create mode 100644 modules/integration/src/test/scala/scala/cli/integration/ExportMill012Tests3NextRc.scala create mode 100644 modules/integration/src/test/scala/scala/cli/integration/ExportMill012TestsDefault.scala create mode 100644 modules/integration/src/test/scala/scala/cli/integration/ExportMill10Tests212.scala create mode 100644 modules/integration/src/test/scala/scala/cli/integration/ExportMill10Tests213.scala create mode 100644 modules/integration/src/test/scala/scala/cli/integration/ExportMill10Tests3Lts.scala create mode 100644 modules/integration/src/test/scala/scala/cli/integration/ExportMill10Tests3NextRc.scala create mode 100644 modules/integration/src/test/scala/scala/cli/integration/ExportMill10TestsDefault.scala delete mode 100644 modules/integration/src/test/scala/scala/cli/integration/ExportMillTests212.scala delete mode 100644 modules/integration/src/test/scala/scala/cli/integration/ExportMillTests213.scala delete mode 100644 modules/integration/src/test/scala/scala/cli/integration/ExportMillTests3Lts.scala delete mode 100644 modules/integration/src/test/scala/scala/cli/integration/ExportMillTests3NextRc.scala delete mode 100644 modules/integration/src/test/scala/scala/cli/integration/ExportMillTestsDefault.scala diff --git a/build.mill.scala b/build.mill.scala index 7c8c35136e..ef709aa381 100644 --- a/build.mill.scala +++ b/build.mill.scala @@ -1090,7 +1090,8 @@ trait CliIntegration extends SbtModule with ScalaCliPublishModule with HasTests | def jmhCoreModule = "${Deps.jmhCore.dep.module.name.value}" | def jmhGeneratorBytecodeModule = "${Deps.jmhGeneratorBytecode.dep.module.name.value}" | def defaultMillVersion = "${BuildInfo.millVersion}" - | def supportedMillVersions = Seq("${Deps.supportedMillVersions.mkString("\", \"")}") + | def mill012Version = "${Deps.Versions.mill012Version}" + | def mill10Version = "${Deps.Versions.mill10Version}" |} |""".stripMargin if (!os.isFile(dest) || os.read(dest) != code) diff --git a/modules/integration/src/test/scala/scala/cli/integration/ExportCommonTestDefinitions.scala b/modules/integration/src/test/scala/scala/cli/integration/ExportCommonTestDefinitions.scala index 4597e3024f..b9855dd4a0 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/ExportCommonTestDefinitions.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/ExportCommonTestDefinitions.scala @@ -14,6 +14,7 @@ trait ExportCommonTestDefinitions { this: ScalaCliSuite & TestScalaVersionArgs = protected def runExportTests: Boolean = Properties.isMac protected def exportCommand(args: String*): os.proc + protected def defaultExportCommandArgs: Seq[String] = Nil protected def buildToolCommand(root: os.Path, mainClass: Option[String], args: String*): os.proc @@ -64,32 +65,40 @@ trait ExportCommonTestDefinitions { this: ScalaCliSuite & TestScalaVersionArgs = ) // maven returns 'BUILD SUCCESS' } - protected def scalaVersionTest(scalaVersion: String, mainClass: String): Unit = + protected def scalaVersionTest( + scalaVersion: String, + mainClass: String, + extraExportArgs: Seq[String] = Nil + ): Unit = prepareTestInputs(ExportTestProjects.scalaVersionTest(scalaVersion, mainClass)).fromRoot { root => - exportCommand(".").call(cwd = root, stdout = os.Inherit) + exportCommand("." +: extraExportArgs*).call(cwd = root, stdout = os.Inherit) val res = buildToolCommand(root, Some(mainClass), runMainArgs(Some(mainClass))*) .call(cwd = root / outputDir) val output = res.out.text(Charset.defaultCharset()) expect(output.contains("Hello")) } - def extraSourceFromDirectiveWithExtraDependency(mainClass: String, inputs: String*): Unit = + def extraSourceFromDirectiveWithExtraDependency( + mainClass: String, + extraExportArgs: Seq[String], + inputs: String* + ): Unit = prepareTestInputs( ExportTestProjects.extraSourceFromDirectiveWithExtraDependency(actualScalaVersion, mainClass) ).fromRoot { root => - exportCommand(inputs*).call(cwd = root, stdout = os.Inherit) + exportCommand(extraExportArgs ++ inputs*).call(cwd = root, stdout = os.Inherit) val res = buildToolCommand(root, Some(mainClass), runMainArgs(Some(mainClass))*) .call(cwd = root / outputDir) val output = res.out.trim(Charset.defaultCharset()) expect(output.contains(root.toString)) } - def justTestScope(mainClass: String): Unit = { + def justTestScope(mainClass: String, extraExportArgs: Seq[String] = Nil): Unit = { val expectedMessage = "exporting just the test scope actually works!" prepareTestInputs(ExportTestProjects.justTestScope(mainClass, expectedMessage)) .fromRoot { root => - exportCommand(".").call(cwd = root) + exportCommand("." +: extraExportArgs*).call(cwd = root) val testRes = buildToolCommand(root, Some(mainClass), runTestsArgs(Some(mainClass))*) .call(cwd = root / outputDir) val testOutput = testRes.out.text() @@ -97,24 +106,37 @@ trait ExportCommonTestDefinitions { this: ScalaCliSuite & TestScalaVersionArgs = } } - private val scalaVersionsInDir: Seq[String] = Seq("2.12", "2.13", "2", "3", "3.lts") + protected val scalaVersionsInDir: Seq[String] = Seq("2.12", "2.13", "2", "3", "3.lts") if (runExportTests) { test(s"JVM$commonTestDescriptionSuffix") { TestUtil.retryOnCi() { - jvmTest(runMainArgs(Some("Main")), runTestsArgs(Some("Main")), mainClassName = "Main") + jvmTest( + mainArgs = runMainArgs(Some("Main")), + testArgs = runTestsArgs(Some("Main")), + mainClassName = "Main", + extraExportArgs = defaultExportCommandArgs + ) } } test(s"extra source from a directive introducing a dependency$commonTestDescriptionSuffix") { TestUtil.retryOnCi() { - extraSourceFromDirectiveWithExtraDependency("Main", "Main.scala") + extraSourceFromDirectiveWithExtraDependency( + mainClass = "Main", + extraExportArgs = defaultExportCommandArgs, + inputs = "Main.scala" + ) } } test( s"extra source passed both via directive and from command line$commonTestDescriptionSuffix" ) { TestUtil.retryOnCi() { - extraSourceFromDirectiveWithExtraDependency("Main", ".") + extraSourceFromDirectiveWithExtraDependency( + mainClass = "Main", + extraExportArgs = defaultExportCommandArgs, + inputs = "." + ) } } scalaVersionsInDir.foreach { scalaV => @@ -122,7 +144,11 @@ trait ExportCommonTestDefinitions { this: ScalaCliSuite & TestScalaVersionArgs = s"check export for project with scala version in directive as $scalaV$commonTestDescriptionSuffix" ) { TestUtil.retryOnCi() { - scalaVersionTest(scalaV, "Main") + scalaVersionTest( + scalaVersion = scalaV, + mainClass = "Main", + extraExportArgs = defaultExportCommandArgs + ) } } } @@ -130,7 +156,7 @@ trait ExportCommonTestDefinitions { this: ScalaCliSuite & TestScalaVersionArgs = test(s"just test scope$commonTestDescriptionSuffix") { // Keeping the test name ends with Test to support maven convention TestUtil.retryOnCi() { - justTestScope("MyTest") + justTestScope(mainClass = "MyTest", extraExportArgs = defaultExportCommandArgs) } } diff --git a/modules/integration/src/test/scala/scala/cli/integration/ExportMill012Tests212.scala b/modules/integration/src/test/scala/scala/cli/integration/ExportMill012Tests212.scala new file mode 100644 index 0000000000..3c51cea991 --- /dev/null +++ b/modules/integration/src/test/scala/scala/cli/integration/ExportMill012Tests212.scala @@ -0,0 +1,3 @@ +package scala.cli.integration + +class ExportMill012Tests212 extends ExportMillTestDefinitions with Test212 with TestMill012 diff --git a/modules/integration/src/test/scala/scala/cli/integration/ExportMill012Tests213.scala b/modules/integration/src/test/scala/scala/cli/integration/ExportMill012Tests213.scala new file mode 100644 index 0000000000..0a94ab9d13 --- /dev/null +++ b/modules/integration/src/test/scala/scala/cli/integration/ExportMill012Tests213.scala @@ -0,0 +1,27 @@ +package scala.cli.integration + +class ExportMill012Tests213 extends ExportMillTestDefinitions with Test213 with TestMill012 { + if runExportTests then { + test(s"scalac options$commonTestDescriptionSuffix") { + simpleTest( + inputs = ExportTestProjects.scalacOptionsScala2Test(actualScalaVersion), + mainClass = None, + extraExportArgs = defaultExportCommandArgs + ) + } + test(s"pure java$commonTestDescriptionSuffix") { + simpleTest( + inputs = ExportTestProjects.pureJavaTest("ScalaCliJavaTest"), + mainClass = None, + extraExportArgs = defaultExportCommandArgs + ) + } + test(s"custom JAR$commonTestDescriptionSuffix") { + simpleTest( + inputs = ExportTestProjects.customJarTest(actualScalaVersion), + mainClass = None, + extraExportArgs = defaultExportCommandArgs + ) + } + } +} diff --git a/modules/integration/src/test/scala/scala/cli/integration/ExportMill012Tests3Lts.scala b/modules/integration/src/test/scala/scala/cli/integration/ExportMill012Tests3Lts.scala new file mode 100644 index 0000000000..81a8fa98fd --- /dev/null +++ b/modules/integration/src/test/scala/scala/cli/integration/ExportMill012Tests3Lts.scala @@ -0,0 +1,3 @@ +package scala.cli.integration + +class ExportMill012Tests3Lts extends ExportMillTestDefinitions with Test3Lts with TestMill012 diff --git a/modules/integration/src/test/scala/scala/cli/integration/ExportMill012Tests3NextRc.scala b/modules/integration/src/test/scala/scala/cli/integration/ExportMill012Tests3NextRc.scala new file mode 100644 index 0000000000..1ce2a43730 --- /dev/null +++ b/modules/integration/src/test/scala/scala/cli/integration/ExportMill012Tests3NextRc.scala @@ -0,0 +1,3 @@ +package scala.cli.integration + +class ExportMill012Tests3NextRc extends ExportMillTestDefinitions with Test3NextRc with TestMill012 diff --git a/modules/integration/src/test/scala/scala/cli/integration/ExportMill012TestsDefault.scala b/modules/integration/src/test/scala/scala/cli/integration/ExportMill012TestsDefault.scala new file mode 100644 index 0000000000..e2c26ef54e --- /dev/null +++ b/modules/integration/src/test/scala/scala/cli/integration/ExportMill012TestsDefault.scala @@ -0,0 +1,3 @@ +package scala.cli.integration + +class ExportMill012TestsDefault extends ExportMillTestDefinitions with TestDefault with TestMill012 diff --git a/modules/integration/src/test/scala/scala/cli/integration/ExportMill10Tests212.scala b/modules/integration/src/test/scala/scala/cli/integration/ExportMill10Tests212.scala new file mode 100644 index 0000000000..32b57506b1 --- /dev/null +++ b/modules/integration/src/test/scala/scala/cli/integration/ExportMill10Tests212.scala @@ -0,0 +1,3 @@ +package scala.cli.integration + +class ExportMill10Tests212 extends ExportMillTestDefinitions with Test212 with TestMill10 diff --git a/modules/integration/src/test/scala/scala/cli/integration/ExportMill10Tests213.scala b/modules/integration/src/test/scala/scala/cli/integration/ExportMill10Tests213.scala new file mode 100644 index 0000000000..a31bf6d49d --- /dev/null +++ b/modules/integration/src/test/scala/scala/cli/integration/ExportMill10Tests213.scala @@ -0,0 +1,27 @@ +package scala.cli.integration + +class ExportMill10Tests213 extends ExportMillTestDefinitions with Test213 with TestMill10 { + if runExportTests then { + test(s"scalac options$commonTestDescriptionSuffix") { + simpleTest( + inputs = ExportTestProjects.scalacOptionsScala2Test(actualScalaVersion), + mainClass = None, + extraExportArgs = defaultExportCommandArgs + ) + } + test(s"pure java$commonTestDescriptionSuffix") { + simpleTest( + inputs = ExportTestProjects.pureJavaTest("ScalaCliJavaTest"), + mainClass = None, + extraExportArgs = defaultExportCommandArgs + ) + } + test(s"custom JAR$commonTestDescriptionSuffix") { + simpleTest( + inputs = ExportTestProjects.customJarTest(actualScalaVersion), + mainClass = None, + extraExportArgs = defaultExportCommandArgs + ) + } + } +} diff --git a/modules/integration/src/test/scala/scala/cli/integration/ExportMill10Tests3Lts.scala b/modules/integration/src/test/scala/scala/cli/integration/ExportMill10Tests3Lts.scala new file mode 100644 index 0000000000..a6b9df90a0 --- /dev/null +++ b/modules/integration/src/test/scala/scala/cli/integration/ExportMill10Tests3Lts.scala @@ -0,0 +1,3 @@ +package scala.cli.integration + +class ExportMill10Tests3Lts extends ExportMillTestDefinitions with Test3Lts with TestMill10 diff --git a/modules/integration/src/test/scala/scala/cli/integration/ExportMill10Tests3NextRc.scala b/modules/integration/src/test/scala/scala/cli/integration/ExportMill10Tests3NextRc.scala new file mode 100644 index 0000000000..6983894c78 --- /dev/null +++ b/modules/integration/src/test/scala/scala/cli/integration/ExportMill10Tests3NextRc.scala @@ -0,0 +1,3 @@ +package scala.cli.integration + +class ExportMill10Tests3NextRc extends ExportMillTestDefinitions with Test3NextRc with TestMill10 diff --git a/modules/integration/src/test/scala/scala/cli/integration/ExportMill10TestsDefault.scala b/modules/integration/src/test/scala/scala/cli/integration/ExportMill10TestsDefault.scala new file mode 100644 index 0000000000..50287d035e --- /dev/null +++ b/modules/integration/src/test/scala/scala/cli/integration/ExportMill10TestsDefault.scala @@ -0,0 +1,3 @@ +package scala.cli.integration + +class ExportMill10TestsDefault extends ExportMillTestDefinitions with TestDefault with TestMill10 diff --git a/modules/integration/src/test/scala/scala/cli/integration/ExportMillTestDefinitions.scala b/modules/integration/src/test/scala/scala/cli/integration/ExportMillTestDefinitions.scala index 6e2bd61d02..5b03fbb6b3 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/ExportMillTestDefinitions.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/ExportMillTestDefinitions.scala @@ -9,9 +9,8 @@ abstract class ExportMillTestDefinitions extends ScalaCliSuite with TestScalaVersionArgs with ExportCommonTestDefinitions with ExportScalaOrientedBuildToolsTestDefinitions - with MillTestHelper { this: TestScalaVersion => + with MillTestHelper { this: TestScalaVersion & TestMillVersion => override val prepareTestInputs: TestInputs => TestInputs = _.withMillJvmOpts - override def commonTestDescriptionSuffix = s" (Mill ${Constants.defaultMillVersion})" override val outputDir: RelPath = millOutputDir override def exportCommand(args: String*): os.proc = @@ -35,6 +34,10 @@ abstract class ExportMillTestDefinitions extends ScalaCliSuite override def runTestsArgs(mainClass: Option[String]): Seq[String] = Seq(s"$millDefaultProjectName.test") + override def commonTestDescriptionSuffix = s" (Mill $millVersion & Scala $actualScalaVersion)" + + override protected def defaultExportCommandArgs: Seq[String] = Seq("--mill-version", millVersion) + def jvmTestScalacOptions(className: String, exportArgs: Seq[String]): Unit = ExportTestProjects.jvmTest(actualScalaVersion, className).withMillJvmOpts.fromRoot { root => exportCommand(exportArgs :+ "."*).call(cwd = root, stdout = os.Inherit) @@ -80,43 +83,30 @@ abstract class ExportMillTestDefinitions extends ScalaCliSuite } } - for { - millVersion <- Constants.supportedMillVersions - millVersionArgs = Seq("--mill-version", millVersion) - if runExportTests - } { - test(s"JVM custom project name (Mill $millVersion)") { + if runExportTests then { + test(s"JVM custom project name$commonTestDescriptionSuffix") { TestUtil.retryOnCi() { val customProjectName = "newproject" jvmTest( mainArgs = Seq(s"$customProjectName.run"), testArgs = Seq(s"$customProjectName.test"), - extraExportArgs = Seq("-p", customProjectName) ++ millVersionArgs, + extraExportArgs = Seq("-p", customProjectName) ++ defaultExportCommandArgs, mainClassName = "Hello" ) } } - test(s"JVM scalac options (Mill $millVersion)") { - TestUtil.retryOnCi() { - jvmTestScalacOptions(className = "Hello", exportArgs = millVersionArgs) - } - } - if !actualScalaVersion.startsWith("3.") then - test(s"JVM with compiler plugin (Mill $millVersion)") { - TestUtil.retryOnCi() { - jvmTestCompilerPlugin(mainClass = "Hello", exportArgs = millVersionArgs) - } - } - - test(s"Scala Native (Mill $millVersion)") { - // FIXME this should be adjusted to Scala Native 0.5.x syntax once Mill gets support for it + test(s"JVM scalac options$commonTestDescriptionSuffix") { TestUtil.retryOnCi() { - simpleTest( - inputs = ExportTestProjects.nativeTest(actualScalaVersion), - mainClass = None, - extraExportArgs = millVersionArgs - ) + jvmTestScalacOptions(className = "Hello", exportArgs = defaultExportCommandArgs) } } } } + +sealed trait TestMillVersion: + def millVersion: String +trait TestMill012 extends TestMillVersion: + self: ExportMillTestDefinitions => override def millVersion: String = Constants.mill012Version +trait TestMill10 extends TestMillVersion: + self: ExportMillTestDefinitions => override def millVersion: String = Constants.mill10Version + diff --git a/modules/integration/src/test/scala/scala/cli/integration/ExportMillTests212.scala b/modules/integration/src/test/scala/scala/cli/integration/ExportMillTests212.scala deleted file mode 100644 index aee2fadee4..0000000000 --- a/modules/integration/src/test/scala/scala/cli/integration/ExportMillTests212.scala +++ /dev/null @@ -1,3 +0,0 @@ -package scala.cli.integration - -class ExportMillTests212 extends ExportMillTestDefinitions with Test212 diff --git a/modules/integration/src/test/scala/scala/cli/integration/ExportMillTests213.scala b/modules/integration/src/test/scala/scala/cli/integration/ExportMillTests213.scala deleted file mode 100644 index 243a1d3f23..0000000000 --- a/modules/integration/src/test/scala/scala/cli/integration/ExportMillTests213.scala +++ /dev/null @@ -1,15 +0,0 @@ -package scala.cli.integration - -class ExportMillTests213 extends ExportMillTestDefinitions with Test213 { - if (runExportTests) { - test("scalac options") { - simpleTest(ExportTestProjects.scalacOptionsScala2Test(actualScalaVersion), mainClass = None) - } - test("pure java") { - simpleTest(ExportTestProjects.pureJavaTest("ScalaCliJavaTest"), mainClass = None) - } - test("custom JAR") { - simpleTest(ExportTestProjects.customJarTest(actualScalaVersion), mainClass = None) - } - } -} diff --git a/modules/integration/src/test/scala/scala/cli/integration/ExportMillTests3Lts.scala b/modules/integration/src/test/scala/scala/cli/integration/ExportMillTests3Lts.scala deleted file mode 100644 index 075d70e624..0000000000 --- a/modules/integration/src/test/scala/scala/cli/integration/ExportMillTests3Lts.scala +++ /dev/null @@ -1,3 +0,0 @@ -package scala.cli.integration - -class ExportMillTests3Lts extends ExportMillTestDefinitions with Test3Lts diff --git a/modules/integration/src/test/scala/scala/cli/integration/ExportMillTests3NextRc.scala b/modules/integration/src/test/scala/scala/cli/integration/ExportMillTests3NextRc.scala deleted file mode 100644 index 543c53834a..0000000000 --- a/modules/integration/src/test/scala/scala/cli/integration/ExportMillTests3NextRc.scala +++ /dev/null @@ -1,3 +0,0 @@ -package scala.cli.integration - -class ExportMillTests3NextRc extends ExportMillTestDefinitions with Test3NextRc diff --git a/modules/integration/src/test/scala/scala/cli/integration/ExportMillTestsDefault.scala b/modules/integration/src/test/scala/scala/cli/integration/ExportMillTestsDefault.scala deleted file mode 100644 index 0d0d204f7e..0000000000 --- a/modules/integration/src/test/scala/scala/cli/integration/ExportMillTestsDefault.scala +++ /dev/null @@ -1,3 +0,0 @@ -package scala.cli.integration - -class ExportMillTestsDefault extends ExportMillTestDefinitions with TestDefault diff --git a/modules/integration/src/test/scala/scala/cli/integration/ExportScalaOrientedBuildToolsTestDefinitions.scala b/modules/integration/src/test/scala/scala/cli/integration/ExportScalaOrientedBuildToolsTestDefinitions.scala index dccafbed2f..ab45da2514 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/ExportScalaOrientedBuildToolsTestDefinitions.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/ExportScalaOrientedBuildToolsTestDefinitions.scala @@ -11,12 +11,12 @@ import java.nio.charset.Charset trait ExportScalaOrientedBuildToolsTestDefinitions { this: ExportCommonTestDefinitions & ScalaCliSuite & TestScalaVersionArgs => - def compileOnlyTest(mainClass: String): Unit = { + def compileOnlyTest(mainClass: String, extraExportArgs: Seq[String] = Nil): Unit = { val userName = "John" prepareTestInputs( ExportTestProjects.compileOnlySource(actualScalaVersion, userName = userName) ).fromRoot { root => - exportCommand(".").call(cwd = root, stdout = os.Inherit) + exportCommand("." +: extraExportArgs*).call(cwd = root, stdout = os.Inherit) val res = buildToolCommand(root, None, runMainArgs(Some(mainClass))*) .call(cwd = root / outputDir) val output = res.out.trim(Charset.defaultCharset()) @@ -25,7 +25,7 @@ trait ExportScalaOrientedBuildToolsTestDefinitions { } } - def testZioTest(testClassName: String): Unit = { + def testZioTest(testClassName: String, extraExportArgs: Seq[String] = Nil): Unit = { val testInput = TestInputs( // todo: remove this hack after the PR https://github.com/VirtusLab/scala-cli/pull/3046 is merged os.rel / "Hello.scala" -> """object Hello extends App""", @@ -53,7 +53,7 @@ trait ExportScalaOrientedBuildToolsTestDefinitions { ) prepareTestInputs(testInput).fromRoot { root => - val exportArgs = Seq(".") + val exportArgs = "." +: extraExportArgs val testArgsToPass = runTestsArgs(None) exportCommand(exportArgs*).call(cwd = root, stdout = os.Inherit) val testRes = buildToolCommand(root, None, testArgsToPass*).call(cwd = root / outputDir) @@ -61,9 +61,9 @@ trait ExportScalaOrientedBuildToolsTestDefinitions { expect(testOutput.contains("1 succeeded")) } } - protected def logbackBugCase(mainClass: String): Unit = + protected def logbackBugCase(mainClass: String, extraExportArgs: Seq[String] = Nil): Unit = prepareTestInputs(ExportTestProjects.logbackBugCase(actualScalaVersion)).fromRoot { root => - exportCommand(".").call(cwd = root, stdout = os.Inherit) + exportCommand("." +: extraExportArgs*).call(cwd = root, stdout = os.Inherit) val res = buildToolCommand(root, Some(mainClass), runMainArgs(Some(mainClass))*) .call(cwd = root / outputDir) val output = res.out.text(Charset.defaultCharset()) @@ -73,24 +73,28 @@ trait ExportScalaOrientedBuildToolsTestDefinitions { if runExportTests then { test(s"compile-time only for jsoniter macros$commonTestDescriptionSuffix") { TestUtil.retryOnCi() { - compileOnlyTest("main") + compileOnlyTest(mainClass = "main", extraExportArgs = defaultExportCommandArgs) } } test(s"Scala.js$commonTestDescriptionSuffix") { TestUtil.retryOnCi() { - simpleTest(ExportTestProjects.jsTest(actualScalaVersion), mainClass = None) + simpleTest( + inputs = ExportTestProjects.jsTest(actualScalaVersion), + mainClass = None, + extraExportArgs = defaultExportCommandArgs + ) } } test(s"zio test$commonTestDescriptionSuffix") { TestUtil.retryOnCi() { - testZioTest("ZioSpec") + testZioTest(testClassName = "ZioSpec", extraExportArgs = defaultExportCommandArgs) } } test( s"Ensure test framework NPE is not thrown when depending on logback$commonTestDescriptionSuffix" ) { TestUtil.retryOnCi() { - logbackBugCase("main") + logbackBugCase(mainClass = "main", extraExportArgs = defaultExportCommandArgs) } } } diff --git a/project/deps/package.mill.scala b/project/deps/package.mill.scala index 7d3bbdef1c..2804c254c5 100644 --- a/project/deps/package.mill.scala +++ b/project/deps/package.mill.scala @@ -143,8 +143,8 @@ object Deps { def javaClassName = "0.1.9" def bloop = "2.0.17" def sbtVersion = "1.11.7" - def mill012Version = "0.12.17" - def mill10Version = "1.0.6" + def mill012Version = if (BuildInfo.millVersion.startsWith("0.12.")) BuildInfo.millVersion else "0.12.17" + def mill10Version = if (BuildInfo.millVersion.startsWith("1.0.")) BuildInfo.millVersion else "1.0.6" def mavenVersion = "3.8.1" def mavenScalaCompilerPluginVersion = "4.9.1" def mavenExecPluginVersion = "3.3.0" @@ -154,13 +154,6 @@ object Deps { def scalafix = "0.14.4" } - // Supported Mill versions for exported builds as covered by integration tests - def supportedMillVersions = Seq( - BuildInfo.millVersion, - Deps.Versions.mill012Version, - Deps.Versions.mill10Version - ).distinct - // DO NOT hardcode a Scala version in this dependency string // This dependency is used to ensure that Ammonite is available for Scala versions // that Scala CLI supports. From 26411cabe75669931c266b6ec43bb0207f34aaff Mon Sep 17 00:00:00 2001 From: Piotr Chabelski Date: Tue, 23 Dec 2025 17:10:41 +0100 Subject: [PATCH 4/5] Include default build tool versions in `export` `--help`/reference docs --- build.mill.scala | 7 +++ .../cli/commands/export0/ExportOptions.scala | 49 +++++++++++-------- .../ExportMillTestDefinitions.scala | 13 ++--- project/deps/package.mill.scala | 20 ++++---- website/docs/reference/cli-options.md | 12 +++-- 5 files changed, 61 insertions(+), 40 deletions(-) diff --git a/build.mill.scala b/build.mill.scala index ef709aa381..1ff073cbd6 100644 --- a/build.mill.scala +++ b/build.mill.scala @@ -841,6 +841,13 @@ trait Cli extends CrossSbtModule with ProtoBuildModule with CliLaunchers | def defaultGraalVMVersion = "${deps.graalVmVersion}" | def scalaPyVersion = "${Deps.scalaPy.dep.versionConstraint.asString}" | def signingCliJvmVersion = ${Deps.Versions.signingCliJvmVersion} + | def defaultMillVersion = "${BuildInfo.millVersion}" + | def mill012Version = "${Deps.Versions.mill012Version}" + | def mill10Version = "${Deps.Versions.mill10Version}" + | def defaultSbtVersion = "${Deps.Versions.sbtVersion}" + | def defaultMavenVersion = "${Deps.Versions.mavenVersion}" + | def defaultMavenScalaCompilerPluginVersion = "${Deps.Versions.mavenScalaCompilerPluginVersion}" + | def defaultMavenExecPluginVersion = "${Deps.Versions.mavenExecPluginVersion}" |} |""".stripMargin if (!os.isFile(dest) || os.read(dest) != code) diff --git a/modules/cli/src/main/scala/scala/cli/commands/export0/ExportOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/export0/ExportOptions.scala index 063e040940..67d7da103f 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/export0/ExportOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/export0/ExportOptions.scala @@ -11,66 +11,74 @@ import scala.cli.commands.shared.{ SharedOptions } import scala.cli.commands.tags +import scala.cli.commands.Constants -// format: off @HelpMessage(ExportOptions.helpMessage, "", ExportOptions.detailedHelpMessage) final case class ExportOptions( // FIXME There might be too many options for 'scala-cli export' there @Recurse - shared: SharedOptions = SharedOptions(), + shared: SharedOptions = SharedOptions(), @Recurse - mainClass: MainClassOptions = MainClassOptions(), - + mainClass: MainClassOptions = MainClassOptions(), @Group(HelpGroup.BuildToolExport.toString) @Tag(tags.restricted) @Tag(tags.inShortHelp) @HelpMessage("Sets the export format to SBT") - sbt: Option[Boolean] = None, + sbt: Option[Boolean] = None, @Group(HelpGroup.BuildToolExport.toString) @Tag(tags.experimental) @Tag(tags.inShortHelp) @HelpMessage("Sets the export format to Maven") @Name("mvn") - maven: Option[Boolean] = None, + maven: Option[Boolean] = None, @Group(HelpGroup.BuildToolExport.toString) @Tag(tags.restricted) @Tag(tags.inShortHelp) @HelpMessage("Sets the export format to Mill") - mill: Option[Boolean] = None, + mill: Option[Boolean] = None, @Tag(tags.restricted) @Tag(tags.inShortHelp) @Group(HelpGroup.BuildToolExport.toString) @HelpMessage("Sets the export format to Json") - json: Option[Boolean] = None, - + json: Option[Boolean] = None, @Name("setting") @Group(HelpGroup.BuildToolExport.toString) @Tag(tags.restricted) - sbtSetting: List[String] = Nil, + sbtSetting: List[String] = Nil, @Name("p") @Group(HelpGroup.BuildToolExport.toString) @Tag(tags.restricted) @HelpMessage("Project name to be used on Mill build file") - project: Option[String] = None, + project: Option[String] = None, @Group(HelpGroup.BuildToolExport.toString) @Tag(tags.restricted) - @HelpMessage("Version of SBT to be used for the export") - sbtVersion: Option[String] = None, + @HelpMessage( + s"Version of SBT to be used for the export (${Constants.defaultSbtVersion} by default)" + ) + sbtVersion: Option[String] = None, @Group(HelpGroup.BuildToolExport.toString) @Tag(tags.restricted) - @HelpMessage("Version of Mill to be used for the export") - millVersion: Option[String] = None, + @HelpMessage( + s"Version of Mill to be used for the export (${Constants.defaultMillVersion} by default)" + ) + millVersion: Option[String] = None, @Group(HelpGroup.BuildToolExport.toString) @Tag(tags.experimental) - @HelpMessage("Version of Maven Compiler Plugin to be used for the export") - mvnVersion: Option[String] = None, + @HelpMessage( + s"Version of Maven Compiler Plugin to be used for the export (${Constants.defaultMavenVersion} by default)" + ) + mvnVersion: Option[String] = None, @Group(HelpGroup.BuildToolExport.toString) @Tag(tags.experimental) - @HelpMessage("Version of Maven Scala Plugin to be used for the export") + @HelpMessage( + s"Version of Maven Scala Plugin to be used for the export (${Constants.defaultMavenScalaCompilerPluginVersion} by default)" + ) mvnScalaVersion: Option[String] = None, @Group(HelpGroup.BuildToolExport.toString) @Tag(tags.experimental) - @HelpMessage("Version of Maven Exec Plugin to be used for the export") + @HelpMessage( + s"Version of Maven Exec Plugin to be used for the export (${Constants.defaultMavenExecPluginVersion} by default)" + ) mvnExecPluginVersion: Option[String] = None, @Group(HelpGroup.BuildToolExport.toString) @Tag(tags.experimental) @@ -87,9 +95,8 @@ final case class ExportOptions( @Name("o") @Group(HelpGroup.BuildToolExport.toString) @Tag(tags.restricted) - output: Option[String] = None, + output: Option[String] = None ) extends HasSharedOptions -// format: on object ExportOptions { implicit lazy val parser: Parser[ExportOptions] = Parser.derive implicit lazy val help: Help[ExportOptions] = Help.derive diff --git a/modules/integration/src/test/scala/scala/cli/integration/ExportMillTestDefinitions.scala b/modules/integration/src/test/scala/scala/cli/integration/ExportMillTestDefinitions.scala index 5b03fbb6b3..6fd3d9ecea 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/ExportMillTestDefinitions.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/ExportMillTestDefinitions.scala @@ -103,10 +103,11 @@ abstract class ExportMillTestDefinitions extends ScalaCliSuite } } -sealed trait TestMillVersion: +sealed trait TestMillVersion: def millVersion: String -trait TestMill012 extends TestMillVersion: - self: ExportMillTestDefinitions => override def millVersion: String = Constants.mill012Version -trait TestMill10 extends TestMillVersion: - self: ExportMillTestDefinitions => override def millVersion: String = Constants.mill10Version - +trait TestMill012 extends TestMillVersion: + self: ExportMillTestDefinitions => + override def millVersion: String = Constants.mill012Version +trait TestMill10 extends TestMillVersion: + self: ExportMillTestDefinitions => + override def millVersion: String = Constants.mill10Version diff --git a/project/deps/package.mill.scala b/project/deps/package.mill.scala index 2804c254c5..9a02d139f1 100644 --- a/project/deps/package.mill.scala +++ b/project/deps/package.mill.scala @@ -143,15 +143,17 @@ object Deps { def javaClassName = "0.1.9" def bloop = "2.0.17" def sbtVersion = "1.11.7" - def mill012Version = if (BuildInfo.millVersion.startsWith("0.12.")) BuildInfo.millVersion else "0.12.17" - def mill10Version = if (BuildInfo.millVersion.startsWith("1.0.")) BuildInfo.millVersion else "1.0.6" - def mavenVersion = "3.8.1" - def mavenScalaCompilerPluginVersion = "4.9.1" - def mavenExecPluginVersion = "3.3.0" - def mavenAppArtifactId = "maven-app" - def mavenAppGroupId = "com.example" - def mavenAppVersion = "0.1-SNAPSHOT" - def scalafix = "0.14.4" + def mill012Version = + if (BuildInfo.millVersion.startsWith("0.12.")) BuildInfo.millVersion else "0.12.17" + def mill10Version = + if (BuildInfo.millVersion.startsWith("1.0.")) BuildInfo.millVersion else "1.0.6" + def mavenVersion = "3.8.1" + def mavenScalaCompilerPluginVersion = "4.9.1" + def mavenExecPluginVersion = "3.3.0" + def mavenAppArtifactId = "maven-app" + def mavenAppGroupId = "com.example" + def mavenAppVersion = "0.1-SNAPSHOT" + def scalafix = "0.14.4" } // DO NOT hardcode a Scala version in this dependency string diff --git a/website/docs/reference/cli-options.md b/website/docs/reference/cli-options.md index 0e51ecde60..a10e1b29e7 100644 --- a/website/docs/reference/cli-options.md +++ b/website/docs/reference/cli-options.md @@ -384,19 +384,23 @@ Project name to be used on Mill build file ### `--sbt-version` -Version of SBT to be used for the export +Version of SBT to be used for the export (1.11.7 by default) + +### `--mill-version` + +Version of Mill to be used for the export (0.12.17 by default) ### `--mvn-version` -Version of Maven Compiler Plugin to be used for the export +Version of Maven Compiler Plugin to be used for the export (3.8.1 by default) ### `--mvn-scala-version` -Version of Maven Scala Plugin to be used for the export +Version of Maven Scala Plugin to be used for the export (4.9.1 by default) ### `--mvn-exec-plugin-version` -Version of Maven Exec Plugin to be used for the export +Version of Maven Exec Plugin to be used for the export (3.3.0 by default) ### `--mvn-app-artifact-id` From b51131204d5291ff6af8a383a540a86477729f56 Mon Sep 17 00:00:00 2001 From: Piotr Chabelski Date: Tue, 23 Dec 2025 17:16:15 +0100 Subject: [PATCH 5/5] misc `export` Mill tweaks --- .../scala/cli/commands/export0/Export.scala | 4 +- .../cli/commands/export0/ExportOptions.scala | 3 +- .../cli/exportCmd/MillProjectDescriptor.scala | 37 ++++++++----------- 3 files changed, 18 insertions(+), 26 deletions(-) diff --git a/modules/cli/src/main/scala/scala/cli/commands/export0/Export.scala b/modules/cli/src/main/scala/scala/cli/commands/export0/Export.scala index 2c09090944..9c1364441c 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/export0/Export.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/export0/Export.scala @@ -102,8 +102,8 @@ object Export extends ScalaCommand[ExportOptions] { logger: Logger ): MillProjectDescriptor = { val launcherArtifacts = Seq( - os.rel / "mill" -> s"https://github.com/com-lihaoyi/mill/raw/${Constants.millVersion}/mill", - os.rel / "mill.bat" -> s"https://github.com/com-lihaoyi/mill/raw/${Constants.millVersion}/mill.bat" + os.rel / "mill" -> s"https://github.com/com-lihaoyi/mill/raw/$millVersion/mill", + os.rel / "mill.bat" -> s"https://github.com/com-lihaoyi/mill/raw/$millVersion/mill.bat" ) val launcherTasks = launcherArtifacts.map { case (path, url) => diff --git a/modules/cli/src/main/scala/scala/cli/commands/export0/ExportOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/export0/ExportOptions.scala index 67d7da103f..1412fedd21 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/export0/ExportOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/export0/ExportOptions.scala @@ -10,8 +10,7 @@ import scala.cli.commands.shared.{ MainClassOptions, SharedOptions } -import scala.cli.commands.tags -import scala.cli.commands.Constants +import scala.cli.commands.{Constants, tags} @HelpMessage(ExportOptions.helpMessage, "", ExportOptions.detailedHelpMessage) final case class ExportOptions( diff --git a/modules/cli/src/main/scala/scala/cli/exportCmd/MillProjectDescriptor.scala b/modules/cli/src/main/scala/scala/cli/exportCmd/MillProjectDescriptor.scala index f267f81163..f0f08646cd 100644 --- a/modules/cli/src/main/scala/scala/cli/exportCmd/MillProjectDescriptor.scala +++ b/modules/cli/src/main/scala/scala/cli/exportCmd/MillProjectDescriptor.scala @@ -30,14 +30,14 @@ final case class MillProjectDescriptor( val pureJava = ProjectDescriptor.isPureJavaProject(options, sources) - val sv = options.scalaParams.toOption.flatten.map(_.scalaVersion).getOrElse( - ScalaCli.getDefaultScalaVersion - ) - - if (pureJava) - MillProject() - else - MillProject(scalaVersion = Some(sv)) + val sv = options.scalaParams + .toOption + .flatten + .map(_.scalaVersion) + .getOrElse(ScalaCli.getDefaultScalaVersion) + + if pureJava then MillProject() + else MillProject(scalaVersion = Some(sv)) } private def scalaCompilerPlugins(buildOptions: BuildOptions): MillProject = @@ -49,9 +49,7 @@ final case class MillProjectDescriptor( MillProject(scalacOptions = buildOptions.scalaOptions.scalacOptions.toSeq.map(_.value.value)) private def scalaJsSettings(options: ScalaJsOptions): MillProject = { - - val scalaJsVersion = Some(options.version.getOrElse(Constants.scalaJsVersion)) - + val scalaJsVersion = Some(options.version.getOrElse(Constants.scalaJsVersion)) val moduleKindDecls = if (options.moduleKindStr.isEmpty) Nil else @@ -108,14 +106,12 @@ final case class MillProjectDescriptor( } private def customResourcesSettings(options: BuildOptions): MillProject = - MillProject( - resourcesDirs = options.classPathOptions.resourcesDir - ) + MillProject(resourcesDirs = options.classPathOptions.resourcesDir) private def customJarsSettings(options: BuildOptions): MillProject = { val customCompileOnlyJarsDecls = - if (options.classPathOptions.extraCompileOnlyJars.isEmpty) Nil + if options.classPathOptions.extraCompileOnlyJars.isEmpty then Nil else { val jars = options.classPathOptions.extraCompileOnlyJars.map(p => s"""PathRef(os.Path("$p"))""") @@ -123,7 +119,7 @@ final case class MillProjectDescriptor( } val customJarsDecls = - if (options.classPathOptions.extraClassPath.isEmpty) Nil + if options.classPathOptions.extraClassPath.isEmpty then Nil else { val jars = options.classPathOptions.extraClassPath.map(p => s"""PathRef(os.Path("$p"))""") Seq( @@ -131,13 +127,10 @@ final case class MillProjectDescriptor( ) } - MillProject( - extraDecls = customCompileOnlyJarsDecls ++ customJarsDecls - ) + MillProject(extraDecls = customCompileOnlyJarsDecls ++ customJarsDecls) } private def testFrameworkSettings(options: BuildOptions): MillProject = { - val testClassPath: Seq[Path] = options.artifacts(logger, Scope.Test) match { case Right(artifacts) => artifacts.classPath.map(_.toNIO) case Left(exception) => @@ -185,9 +178,9 @@ final case class MillProjectDescriptor( scalaCompilerPlugins(optionsMain), dependencySettings(optionsMain, optionsTest), repositorySettings(optionsMain), - if (optionsMain.platform.value == Platform.JS) scalaJsSettings(optionsMain.scalaJsOptions) + if optionsMain.platform.value == Platform.JS then scalaJsSettings(optionsMain.scalaJsOptions) else MillProject(), - if (optionsMain.platform.value == Platform.Native) + if optionsMain.platform.value == Platform.Native then scalaNativeSettings(optionsMain.scalaNativeOptions) else MillProject(), customResourcesSettings(optionsMain),