diff --git a/.github/scripts/check-cross-version-deps.sc b/.github/scripts/check-cross-version-deps.sc
index 64f16dcea5..64c23335ba 100755
--- a/.github/scripts/check-cross-version-deps.sc
+++ b/.github/scripts/check-cross-version-deps.sc
@@ -11,9 +11,9 @@ val modules =
for { module <- modules } {
println(s"Checking for $module...")
- val depRegex = "\\[\\d+]\\s+[│└├─\\S\\s]+\\s([\\w.-]+):([\\w.-]+):([\\w\\s\\S.-]+)".r
+ val depRegex = "[│└├─\\S\\s]+\\s([\\w.-]+):([\\w.-]+):([\\w\\s\\S.-]+)".r
val scalaDepSuffixRegex = "^(.+?)(_[23](?:\\.\\d{2})?)?$".r
- val deps = os.proc(os.pwd / "mill", "-i", s"$module.ivyDepsTree")
+ val deps = os.proc(os.pwd / "mill", "-i", s"$module.showMvnDepsTree")
.call(cwd = os.pwd)
.out
.lines()
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 5a4a0fff20..c8cc0a6b5c 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1455,7 +1455,7 @@ jobs:
- name: Check native-image config format
run: ./mill -i __.checkNativeImageConfFormat
- name: Check Ammonite availability
- run: ./mill -i 'dummy.amm[_].resolvedRunIvyDeps'
+ run: ./mill -i 'dummy.amm[_].resolvedRunMvnDeps'
- name: Check for cross Scala version conflicts
run: .github/scripts/check-cross-version-deps.sc
- name: Scalafix check
diff --git a/.mill-version b/.mill-version
index bcc7c361e1..af0b7ddbff 100644
--- a/.mill-version
+++ b/.mill-version
@@ -1 +1 @@
-0.12.16
+1.0.6
diff --git a/build.mill.scala b/build.mill.scala
index b19a0f8cdd..7186fdf20d 100644
--- a/build.mill.scala
+++ b/build.mill.scala
@@ -1,9 +1,12 @@
+//| mvnDeps:
+//| - io.github.alexarchambault.mill::mill-native-image::0.2.4
+//| - io.github.alexarchambault.mill::mill-native-image-upload:0.2.4
+//| - com.goyeau::mill-scalafix::0.6.0
+//| - com.lumidion::sonatype-central-client-requests:0.6.0
+//| - io.get-coursier:coursier-launcher_2.13:2.1.25-M21
+//| - org.eclipse.jgit:org.eclipse.jgit:7.3.0.202506031305-r
package build
-import $packages._
-import $ivy.`com.lihaoyi::mill-contrib-bloop:$MILL_VERSION`
-import $ivy.`io.get-coursier::coursier-launcher:2.1.25-M21`
-import $ivy.`io.github.alexarchambault.mill::mill-native-image-upload:0.1.31-1`
import build.ci.publishVersion
import build.project.deps
import deps.{Cli, Deps, Docker, InternalDeps, Java, Scala, TestDeps}
@@ -15,6 +18,7 @@ import settings.{
FormatNativeImageConf,
HasTests,
LocalRepo,
+ LocatedInModules,
PublishLocalNoFluff,
ScalaCliCrossSbtModule,
ScalaCliScalafixModule,
@@ -33,39 +37,35 @@ import java.io.File
import java.net.URL
import java.nio.charset.Charset
import java.util.Locale
-import de.tobiasroeser.mill.vcs.version.VcsVersion
import io.github.alexarchambault.millnativeimage.upload.Upload
-import mill._
-import mill.api.Loose
-import scalalib.{publish => _, _}
-import mill.contrib.bloop.Bloop
-import mill.define.Task.Simple
-import mill.testrunner.TestResult
+import mill.*
+import mill.api.{BuildCtx, ModuleCtx, Task}
+import mill.scalalib.*
+import scalalib.{publish as _, *}
+import mill.javalib.testrunner.TestResult
+import mill.util.{Tasks, VcsVersion}
import _root_.scala.util.{Properties, Using}
-
-// Tell mill modules are under modules/
-implicit def millModuleBasePath: define.Ctx.BasePath =
- define.Ctx.BasePath(super.millModuleBasePath.value / "modules")
+import _root_.scala.util.{Properties, Using}
object cli extends Cross[Cli](Scala.scala3MainVersions) with CrossScalaDefaultToInternal
-trait CrossScalaDefault { _: mill.define.Cross[_] =>
+trait CrossScalaDefault { self: Cross[?] =>
def crossScalaDefaultVersion: String
override def defaultCrossSegments: Seq[String] = Seq(crossScalaDefaultVersion)
}
-trait CrossScalaDefaultToInternal extends CrossScalaDefault { _: mill.define.Cross[_] =>
+trait CrossScalaDefaultToInternal extends CrossScalaDefault { self: Cross[?] =>
override def crossScalaDefaultVersion: String = Scala.defaultInternal
}
-trait CrossScalaDefaultToRunner extends CrossScalaDefault { _: mill.define.Cross[_] =>
+trait CrossScalaDefaultToRunner extends CrossScalaDefault { self: Cross[?] =>
override def crossScalaDefaultVersion: String = Scala.runnerScala3
}
// Publish a bootstrapped, executable jar for a restricted environments
object cliBootstrapped extends ScalaCliPublishModule {
- override def unmanagedClasspath: T[Agg[PathRef]] =
+ override def unmanagedClasspath: T[Seq[PathRef]] =
Task(cli(Scala.defaultInternal).nativeImageClassPath())
override def jar: T[PathRef] = assembly()
@@ -80,9 +80,7 @@ object cliBootstrapped extends ScalaCliPublishModule {
Assembly.Rule.ExcludePattern(".*\\.semanticdb")
) ++ super.assemblyRules
- override def resources: T[Seq[PathRef]] = Task.Sources {
- super.resources() ++ Seq(propertiesFilesResources())
- }
+ override def resources: T[Seq[PathRef]] = super.resources() ++ Seq(propertiesFilesResources())
def propertiesFilesResources: T[PathRef] = Task(persistent = true) {
val dir = Task.dest / "resources"
@@ -98,27 +96,33 @@ object `specification-level` extends Cross[SpecificationLevel](Scala.scala3MainV
with CrossScalaDefaultToInternal
object `build-macros` extends Cross[BuildMacros](Scala.scala3MainVersions)
with CrossScalaDefaultToInternal
-object config extends Cross[Config](Scala.scala3MainVersions) with CrossScalaDefaultToInternal
-object options extends Cross[Options](Scala.scala3MainVersions) with CrossScalaDefaultToInternal
+object config extends Cross[Config](Scala.scala3MainVersions)
+ with CrossScalaDefaultToInternal
+object options extends Cross[Options](Scala.scala3MainVersions)
+ with CrossScalaDefaultToInternal
object directives extends Cross[Directives](Scala.scala3MainVersions)
with CrossScalaDefaultToInternal
-object core extends Cross[Core](Scala.scala3MainVersions) with CrossScalaDefaultToInternal
+object core extends Cross[Core](Scala.scala3MainVersions)
+ with CrossScalaDefaultToInternal
object `build-module` extends Cross[Build](Scala.scala3MainVersions)
with CrossScalaDefaultToInternal
-object runner extends Cross[Runner](Scala.runnerScalaVersions) with CrossScalaDefaultToRunner
+object runner extends Cross[Runner](Scala.runnerScalaVersions)
+ with CrossScalaDefaultToRunner
object `test-runner` extends Cross[TestRunner](Scala.runnerScalaVersions)
with CrossScalaDefaultToRunner
object `tasty-lib` extends Cross[TastyLib](Scala.scala3MainVersions)
with CrossScalaDefaultToInternal
-object `scala-cli-bsp` extends JavaModule with ScalaCliPublishModule {
- override def ivyDeps: T[Agg[Dep]] = super.ivyDeps() ++ Seq(
+object `scala-cli-bsp` extends JavaModule
+ with ScalaCliPublishModule
+ with LocatedInModules {
+ override def mvnDeps: T[Seq[Dep]] = super.mvnDeps() ++ Seq(
Deps.bsp4j
)
}
object integration extends CliIntegration {
object test extends IntegrationScalaTests {
- override def ivyDeps: T[Loose.Agg[Dep]] = super.ivyDeps() ++ Seq(
+ override def mvnDeps: T[Seq[Dep]] = super.mvnDeps() ++ Seq(
Deps.coursierArchiveCache,
Deps.jgit,
Deps.jsoup
@@ -126,10 +130,8 @@ object integration extends CliIntegration {
}
object docker extends CliIntegrationDocker {
object test extends ScalaCliTests {
- override def sources: T[Seq[PathRef]] = Task.Sources {
- super.sources() ++ integration.sources()
- }
- def tmpDirBase: T[PathRef] = Task(persistent = true) {
+ override def sources: T[Seq[PathRef]] = super.sources() ++ integration.sources()
+ def tmpDirBase: T[PathRef] = Task(persistent = true) {
PathRef(Task.dest / "working-dir")
}
override def forkEnv: T[Map[String, String]] = super.forkEnv() ++ Seq(
@@ -142,10 +144,8 @@ object integration extends CliIntegration {
object `docker-slim` extends CliIntegrationDocker {
object test extends ScalaCliTests {
- override def sources: T[Seq[PathRef]] = Task.Sources {
- integration.docker.test.sources()
- }
- def tmpDirBase: T[PathRef] = Task(persistent = true) {
+ override def sources: T[Seq[PathRef]] = integration.docker.test.sources()
+ def tmpDirBase: T[PathRef] = Task(persistent = true) {
PathRef(Task.dest / "working-dir")
}
override def forkEnv: T[Map[String, String]] = super.forkEnv() ++ Seq(
@@ -160,8 +160,9 @@ object integration extends CliIntegration {
object `docs-tests` extends Cross[DocsTests](Scala.scala3MainVersions)
with CrossScalaDefaultToInternal
-trait DocsTests extends CrossSbtModule with ScalaCliScalafixModule with HasTests { main =>
- override def ivyDeps: T[Agg[Dep]] = Agg(
+trait DocsTests extends CrossSbtModule with ScalaCliScalafixModule with LocatedInModules
+ with HasTests { main =>
+ override def mvnDeps: T[Seq[Dep]] = Seq(
Deps.fansi,
Deps.osLib,
Deps.pprint
@@ -200,26 +201,28 @@ trait DocsTests extends CrossSbtModule with ScalaCliScalafixModule with HasTests
object test extends ScalaCliTests with ScalaCliScalafixModule {
override def forkEnv: T[Map[String, String]] = super.forkEnv() ++ extraEnv() ++ Seq(
- "SCALA_CLI_EXAMPLES" -> (Task.workspace / "examples").toString,
- "SCALA_CLI_GIF_SCENARIOS" -> (Task.workspace / "gifs" / "scenarios").toString,
- "SCALA_CLI_WEBSITE_IMG" -> (Task.workspace / "website" / "static" / "img").toString,
- "SCALA_CLI_GIF_RENDERER_DOCKER_DIR" -> (Task.workspace / "gifs").toString,
- "SCALA_CLI_SVG_RENDERER_DOCKER_DIR" -> (Task.workspace / "gifs" / "svg_render").toString
+ "SCALA_CLI_EXAMPLES" -> (BuildCtx.workspaceRoot / "examples").toString,
+ "SCALA_CLI_GIF_SCENARIOS" -> (BuildCtx.workspaceRoot / "gifs" / "scenarios").toString,
+ "SCALA_CLI_WEBSITE_IMG" -> (BuildCtx.workspaceRoot / "website" / "static" / "img").toString,
+ "SCALA_CLI_GIF_RENDERER_DOCKER_DIR" -> (BuildCtx.workspaceRoot / "gifs").toString,
+ "SCALA_CLI_SVG_RENDERER_DOCKER_DIR" -> (BuildCtx.workspaceRoot / "gifs" / "svg_render").toString
)
- override def resources: T[Seq[PathRef]] = Task.Sources {
- // Adding markdown directories here, so that they're watched for changes in watch mode
- Seq(
- PathRef(Task.workspace / "website" / "docs" / "commands"),
- PathRef(Task.workspace / "website" / "docs" / "cookbooks")
- ) ++ super.resources()
+ private def customResources: T[Seq[PathRef]] = {
+ val customPaths: Seq[os.Path] = Seq(
+ BuildCtx.workspaceRoot / "website" / "docs" / "commands",
+ BuildCtx.workspaceRoot / "website" / "docs" / "cookbooks"
+ )
+ Task.Sources(customPaths*)
}
+ override def resources: T[Seq[PathRef]] =
+ // Adding markdown directories here, so that they're watched for changes in watch mode
+ super.resources() ++ customResources()
}
}
-object packager extends ScalaModule with Bloop.Module {
- override def skipBloop = true
+object packager extends ScalaModule {
override def scalaVersion: T[String] = Scala.scala3Lts
- override def ivyDeps: T[Agg[Dep]] = Agg(
+ override def mvnDeps: T[Seq[Dep]] = Seq(
Deps.scalaPackagerCli
)
override def mainClass: T[Option[String]] = Some("packager.cli.PackagerCli")
@@ -228,13 +231,15 @@ object packager extends ScalaModule with Bloop.Module {
object `generate-reference-doc` extends Cross[GenerateReferenceDoc](Scala.scala3MainVersions)
with CrossScalaDefaultToInternal
-trait GenerateReferenceDoc extends CrossSbtModule with ScalaCliScalafixModule {
+trait GenerateReferenceDoc extends CrossSbtModule
+ with LocatedInModules
+ with ScalaCliScalafixModule {
override def moduleDeps: Seq[JavaModule] = Seq(
cli(crossScalaVersion)
)
override def repositoriesTask: Task[Seq[Repository]] =
Task.Anon(super.repositoriesTask() ++ customRepositories)
- override def ivyDeps: T[Agg[Dep]] = Agg(
+ override def mvnDeps: T[Seq[Dep]] = Seq(
Deps.argonautShapeless,
Deps.caseApp,
Deps.munit
@@ -246,45 +251,40 @@ trait GenerateReferenceDoc extends CrossSbtModule with ScalaCliScalafixModule {
)
}
-object dummy extends Module {
+object dummy extends LocatedInModules {
// dummy projects to get scala steward updates for Ammonite and scalafmt, whose
// versions are used in the fmt and repl commands, and ensure Ammonite is available
// for all Scala versions we support.
object amm extends Cross[Amm](Scala.listMaxAmmoniteScalaVersion)
- trait Amm extends Cross.Module[String] with CrossScalaModule with Bloop.Module {
+ trait Amm extends Cross.Module[String] with CrossScalaModule {
override def crossScalaVersion: String = crossValue
- override def skipBloop = true
- override def ivyDeps: T[Agg[Dep]] = {
+ override def mvnDeps: T[Seq[Dep]] = {
val ammoniteDep =
if (crossValue == Scala.scala3Lts) Deps.ammoniteForScala3Lts
else Deps.ammonite
- Agg(ammoniteDep)
+ Seq(ammoniteDep)
}
}
- object scalafmt extends ScalaModule with Bloop.Module {
- override def skipBloop = true
+ object scalafmt extends ScalaModule {
override def scalaVersion: T[String] = Scala.defaultInternal
- override def ivyDeps: T[Agg[Dep]] = Agg(
+ override def mvnDeps: T[Seq[Dep]] = Seq(
Deps.scalafmtCli
)
}
- object pythonInterface extends JavaModule with Bloop.Module {
- override def skipBloop = true
- override def ivyDeps: T[Agg[Dep]] = Agg(
+ object pythonInterface extends JavaModule {
+ override def mvnDeps: T[Seq[Dep]] = Seq(
Deps.pythonInterface
)
}
- object scalaPy extends ScalaModule with Bloop.Module {
- override def skipBloop = true
+ object scalaPy extends ScalaModule {
override def scalaVersion: T[String] = Scala.defaultInternal
- override def ivyDeps: T[Agg[Dep]] = Agg(
+ override def mvnDeps: T[Seq[Dep]] = Seq(
Deps.scalaPy
)
}
- object scalafix extends ScalaModule with Bloop.Module {
- override def skipBloop = true
+ object scalafix extends ScalaModule {
override def scalaVersion: T[String] = Scala.defaultInternal
- override def ivyDeps: T[Agg[Dep]] = Agg(
+ override def mvnDeps: T[Seq[Dep]] = Seq(
Deps.scalafixInterfaces
)
}
@@ -293,11 +293,12 @@ object dummy extends Module {
trait BuildMacros extends ScalaCliCrossSbtModule
with ScalaCliPublishModule
with ScalaCliScalafixModule
- with HasTests {
+ with HasTests
+ with LocatedInModules {
override def crossScalaVersion: String = crossValue
- override def compileIvyDeps: T[Agg[Dep]] = Task {
- if (crossScalaVersion.startsWith("3")) super.compileIvyDeps()
- else super.compileIvyDeps() ++ Agg(Deps.scalaReflect(crossScalaVersion))
+ override def compileMvnDeps: T[Seq[Dep]] = Task {
+ if (crossScalaVersion.startsWith("3")) super.compileMvnDeps()
+ else super.compileMvnDeps() ++ Seq(Deps.scalaReflect(crossScalaVersion))
}
object test extends ScalaCliTests with ScalaCliScalafixModule {
@@ -306,7 +307,7 @@ trait BuildMacros extends ScalaCliCrossSbtModule
}
def testNegativeCompilation(): Command[Unit] = Task.Command(exclusive = true) {
- val base = Task.workspace / "modules" / "build-macros" / "src"
+ val base = BuildCtx.workspaceRoot / "modules" / "build-macros" / "src"
val negativeTests = Seq(
"MismatchedLeft.scala" -> Seq(
"Found: +EE1".r,
@@ -333,7 +334,7 @@ trait BuildMacros extends ScalaCliCrossSbtModule
).call(
check = false,
mergeErrIntoOut = true,
- cwd = Task.workspace
+ cwd = BuildCtx.workspaceRoot
)
val compileResult = compile()
if (compileResult.exitCode != 0) {
@@ -382,7 +383,8 @@ trait ProtoBuildModule extends ScalaCliPublishModule with HasTests
trait Core extends ScalaCliCrossSbtModule
with ScalaCliPublishModule
with HasTests
- with ScalaCliScalafixModule {
+ with ScalaCliScalafixModule
+ with LocatedInModules {
override def crossScalaVersion: String = crossValue
override def moduleDeps: Seq[SonatypeCentralPublishModule] = Seq(
@@ -398,7 +400,7 @@ trait Core extends ScalaCliCrossSbtModule
override def repositoriesTask: Task[Seq[Repository]] =
Task.Anon(super.repositoriesTask() ++ deps.customRepositories)
- override def ivyDeps: T[Agg[Dep]] = super.ivyDeps() ++ Agg(
+ override def mvnDeps: T[Seq[Dep]] = super.mvnDeps() ++ Seq(
Deps.bloopRifle.exclude(("org.scala-lang.modules", "scala-collection-compat_2.13")),
Deps.collectionCompat,
Deps.coursierJvm
@@ -419,7 +421,7 @@ trait Core extends ScalaCliCrossSbtModule
Deps.scalaJsLogging,
Deps.swoval
)
- override def compileIvyDeps: T[Agg[Dep]] = super.compileIvyDeps() ++ Seq(
+ override def compileMvnDeps: T[Seq[Dep]] = super.compileMvnDeps() ++ Seq(
Deps.jsoniterMacros
)
@@ -583,7 +585,8 @@ trait Core extends ScalaCliCrossSbtModule
trait Directives extends ScalaCliCrossSbtModule
with ScalaCliPublishModule
with HasTests
- with ScalaCliScalafixModule {
+ with ScalaCliScalafixModule
+ with LocatedInModules {
override def crossScalaVersion: String = crossValue
override def moduleDeps: Seq[SonatypeCentralPublishModule] = Seq(
options(crossScalaVersion),
@@ -595,11 +598,11 @@ trait Directives extends ScalaCliCrossSbtModule
super.scalacOptions() ++ asyncScalacOptions(crossScalaVersion)
}
- override def compileIvyDeps: T[Agg[Dep]] = super.compileIvyDeps() ++ Agg(
+ override def compileMvnDeps: T[Seq[Dep]] = super.compileMvnDeps() ++ Seq(
Deps.jsoniterMacros,
Deps.svm
)
- override def ivyDeps: T[Agg[Dep]] = super.ivyDeps() ++ Agg(
+ override def mvnDeps: T[Seq[Dep]] = super.mvnDeps() ++ Seq(
// Deps.asm,
Deps.bloopConfig,
Deps.jsoniterCore,
@@ -611,7 +614,7 @@ trait Directives extends ScalaCliCrossSbtModule
Task.Anon(super.repositoriesTask() ++ deps.customRepositories)
object test extends ScalaCliTests {
- override def ivyDeps: T[Loose.Agg[Dep]] = super.ivyDeps() ++ Agg(
+ override def mvnDeps: T[Seq[Dep]] = super.mvnDeps() ++ Seq(
Deps.pprint
)
override def runClasspath: T[Seq[PathRef]] = Task {
@@ -646,17 +649,21 @@ trait Directives extends ScalaCliCrossSbtModule
trait Config extends ScalaCliCrossSbtModule
with ScalaCliPublishModule
- with ScalaCliScalafixModule {
+ with ScalaCliScalafixModule
+ with LocatedInModules {
override def crossScalaVersion: String = crossValue
override def moduleDeps: Seq[SonatypeCentralPublishModule] =
Seq(`specification-level`(crossScalaVersion))
- override def ivyDeps: T[Agg[Dep]] = super.ivyDeps() ++ Agg(Deps.jsoniterCore)
- override def compileIvyDeps: T[Agg[Dep]] = super.compileIvyDeps() ++ Agg(Deps.jsoniterMacros)
+ override def mvnDeps: T[Seq[Dep]] = super.mvnDeps() ++ Seq(Deps.jsoniterCore)
+ override def compileMvnDeps: T[Seq[Dep]] = super.compileMvnDeps() ++ Seq(Deps.jsoniterMacros)
override def scalacOptions: T[Seq[String]] = super.scalacOptions() ++ Seq("-deprecation")
}
-trait Options extends ScalaCliCrossSbtModule with ScalaCliPublishModule with HasTests
- with ScalaCliScalafixModule {
+trait Options extends ScalaCliCrossSbtModule
+ with ScalaCliPublishModule
+ with HasTests
+ with ScalaCliScalafixModule
+ with LocatedInModules {
override def crossScalaVersion: String = crossValue
override def moduleDeps: Seq[SonatypeCentralPublishModule] = Seq(
core(crossScalaVersion)
@@ -668,11 +675,11 @@ trait Options extends ScalaCliCrossSbtModule with ScalaCliPublishModule with Has
super.scalacOptions() ++ asyncScalacOptions(crossScalaVersion)
}
- override def ivyDeps: T[Agg[Dep]] = super.ivyDeps() ++ Agg(
+ override def mvnDeps: T[Seq[Dep]] = super.mvnDeps() ++ Seq(
Deps.bloopConfig,
Deps.signingCliShared
)
- override def compileIvyDeps: T[Agg[Dep]] = super.compileIvyDeps() ++ Seq(
+ override def compileMvnDeps: T[Seq[Dep]] = super.compileMvnDeps() ++ Seq(
Deps.jsoniterMacros
)
@@ -691,9 +698,10 @@ trait Options extends ScalaCliCrossSbtModule with ScalaCliPublishModule with Has
trait Build extends ScalaCliCrossSbtModule
with ScalaCliPublishModule
with HasTests
- with ScalaCliScalafixModule {
- override def crossScalaVersion: String = crossValue
- override def millSourcePath: os.Path = super.millSourcePath / os.up / "build"
+ with ScalaCliScalafixModule
+ with LocatedInModules {
+ override def crossScalaVersion: String = crossValue
+ override def moduleDir: os.Path = super.moduleDir / os.up / "build"
override def moduleDeps: Seq[SonatypeCentralPublishModule] = Seq(
options(crossScalaVersion),
directives(crossScalaVersion),
@@ -705,11 +713,11 @@ trait Build extends ScalaCliCrossSbtModule
super.scalacOptions() ++ asyncScalacOptions(crossScalaVersion)
}
- override def compileIvyDeps: T[Agg[Dep]] = super.compileIvyDeps() ++ Agg(
+ override def compileMvnDeps: T[Seq[Dep]] = super.compileMvnDeps() ++ Seq(
Deps.jsoniterMacros,
Deps.svm
)
- override def ivyDeps: T[Agg[Dep]] = super.ivyDeps() ++ Agg(
+ override def mvnDeps: T[Seq[Dep]] = super.mvnDeps() ++ Seq(
Deps.asm,
Deps.collectionCompat,
Deps.javaClassName,
@@ -729,7 +737,7 @@ trait Build extends ScalaCliCrossSbtModule
object test extends ScalaCliTests with ScalaCliScalafixModule {
override def scalacOptions: T[Seq[String]] = super.scalacOptions() ++ Seq("-deprecation")
- override def ivyDeps: T[Loose.Agg[Dep]] = super.ivyDeps() ++ Agg(
+ override def mvnDeps: T[Seq[Dep]] = super.mvnDeps() ++ Seq(
Deps.pprint,
Deps.slf4jNop
)
@@ -775,12 +783,14 @@ trait Build extends ScalaCliCrossSbtModule
}
trait SpecificationLevel extends ScalaCliCrossSbtModule
- with ScalaCliPublishModule {
+ with ScalaCliPublishModule
+ with LocatedInModules {
override def crossScalaVersion: String = crossValue
}
trait Cli extends CrossSbtModule with ProtoBuildModule with CliLaunchers
- with FormatNativeImageConf {
+ with FormatNativeImageConf
+ with LocatedInModules {
// Copied from Mill: https://github.com/com-lihaoyi/mill/blob/ea367c09bd31a30464ca901cb29863edde5340be/scalalib/src/mill/scalalib/JavaModule.scala#L792
def debug(port: Int, args: Task[Args] = Task.Anon(Args())): Command[Unit] = Task.Command {
try mill.api.Result.Success(
@@ -878,9 +888,7 @@ trait Cli extends CrossSbtModule with ProtoBuildModule with CliLaunchers
}
PathRef(dir)
}
- override def resources: T[Seq[PathRef]] = Task.Sources {
- super.resources() ++ Seq(defaultFilesResources())
- }
+ override def resources: T[Seq[PathRef]] = super.resources() ++ Seq(defaultFilesResources())
override def scalacOptions: T[Seq[String]] = Task {
super.scalacOptions() ++ asyncScalacOptions(crossScalaVersion) ++ Seq("-deprecation")
@@ -897,7 +905,7 @@ trait Cli extends CrossSbtModule with ProtoBuildModule with CliLaunchers
override def repositoriesTask: Task[Seq[Repository]] =
Task.Anon(super.repositoriesTask() ++ customRepositories)
- override def ivyDeps: T[Agg[Dep]] = super.ivyDeps() ++ Agg(
+ override def mvnDeps: T[Seq[Dep]] = super.mvnDeps() ++ Seq(
Deps.caseApp,
Deps.coursierLauncher,
Deps.coursierProxySetup,
@@ -916,17 +924,17 @@ trait Cli extends CrossSbtModule with ProtoBuildModule with CliLaunchers
Deps.scala3Graal, // TODO: drop this if we ever bump internal JDK to 24+
Deps.scala3GraalProcessor // TODO: drop this if we ever bump internal JDK to 24+
)
- override def compileIvyDeps: T[Agg[Dep]] = super.compileIvyDeps() ++ Agg(
+ override def compileMvnDeps: T[Seq[Dep]] = super.compileMvnDeps() ++ Seq(
Deps.jsoniterMacros,
Deps.svm
)
override def mainClass: T[Option[String]] = Some("scala.cli.ScalaCli")
- private def scala3GraalProcessorClassPath: T[Agg[PathRef]] = T {
- resolveDeps(T {
+ private def scala3GraalProcessorClassPath: T[Seq[PathRef]] = Task {
+ defaultResolver().classpath {
val bind = bindDependency()
- Agg(Deps.scala3GraalProcessor).map(bind)
- })()
+ Seq(Deps.scala3GraalProcessor).map(bind)
+ }
}
override def nativeImageClassPath: T[Seq[PathRef]] = Task {
@@ -953,7 +961,7 @@ trait Cli extends CrossSbtModule with ProtoBuildModule with CliLaunchers
super.runClasspath() ++ Seq(localRepoJar())
}
- override def compileIvyDeps: T[Agg[Dep]] = super.ivyDeps() ++ Agg(
+ override def compileMvnDeps: T[Seq[Dep]] = super.mvnDeps() ++ Seq(
Deps.jsoniterMacros
)
@@ -964,8 +972,11 @@ trait Cli extends CrossSbtModule with ProtoBuildModule with CliLaunchers
}
}
-trait CliIntegration extends SbtModule with ScalaCliPublishModule with HasTests
- with ScalaCliScalafixModule {
+trait CliIntegration extends SbtModule
+ with ScalaCliPublishModule
+ with HasTests
+ with ScalaCliScalafixModule
+ with LocatedInModules {
override def scalaVersion: T[String] = sv
def sv: String = Scala.scala3Lts
@@ -977,12 +988,12 @@ trait CliIntegration extends SbtModule with ScalaCliPublishModule with HasTests
super.scalacOptions() ++ Seq("-deprecation")
}
- override def ivyDeps: T[Agg[Dep]] = super.ivyDeps() ++ Agg(
+ override def mvnDeps: T[Seq[Dep]] = super.mvnDeps() ++ Seq(
Deps.osLib
)
trait IntegrationScalaTests extends super.ScalaCliTests with ScalaCliScalafixModule {
- override def ivyDeps: T[Loose.Agg[Dep]] = super.ivyDeps() ++ Agg(
+ override def mvnDeps: T[Seq[Dep]] = super.mvnDeps() ++ Seq(
Deps.bsp4j,
Deps.coursier
.exclude(("com.github.plokhotnyuk.jsoniter-scala", "jsoniter-scala-macros")),
@@ -993,7 +1004,7 @@ trait CliIntegration extends SbtModule with ScalaCliPublishModule with HasTests
Deps.slf4jNop,
Deps.usingDirectives
)
- override def compileIvyDeps: T[Agg[Dep]] = super.compileIvyDeps() ++ Seq(
+ override def compileMvnDeps: T[Seq[Dep]] = super.compileMvnDeps() ++ Seq(
Deps.jsoniterMacros
)
override def forkEnv: T[Map[String, String]] = super.forkEnv() ++ Seq(
@@ -1006,7 +1017,7 @@ trait CliIntegration extends SbtModule with ScalaCliPublishModule with HasTests
val dir = Task.dest / "constants"
val dest = dir / "Constants.scala"
val mostlyStaticDockerfile =
- Task.workspace / ".github" / "scripts" / "docker" / "ScalaCliSlimDockerFile"
+ BuildCtx.workspaceRoot / ".github" / "scripts" / "docker" / "ScalaCliSlimDockerFile"
assert(
os.exists(mostlyStaticDockerfile),
s"Error: $mostlyStaticDockerfile not found"
@@ -1099,48 +1110,61 @@ trait CliIntegration extends SbtModule with ScalaCliPublishModule with HasTests
override def generatedSources: T[Seq[PathRef]] =
super.generatedSources() ++ Seq(constantsFile())
- override def test(args: String*): Command[(String, Seq[TestResult])] = jvm(args: _*)
+ override def testForked(args: String*): Command[(msg: String, results: Seq[TestResult])] =
+ jvm(args*)
def forcedLauncher: T[PathRef] = Task(persistent = true) {
val ext = if (Properties.isWin) ".exe" else ""
val launcher = Task.dest / s"scala-cli$ext"
- if (!os.exists(launcher)) {
- val dir = Option(System.getenv("SCALA_CLI_IT_FORCED_LAUNCHER_DIRECTORY")).getOrElse {
- sys.error("SCALA_CLI_IT_FORCED_LAUNCHER_DIRECTORY not set")
+ if !os.exists(launcher) then
+ BuildCtx.withFilesystemCheckerDisabled {
+ val dir = Option(System.getenv("SCALA_CLI_IT_FORCED_LAUNCHER_DIRECTORY")).getOrElse {
+ sys.error("SCALA_CLI_IT_FORCED_LAUNCHER_DIRECTORY not set")
+ }
+ System.err.println(s"SCALA_CLI_IT_FORCED_LAUNCHER_DIRECTORY was set to $dir")
+ val content = importedLauncher(dir, BuildCtx.workspaceRoot)
+ System.err.println(s"writing launcher to $launcher")
+ os.write(
+ launcher,
+ content,
+ createFolders = true,
+ perms = if (Properties.isWin) null else "rwxr-xr-x"
+ )
}
- val content = importedLauncher(dir, Task.workspace)
- os.write(
- launcher,
- content,
- createFolders = true,
- perms = if (Properties.isWin) null else "rwxr-xr-x"
- )
- }
PathRef(launcher)
}
def forcedStaticLauncher: T[PathRef] = Task(persistent = true) {
val launcher = Task.dest / "scala-cli"
- if (!os.exists(launcher)) {
- val dir = Option(System.getenv("SCALA_CLI_IT_FORCED_STATIC_LAUNCHER_DIRECTORY")).getOrElse {
- sys.error("SCALA_CLI_IT_FORCED_STATIC_LAUNCHER_DIRECTORY not set")
+ if !os.exists(launcher) then
+ BuildCtx.withFilesystemCheckerDisabled {
+ val dir =
+ Option(System.getenv("SCALA_CLI_IT_FORCED_STATIC_LAUNCHER_DIRECTORY")).getOrElse {
+ sys.error("SCALA_CLI_IT_FORCED_STATIC_LAUNCHER_DIRECTORY not set")
+ }
+ System.err.println(s"SCALA_CLI_IT_FORCED_STATIC_LAUNCHER_DIRECTORY was set to $dir")
+ val content = importedLauncher(dir, BuildCtx.workspaceRoot)
+ System.err.println(s"writing launcher to $launcher")
+ os.write(launcher, content, createFolders = true)
}
- val content = importedLauncher(dir, Task.workspace)
- os.write(launcher, content, createFolders = true)
- }
PathRef(launcher)
}
def forcedMostlyStaticLauncher: T[PathRef] = Task(persistent = true) {
val launcher = Task.dest / "scala-cli"
- if (!os.exists(launcher)) {
- val dir =
- Option(System.getenv("SCALA_CLI_IT_FORCED_MOSTLY_STATIC_LAUNCHER_DIRECTORY")).getOrElse {
- sys.error("SCALA_CLI_IT_FORCED_MOSTLY_STATIC_LAUNCHER_DIRECTORY not set")
- }
- val content = importedLauncher(dir, Task.workspace)
- os.write(launcher, content, createFolders = true)
- }
+ if !os.exists(launcher) then
+ BuildCtx.withFilesystemCheckerDisabled {
+ val dir =
+ Option(System.getenv("SCALA_CLI_IT_FORCED_MOSTLY_STATIC_LAUNCHER_DIRECTORY")).getOrElse {
+ sys.error("SCALA_CLI_IT_FORCED_MOSTLY_STATIC_LAUNCHER_DIRECTORY not set")
+ }
+ System.err.println(
+ s"SCALA_CLI_IT_FORCED_MOSTLY_STATIC_LAUNCHER_DIRECTORY was set to $dir"
+ )
+ val content = importedLauncher(dir, BuildCtx.workspaceRoot)
+ System.err.println(s"writing launcher to $launcher")
+ os.write(launcher, content, createFolders = true)
+ }
PathRef(launcher)
}
@@ -1193,58 +1217,66 @@ trait CliIntegration extends SbtModule with ScalaCliPublishModule with HasTests
private def testArgs(args: Seq[String], launcher: os.Path, cliKind: String): Seq[String] =
extraTestArgs(launcher, cliKind) ++ debugTestArgs(args)
- def jvm(args: String*): Command[(String, Seq[TestResult])] = Task.Command {
+ def jvm(args: String*): Command[(msg: String, results: Seq[TestResult])] = Task.Command {
testTask(
Task.Anon(args ++ testArgs(args, Launchers.jvm().path, "jvm")),
Task.Anon(Seq.empty[String])
)()
}
- def jvmBootstrapped(args: String*): Command[(String, Seq[TestResult])] = Task.Command {
- testTask(
- Task.Anon(args ++ testArgs(args, Launchers.jvmBootstrapped().path, "jvmBootstrapped")),
- Task.Anon(Seq.empty[String])
- )()
- }
- def native(args: String*): Command[(String, Seq[TestResult])] = Task.Command {
+
+ def jvmBootstrapped(args: String*): Command[(msg: String, results: Seq[TestResult])] =
+ Task.Command {
+ testTask(
+ Task.Anon(args ++ testArgs(args, Launchers.jvmBootstrapped().path, "jvmBootstrapped")),
+ Task.Anon(Seq.empty[String])
+ )()
+ }
+
+ def native(args: String*): Command[(msg: String, results: Seq[TestResult])] = Task.Command {
testTask(
Task.Anon(args ++ testArgs(args, Launchers.native().path, "native")),
Task.Anon(Seq.empty[String])
)()
}
- def nativeStatic(args: String*): Command[(String, Seq[TestResult])] = Task.Command {
- testTask(
- Task.Anon(args ++ testArgs(args, Launchers.nativeStatic().path, "native-static")),
- Task.Anon(Seq.empty[String])
- )()
- }
- def nativeMostlyStatic(args: String*): Command[(String, Seq[TestResult])] = Task.Command {
- testTask(
- Task.Anon(args ++ testArgs(
- args,
- Launchers.nativeMostlyStatic().path,
- "native-mostly-static"
- )),
- Task.Anon(Seq.empty[String])
- )()
- }
+
+ def nativeStatic(args: String*): Command[(msg: String, results: Seq[TestResult])] =
+ Task.Command {
+ testTask(
+ Task.Anon(args ++ testArgs(args, Launchers.nativeStatic().path, "native-static")),
+ Task.Anon(Seq.empty[String])
+ )()
+ }
+
+ def nativeMostlyStatic(args: String*): Command[(msg: String, results: Seq[TestResult])] =
+ Task.Command {
+ testTask(
+ Task.Anon(args ++ testArgs(
+ args,
+ Launchers.nativeMostlyStatic().path,
+ "native-mostly-static"
+ )),
+ Task.Anon(Seq.empty[String])
+ )()
+ }
}
}
trait CliIntegrationDocker extends SbtModule with ScalaCliPublishModule with HasTests {
override def scalaVersion: T[String] = Scala.scala3Lts
- override def ivyDeps: T[Agg[Dep]] = super.ivyDeps() ++ Agg(
+ override def mvnDeps: T[Seq[Dep]] = super.mvnDeps() ++ Seq(
Deps.osLib
)
}
trait Runner extends CrossSbtModule
with ScalaCliPublishModule
- with ScalaCliScalafixModule {
+ with ScalaCliScalafixModule
+ with LocatedInModules {
override def scalacOptions: T[Seq[String]] = Task {
super.scalacOptions() ++ Seq("-deprecation")
}
override def mainClass: T[Option[String]] = Some("scala.cli.runner.Runner")
- override def sources: T[Seq[PathRef]] = Task.Sources {
+ override def sources: T[Seq[PathRef]] = {
val scala3DirName =
if (crossScalaVersion.contains("-RC")) "scala-3-unstable" else "scala-3-stable"
val extraDirs = Seq(PathRef(moduleDir / "src" / "main" / scala3DirName))
@@ -1254,11 +1286,12 @@ trait Runner extends CrossSbtModule
trait TestRunner extends CrossSbtModule
with ScalaCliPublishModule
- with ScalaCliScalafixModule {
+ with ScalaCliScalafixModule
+ with LocatedInModules {
override def scalacOptions: T[Seq[String]] = Task {
super.scalacOptions() ++ Seq("-deprecation")
}
- override def ivyDeps: T[Agg[Dep]] = super.ivyDeps() ++ Agg(
+ override def mvnDeps: T[Seq[Dep]] = super.mvnDeps() ++ Seq(
Deps.asm,
Deps.collectionCompat,
Deps.testInterface
@@ -1268,7 +1301,8 @@ trait TestRunner extends CrossSbtModule
trait TastyLib extends ScalaCliCrossSbtModule
with ScalaCliPublishModule
- with ScalaCliScalafixModule {
+ with ScalaCliScalafixModule
+ with LocatedInModules {
override def crossScalaVersion: String = crossValue
def constantsFile: T[PathRef] = Task(persistent = true) {
val dir = Task.dest / "constants"
@@ -1305,7 +1339,7 @@ object `local-repo` extends LocalRepo {
}
// Helper CI commands
-def publishSonatype(tasks: mill.main.Tasks[PublishModule.PublishData]) = Task.Command {
+def publishSonatype(tasks: Tasks[PublishModule.PublishData]) = Task.Command {
val taskNames = tasks.value.map(_.toString())
System.err.println(
s"""Tasks producing artifacts to be included in the bundle:
@@ -1316,16 +1350,16 @@ def publishSonatype(tasks: mill.main.Tasks[PublishModule.PublishData]) = Task.Co
val bundleName = s"$organization-$ghName-$pv"
System.err.println(s"Publishing bundle: $bundleName")
publish.publishSonatype(
- data = define.Task.sequence(tasks.value)(),
+ data = Task.sequence(tasks.value)(),
log = Task.ctx().log,
- workspace = Task.workspace,
+ workspace = BuildCtx.workspaceRoot,
env = Task.env,
bundleName = bundleName
)
}
-def copyTo(task: mill.main.Tasks[PathRef], dest: String): Command[Unit] = Task.Command {
- val destPath = os.Path(dest, Task.workspace)
+def copyTo(task: Tasks[PathRef], dest: String): Command[Unit] = Task.Command {
+ val destPath = os.Path(dest, BuildCtx.workspaceRoot)
if (task.value.length > 1)
sys.error("Expected a single task")
val ref = task.value.head()
@@ -1334,7 +1368,7 @@ def copyTo(task: mill.main.Tasks[PathRef], dest: String): Command[Unit] = Task.C
}
def writePackageVersionTo(dest: String): Command[Unit] = Task.Command {
- val destPath = os.Path(dest, Task.workspace)
+ val destPath = os.Path(dest, BuildCtx.workspaceRoot)
val rawVersion = cli(Scala.defaultInternal).publishVersion()
val version =
if (rawVersion.contains("+")) rawVersion.stripSuffix("-SNAPSHOT")
@@ -1343,7 +1377,7 @@ def writePackageVersionTo(dest: String): Command[Unit] = Task.Command {
}
def writeShortPackageVersionTo(dest: String): Command[Unit] = Task.Command {
- val destPath = os.Path(dest, Task.workspace)
+ val destPath = os.Path(dest, BuildCtx.workspaceRoot)
val rawVersion = cli(Scala.defaultInternal).publishVersion()
val version = rawVersion.takeWhile(c => c != '-' && c != '+')
os.write.over(destPath, version)
@@ -1384,7 +1418,7 @@ def copyLauncher(directory: String = "artifacts"): Command[os.Path] = Task.Comma
directory = directory,
name = "scala-cli",
compress = true,
- workspace = Task.workspace
+ workspace = BuildCtx.workspaceRoot
)
}
@@ -1392,7 +1426,7 @@ def copyJvmLauncher(directory: String = "artifacts"): Command[Unit] = Task.Comma
val launcher = cli(Scala.defaultInternal).standaloneLauncher().path
os.copy(
launcher,
- os.Path(directory, Task.workspace) / s"scala-cli$platformExecutableJarExtension",
+ os.Path(directory, BuildCtx.workspaceRoot) / s"scala-cli$platformExecutableJarExtension",
createFolders = true,
replaceExisting = true
)
@@ -1401,7 +1435,7 @@ def copyJvmBootstrappedLauncher(directory: String = "artifacts"): Command[Unit]
val launcher = cliBootstrapped.jar().path
os.copy(
launcher,
- os.Path(directory, Task.workspace) / s"scala-cli.jar",
+ os.Path(directory, BuildCtx.workspaceRoot) / s"scala-cli.jar",
createFolders = true,
replaceExisting = true
)
@@ -1410,7 +1444,7 @@ def copyJvmBootstrappedLauncher(directory: String = "artifacts"): Command[Unit]
def uploadLaunchers(directory: String = "artifacts"): Command[Unit] = Task.Command {
val version = cli(Scala.defaultInternal).publishVersion()
- val path = os.Path(directory, Task.workspace)
+ val path = os.Path(directory, BuildCtx.workspaceRoot)
val launchers = os.list(path).filter(os.isFile(_)).map { path =>
path -> path.last
}
@@ -1419,16 +1453,16 @@ def uploadLaunchers(directory: String = "artifacts"): Command[Unit] = Task.Comma
else ("v" + version, false)
System.err.println(s"Uploading to tag $tag (overwrite assets: $overwriteAssets)")
Upload.upload(ghOrg, ghName, ghToken(), tag, dryRun = false, overwrite = overwriteAssets)(
- launchers: _*
+ launchers*
)
}
-def unitTests(): Command[(String, Seq[TestResult])] = Task.Command {
- `build-module`(Scala.defaultInternal).test.test()()
- `build-macros`(Scala.defaultInternal).test.test()()
- cli(Scala.defaultInternal).test.test()()
- directives(Scala.defaultInternal).test.test()()
- options(Scala.defaultInternal).test.test()()
+def unitTests(): Command[(msg: String, results: Seq[TestResult])] = Task.Command {
+ `build-module`(Scala.defaultInternal).test.testForked()()
+ `build-macros`(Scala.defaultInternal).test.testForked()()
+ cli(Scala.defaultInternal).test.testForked()()
+ directives(Scala.defaultInternal).test.testForked()()
+ options(Scala.defaultInternal).test.testForked()()
}
def scala(args: Task[Args] = Task.Anon(Args())) = Task.Command {
@@ -1444,10 +1478,8 @@ def defaultNativeImage(): Command[PathRef] =
cli(Scala.defaultInternal).nativeImage()
}
-def nativeIntegrationTests(): Command[(String, Seq[TestResult])] =
- Task.Command {
- integration.test.native()()
- }
+def nativeIntegrationTests(): Command[(msg: String, results: Seq[TestResult])] =
+ integration.test.native()
def copyDefaultLauncher(directory: String = "artifacts"): Command[os.Path] =
Task.Command {
@@ -1461,7 +1493,7 @@ def copyMostlyStaticLauncher(directory: String = "artifacts"): Command[os.Path]
directory = directory,
name = "scala-cli",
compress = true,
- workspace = Task.workspace,
+ workspace = BuildCtx.workspaceRoot,
suffix = "-mostly-static"
)
}
@@ -1473,7 +1505,7 @@ def copyStaticLauncher(directory: String = "artifacts"): Command[os.Path] = Task
directory = directory,
name = "scala-cli",
compress = true,
- workspace = Task.workspace,
+ workspace = BuildCtx.workspaceRoot,
suffix = "-static"
)
}
@@ -1516,7 +1548,7 @@ object ci extends Module {
def updateScalaCliSetup(): Command[Unit] = Task.Command {
val version = cli(Scala.defaultInternal).publishVersion()
- val targetDir = Task.workspace / "target-scala-cli-setup"
+ val targetDir = BuildCtx.workspaceRoot / "target-scala-cli-setup"
val mainDir = targetDir / "scala-cli-setup"
val setupScriptPath = mainDir / "src" / "main.ts"
@@ -1545,7 +1577,7 @@ object ci extends Module {
def updateStandaloneLauncher(): Command[os.CommandResult] = Task.Command {
val version = cli(Scala.defaultInternal).publishVersion()
- val targetDir = Task.workspace / "target"
+ val targetDir = BuildCtx.workspaceRoot / "target"
val scalaCliDir = targetDir / "scala-cli"
val standaloneLauncherPath = scalaCliDir / "scala-cli.sh"
val standaloneWindowsLauncherPath = scalaCliDir / "scala-cli.bat"
@@ -1614,7 +1646,7 @@ object ci extends Module {
def updateScalaCliBrewFormula(): Command[Unit] = Task.Command {
val version = cli(Scala.defaultInternal).publishVersion()
- val targetDir = Task.workspace / "target"
+ val targetDir = BuildCtx.workspaceRoot / "target"
val homebrewFormulaDir = targetDir / "homebrew-scala-cli"
// clean target directory
@@ -1634,13 +1666,15 @@ object ci extends Module {
val arm64LauncherURL =
s"https://github.com/Virtuslab/scala-cli/releases/download/v$version/scala-cli-aarch64-apple-darwin.gz"
- val x86LauncherPath = os.Path("artifacts", Task.workspace) / "scala-cli-x86_64-apple-darwin.gz"
+ val x86LauncherPath =
+ os.Path("artifacts", BuildCtx.workspaceRoot) / "scala-cli-x86_64-apple-darwin.gz"
val arm64LauncherPath =
- os.Path("artifacts", Task.workspace) / "scala-cli-aarch64-apple-darwin.gz"
+ os.Path("artifacts", BuildCtx.workspaceRoot) / "scala-cli-aarch64-apple-darwin.gz"
val (x86Sha256, arm64Sha256) = brewLaunchersSha(x86LauncherPath, arm64LauncherPath, targetDir)
- val templateFormulaPath = Task.workspace / ".github" / "scripts" / "scala-cli.rb.template"
- val template = os.read(templateFormulaPath)
+ val templateFormulaPath =
+ BuildCtx.workspaceRoot / ".github" / "scripts" / "scala-cli.rb.template"
+ val template = os.read(templateFormulaPath)
val updatedFormula = template
.replace("@X86_LAUNCHER_URL@", x86LauncherURL)
@@ -1657,7 +1691,7 @@ object ci extends Module {
def updateScalaExperimentalBrewFormula(): Command[Unit] = Task.Command {
val version = cli(Scala.defaultInternal).publishVersion()
- val targetDir = Task.workspace / "target"
+ val targetDir = BuildCtx.workspaceRoot / "target"
val homebrewFormulaDir = targetDir / "homebrew-scala-experimental"
// clean homebrew-scala-experimental directory
@@ -1677,12 +1711,13 @@ object ci extends Module {
val arm64LauncherURL =
s"https://github.com/Virtuslab/scala-cli/releases/download/v$version/scala-cli-aarch64-apple-darwin.gz"
- val x86LauncherPath = os.Path("artifacts", Task.workspace) / "scala-cli-x86_64-apple-darwin.gz"
+ val x86LauncherPath =
+ os.Path("artifacts", BuildCtx.workspaceRoot) / "scala-cli-x86_64-apple-darwin.gz"
val arm64LauncherPath =
- os.Path("artifacts", Task.workspace) / "scala-cli-aarch64-apple-darwin.gz"
+ os.Path("artifacts", BuildCtx.workspaceRoot) / "scala-cli-aarch64-apple-darwin.gz"
val (x86Sha256, arm64Sha256) = brewLaunchersSha(x86LauncherPath, arm64LauncherPath, targetDir)
- val templateFormulaPath = Task.workspace / ".github" / "scripts" / "scala.rb.template"
+ val templateFormulaPath = BuildCtx.workspaceRoot / ".github" / "scripts" / "scala.rb.template"
val template = os.read(templateFormulaPath)
val updatedFormula = template
@@ -1700,7 +1735,7 @@ object ci extends Module {
def updateInstallationScript(): Command[Unit] = Task.Command {
val version = cli(Scala.defaultInternal).publishVersion()
- val targetDir = Task.workspace / "target"
+ val targetDir = BuildCtx.workspaceRoot / "target"
val packagesDir = targetDir / "scala-cli-packages"
val installationScriptPath = packagesDir / "scala-setup.sh"
@@ -1727,7 +1762,7 @@ object ci extends Module {
def updateDebianPackages(): Command[Unit] = Task.Command {
val version = cli(Scala.defaultInternal).publishVersion()
- val targetDir = Task.workspace / "target"
+ val targetDir = BuildCtx.workspaceRoot / "target"
val packagesDir = targetDir / "scala-cli-packages"
val debianDir = packagesDir / "debian"
@@ -1745,7 +1780,7 @@ object ci extends Module {
// copy deb package to repository
os.copy(
- os.Path("artifacts", Task.workspace) / "scala-cli-x86_64-pc-linux.deb",
+ os.Path("artifacts", BuildCtx.workspaceRoot) / "scala-cli-x86_64-pc-linux.deb",
debianDir / s"scala-cli_$version.deb"
)
@@ -1795,12 +1830,12 @@ object ci extends Module {
def updateChocolateyPackage(): Command[os.CommandResult] = Task.Command {
val version = cli(Scala.defaultInternal).publishVersion()
- val packagesDir = Task.workspace / "target" / "scala-cli-packages"
- val chocoDir = Task.workspace / ".github" / "scripts" / "choco"
+ val packagesDir = BuildCtx.workspaceRoot / "target" / "scala-cli-packages"
+ val chocoDir = BuildCtx.workspaceRoot / ".github" / "scripts" / "choco"
val msiPackagePath = packagesDir / s"scala-cli_$version.msi"
os.copy(
- Task.workspace / "artifacts" / "scala-cli-x86_64-pc-win32.msi",
+ BuildCtx.workspaceRoot / "artifacts" / "scala-cli-x86_64-pc-win32.msi",
msiPackagePath,
createFolders = true
)
@@ -1839,7 +1874,7 @@ object ci extends Module {
def updateCentOsPackages(): Command[Unit] = Task.Command {
val version = cli(Scala.defaultInternal).publishVersion()
- val targetDir = Task.workspace / "target"
+ val targetDir = BuildCtx.workspaceRoot / "target"
val packagesDir = targetDir / "scala-cli-packages"
val centOsDir = packagesDir / "CentOS"
@@ -1857,7 +1892,7 @@ object ci extends Module {
// copy rpm package to repository
os.copy(
- os.Path("artifacts", Task.workspace) / "scala-cli-x86_64-pc-linux.rpm",
+ os.Path("artifacts", BuildCtx.workspaceRoot) / "scala-cli-x86_64-pc-linux.rpm",
centOsDir / "Packages" / s"scala-cli_$version.rpm"
)
@@ -1928,7 +1963,7 @@ object ci extends Module {
.mkString(System.lineSeparator())
)
}
- val destDir = os.Path(directory, Task.workspace)
+ val destDir = os.Path(directory, BuildCtx.workspaceRoot)
os.copy(orig, destDir / distName, createFolders = true, replaceExisting = true)
}
def writeWixConfigExtra(dest: String = "wix-visual-cpp-redist.xml"): Command[Unit] =
@@ -1972,7 +2007,7 @@ object ci extends Module {
|
|
|""".stripMargin
- val dest0 = os.Path(dest, Task.workspace)
+ val dest0 = os.Path(dest, BuildCtx.workspaceRoot)
os.write.over(dest0, content.getBytes(Charset.defaultCharset()), createFolders = true)
}
def setShouldPublish(): Command[Unit] = publish.setShouldPublish()
@@ -1991,9 +2026,9 @@ object ci extends Module {
"--ttl",
"0"
)
- val baseJavaHome = os.Path(command.!!.trim, Task.workspace)
+ val baseJavaHome = os.Path(command.!!.trim, BuildCtx.workspaceRoot)
System.err.println(s"Initial Java home $baseJavaHome")
- val destJavaHome = os.Path(dest, Task.workspace)
+ val destJavaHome = os.Path(dest, BuildCtx.workspaceRoot)
os.copy(baseJavaHome, destJavaHome, createFolders = true)
System.err.println(s"New Java home $destJavaHome")
destJavaHome
@@ -2001,10 +2036,10 @@ object ci extends Module {
def checkScalaVersions(): Command[Unit] = Task.Command {
website.checkMainScalaVersions(
- Task.workspace / "website" / "docs" / "reference" / "scala-versions.md"
+ BuildCtx.workspaceRoot / "website" / "docs" / "reference" / "scala-versions.md"
)
website.checkScalaJsVersions(
- Task.workspace / "website" / "docs" / "guides" / "advanced" / "scala-js.md"
+ BuildCtx.workspaceRoot / "website" / "docs" / "guides" / "advanced" / "scala-js.md"
)
}
}
diff --git a/mill b/mill
index edc610a8f8..1c03f803e2 100755
--- a/mill
+++ b/mill
@@ -84,7 +84,7 @@ export USE_NATIVE_IMAGE_JAVA_PLATFORM_MODULE_SYSTEM=false
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &> /dev/null && pwd)"
if [[ $IS_WINDOWS ]]; then
- exec "$DIR/millw" "$@"
+ exec "$DIR/mill.bat" "$@"
else
exec "$DIR/millw" $COMMAND
fi
diff --git a/mill.bat b/mill.bat
index 7f99598658..f4e4b58e04 100755
--- a/mill.bat
+++ b/mill.bat
@@ -1,40 +1,8 @@
@echo off
-rem This is a wrapper script, that automatically selects or downloads Mill from Maven Central or GitHub release pages.
-rem
-rem This script determines the Mill version to use by trying these sources
-rem - env-variable `MILL_VERSION`
-rem - local file `.mill-version`
-rem - local file `.config/mill-version`
-rem - `mill-version` from YAML frontmatter of current buildfile
-rem - if accessible, find the latest stable version available on Maven Central (https://repo1.maven.org/maven2)
-rem - env-variable `DEFAULT_MILL_VERSION`
-rem
-rem If a version has the suffix '-native' a native binary will be used.
-rem If a version has the suffix '-jvm' an executable jar file will be used, requiring an already installed Java runtime.
-rem If no such suffix is found, the script will pick a default based on version and platform.
-rem
-rem Once a version was determined, it tries to use either
-rem - a system-installed mill, if found and it's version matches
-rem - an already downloaded version under %USERPROFILE%\.mill\download
-rem
-rem If no working mill version was found on the system,
-rem this script downloads a binary file from Maven Central or Github Pages (this is version dependent)
-rem into a cache location (%USERPROFILE%\.mill\download).
-rem
-rem Mill Project URL: https://github.com/com-lihaoyi/mill
-rem Script Version: 1.0.5
-rem
-rem If you want to improve this script, please also contribute your changes back!
-rem This script was generated from: dist/scripts/src/mill.bat
-rem
-rem Licensed under the Apache License, Version 2.0
-
-rem setlocal seems to be unavailable on Windows 95/98/ME
-rem but I don't think we need to support them in 2019
setlocal enabledelayedexpansion
-if [!DEFAULT_MILL_VERSION!]==[] ( set "DEFAULT_MILL_VERSION=0.12.16" )
+if [!DEFAULT_MILL_VERSION!]==[] ( set "DEFAULT_MILL_VERSION=1.0.6" )
if [!MILL_GITHUB_RELEASE_CDN!]==[] ( set "MILL_GITHUB_RELEASE_CDN=" )
@@ -65,9 +33,24 @@ if [!MILL_VERSION!]==[] (
if exist .config\mill-version (
set /p MILL_VERSION=<.config\mill-version
) else (
- if not "%MILL_BUILD_SCRIPT%"=="" (
+ rem Determine which config file to use for version extraction
+ set "MILL_VERSION_CONFIG_FILE="
+ set "MILL_VERSION_SEARCH_PATTERN="
+
+ if exist build.mill.yaml (
+ set "MILL_VERSION_CONFIG_FILE=build.mill.yaml"
+ set "MILL_VERSION_SEARCH_PATTERN=mill-version:"
+ ) else (
+ if not "%MILL_BUILD_SCRIPT%"=="" (
+ set "MILL_VERSION_CONFIG_FILE=%MILL_BUILD_SCRIPT%"
+ set "MILL_VERSION_SEARCH_PATTERN=//\|.*mill-version"
+ )
+ )
+
+ rem Process the config file if found
+ if not "!MILL_VERSION_CONFIG_FILE!"=="" (
rem Find the line and process it
- for /f "tokens=*" %%a in ('findstr /R /C:"//\|.*mill-version" "%MILL_BUILD_SCRIPT%"') do (
+ for /f "tokens=*" %%a in ('findstr /R /C:"!MILL_VERSION_SEARCH_PATTERN!" "!MILL_VERSION_CONFIG_FILE!"') do (
set "line=%%a"
rem --- 1. Replicate sed 's/.*://' ---
@@ -85,7 +68,7 @@ if [!MILL_VERSION!]==[] (
set "line=!line:'=!"
set "line=!line:"=!"
- rem --- 4. NEW: Replicate sed's trim/space removal ---
+ rem --- 4. Replicate sed's trim/space removal ---
rem Remove all space characters from the result. This is more robust.
set "MILL_VERSION=!line: =!"
@@ -95,27 +78,23 @@ if [!MILL_VERSION!]==[] (
:version_found
rem no-op
- ) else (
- rem no-op
)
)
)
)
if [!MILL_VERSION!]==[] (
- echo No mill version specified. >&2
- echo You should provide a version via a '//^| mill-version: ' comment or a '.mill-version' file. >&2
set MILL_VERSION=%DEFAULT_MILL_VERSION%
)
-if [!MILL_DOWNLOAD_PATH!]==[] set MILL_DOWNLOAD_PATH=%USERPROFILE%\.mill\download
+if [!MILL_FINAL_DOWNLOAD_FOLDER!]==[] set MILL_FINAL_DOWNLOAD_FOLDER=%USERPROFILE%\.cache\mill\download
rem without bat file extension, cmd doesn't seem to be able to run it
set "MILL_NATIVE_SUFFIX=-native"
set "MILL_JVM_SUFFIX=-jvm"
-set "FULL_MILL_VERSION=%MILL_VERSION%"
-set "MILL_EXT=.bat"
+set "MILL_FULL_VERSION=%MILL_VERSION%"
+set "MILL_DOWNLOAD_EXT=.bat"
set "ARTIFACT_SUFFIX="
REM Check if MILL_VERSION contains MILL_NATIVE_SUFFIX
echo !MILL_VERSION! | findstr /C:"%MILL_NATIVE_SUFFIX%" >nul
@@ -125,7 +104,7 @@ if !errorlevel! equ 0 (
REM https://github.com/oracle/graal/issues/9215
IF /I NOT "%PROCESSOR_ARCHITECTURE%"=="ARM64" (
set "ARTIFACT_SUFFIX=-native-windows-amd64"
- set "MILL_EXT=.exe"
+ set "MILL_DOWNLOAD_EXT=.exe"
) else (
rem no-op
)
@@ -153,7 +132,7 @@ if !errorlevel! equ 0 (
if "!SKIP_VERSION!"=="false" (
IF /I NOT "%PROCESSOR_ARCHITECTURE%"=="ARM64" (
set "ARTIFACT_SUFFIX=-native-windows-amd64"
- set "MILL_EXT=.exe"
+ set "MILL_DOWNLOAD_EXT=.exe"
)
) else (
rem no-op
@@ -161,7 +140,7 @@ if !errorlevel! equ 0 (
)
)
-set MILL=%MILL_DOWNLOAD_PATH%\!FULL_MILL_VERSION!!MILL_EXT!
+set MILL=%MILL_FINAL_DOWNLOAD_FOLDER%\!MILL_FULL_VERSION!!MILL_DOWNLOAD_EXT!
set MILL_RESOLVE_DOWNLOAD=
@@ -257,34 +236,26 @@ if [!MILL_RESOLVE_DOWNLOAD!]==[true] (
)
rem there seems to be no way to generate a unique temporary file path (on native Windows)
- set MILL_DOWNLOAD_FILE=%MILL%.tmp
+ if defined MILL_OUTPUT_DIR (
+ set MILL_TEMP_DOWNLOAD_FILE=%MILL_OUTPUT_DIR%\mill-temp-download
+ if not exist "%MILL_OUTPUT_DIR%" mkdir "%MILL_OUTPUT_DIR%"
+ ) else (
+ set MILL_TEMP_DOWNLOAD_FILE=out\mill-bootstrap-download
+ if not exist "out" mkdir "out"
+ )
echo Downloading mill !MILL_VERSION! from !MILL_DOWNLOAD_URL! ... 1>&2
- if not exist "%MILL_DOWNLOAD_PATH%" mkdir "%MILL_DOWNLOAD_PATH%"
- rem curl is bundled with recent Windows 10
- rem but I don't think we can expect all the users to have it in 2019
- where /Q curl
- if !ERRORLEVEL! EQU 0 (
- curl -f -L "!MILL_DOWNLOAD_URL!" -o "!MILL_DOWNLOAD_FILE!"
- ) else (
- rem bitsadmin seems to be available on Windows 7
- rem without /dynamic, github returns 403
- rem bitsadmin is sometimes needlessly slow but it looks better with /priority foreground
- bitsadmin /transfer millDownloadJob /dynamic /priority foreground "!MILL_DOWNLOAD_URL!" "!MILL_DOWNLOAD_FILE!"
- )
- if not exist "!MILL_DOWNLOAD_FILE!" (
- echo Could not download mill !MILL_VERSION! 1>&2
- exit /b 1
- )
+ curl -f -L "!MILL_DOWNLOAD_URL!" -o "!MILL_TEMP_DOWNLOAD_FILE!"
- move /y "!MILL_DOWNLOAD_FILE!" "%MILL%"
+ if not exist "%MILL_FINAL_DOWNLOAD_FOLDER%" mkdir "%MILL_FINAL_DOWNLOAD_FOLDER%"
+ move /y "!MILL_TEMP_DOWNLOAD_FILE!" "%MILL%"
- set MILL_DOWNLOAD_FILE=
+ set MILL_TEMP_DOWNLOAD_FILE=
set MILL_DOWNLOAD_SUFFIX=
)
-set MILL_DOWNLOAD_PATH=
+set MILL_FINAL_DOWNLOAD_FOLDER=
set MILL_VERSION=
set MILL_REPO_URL=
diff --git a/millw b/millw
index 97db4e237e..1062824b51 100755
--- a/millw
+++ b/millw
@@ -1,58 +1,15 @@
#!/usr/bin/env sh
-# This is a wrapper script, that automatically selects or downloads Mill from Maven Central or GitHub release pages.
-#
-# This script determines the Mill version to use by trying these sources
-# - env-variable `MILL_VERSION`
-# - local file `.mill-version`
-# - local file `.config/mill-version`
-# - `mill-version` from YAML frontmatter of current buildfile
-# - if accessible, find the latest stable version available on Maven Central (https://repo1.maven.org/maven2)
-# - env-variable `DEFAULT_MILL_VERSION`
-#
-# If a version has the suffix '-native' a native binary will be used.
-# If a version has the suffix '-jvm' an executable jar file will be used, requiring an already installed Java runtime.
-# If no such suffix is found, the script will pick a default based on version and platform.
-#
-# Once a version was determined, it tries to use either
-# - a system-installed mill, if found and it's version matches
-# - an already downloaded version under ~/.cache/mill/download
-#
-# If no working mill version was found on the system,
-# this script downloads a binary file from Maven Central or Github Pages (this is version dependent)
-# into a cache location (~/.cache/mill/download).
-#
-# Mill Project URL: https://github.com/com-lihaoyi/mill
-# Script Version: 1.0.5
-#
-# If you want to improve this script, please also contribute your changes back!
-# This script was generated from: dist/scripts/src/mill.sh
-#
-# Licensed under the Apache License, Version 2.0
-
set -e
-if [ -z "${DEFAULT_MILL_VERSION}" ] ; then
- DEFAULT_MILL_VERSION="0.12.16"
-fi
-
+if [ -z "${DEFAULT_MILL_VERSION}" ] ; then DEFAULT_MILL_VERSION="1.0.6"; fi
-if [ -z "${GITHUB_RELEASE_CDN}" ] ; then
- GITHUB_RELEASE_CDN=""
-fi
+if [ -z "${GITHUB_RELEASE_CDN}" ] ; then GITHUB_RELEASE_CDN=""; fi
+if [ -z "$MILL_MAIN_CLI" ] ; then MILL_MAIN_CLI="${0}"; fi
MILL_REPO_URL="https://github.com/com-lihaoyi/mill"
-if [ -z "${CURL_CMD}" ] ; then
- CURL_CMD=curl
-fi
-
-# Explicit commandline argument takes precedence over all other methods
-if [ "$1" = "--mill-version" ] ; then
- echo "The --mill-version option is no longer supported." 1>&2
-fi
-
MILL_BUILD_SCRIPT=""
if [ -f "build.mill" ] ; then
@@ -63,77 +20,37 @@ elif [ -f "build.sc" ] ; then
MILL_BUILD_SCRIPT="build.sc"
fi
-# Please note, that if a MILL_VERSION is already set in the environment,
-# We reuse it's value and skip searching for a value.
+# `s/.*://`:
+# This is a greedy match that removes everything from the beginning of the line up to (and including) the last
+# colon (:). This effectively isolates the value part of the declaration.
+#
+# `s/#.*//`:
+# This removes any comments at the end of the line.
+#
+# `s/['\"]//g`:
+# This removes all single and double quotes from the string, wherever they appear (g is for "global").
+#
+# `s/^[[:space:]]*//; s/[[:space:]]*$//`:
+# These two expressions trim any leading or trailing whitespace ([[:space:]] matches spaces and tabs).
+TRIM_VALUE_SED="s/.*://; s/#.*//; s/['\"]//g; s/^[[:space:]]*//; s/[[:space:]]*$//"
-# If not already set, read .mill-version file
if [ -z "${MILL_VERSION}" ] ; then
if [ -f ".mill-version" ] ; then
MILL_VERSION="$(tr '\r' '\n' < .mill-version | head -n 1 2> /dev/null)"
elif [ -f ".config/mill-version" ] ; then
MILL_VERSION="$(tr '\r' '\n' < .config/mill-version | head -n 1 2> /dev/null)"
+ elif [ -f "build.mill.yaml" ] ; then
+ MILL_VERSION="$(grep -E "mill-version:" "build.mill.yaml" | sed -E "$TRIM_VALUE_SED")"
elif [ -n "${MILL_BUILD_SCRIPT}" ] ; then
- # `s/.*://`:
- # This is a greedy match that removes everything from the beginning of the line up to (and including) the last
- # colon (:). This effectively isolates the value part of the declaration.
- #
- # `s/#.*//`:
- # This removes any comments at the end of the line.
- #
- # `s/['\"]//g`:
- # This removes all single and double quotes from the string, wherever they appear (g is for "global").
- #
- # `s/^[[:space:]]*//; s/[[:space:]]*$//`:
- # These two expressions trim any leading or trailing whitespace ([[:space:]] matches spaces and tabs).
- MILL_VERSION="$(grep -E "//\|.*mill-version" "${MILL_BUILD_SCRIPT}" | sed -E "s/.*://; s/#.*//; s/['\"]//g; s/^[[:space:]]*//; s/[[:space:]]*$//")"
+ MILL_VERSION="$(grep -E "//\|.*mill-version" "${MILL_BUILD_SCRIPT}" | sed -E "$TRIM_VALUE_SED")"
fi
fi
-MILL_USER_CACHE_DIR="${XDG_CACHE_HOME:-${HOME}/.cache}/mill"
-
-if [ -z "${MILL_DOWNLOAD_PATH}" ] ; then
- MILL_DOWNLOAD_PATH="${MILL_USER_CACHE_DIR}/download"
-fi
-
-# If not already set, try to fetch newest from Github
-if [ -z "${MILL_VERSION}" ] ; then
- # TODO: try to load latest version from release page
- echo "No mill version specified." 1>&2
- echo "You should provide a version via a '//| mill-version: ' comment or a '.mill-version' file." 1>&2
-
- mkdir -p "${MILL_DOWNLOAD_PATH}"
- LANG=C touch -d '1 hour ago' "${MILL_DOWNLOAD_PATH}/.expire_latest" 2>/dev/null || (
- # we might be on OSX or BSD which don't have -d option for touch
- # but probably a -A [-][[hh]mm]SS
- touch "${MILL_DOWNLOAD_PATH}/.expire_latest"; touch -A -010000 "${MILL_DOWNLOAD_PATH}/.expire_latest"
- ) || (
- # in case we still failed, we retry the first touch command with the intention
- # to show the (previously suppressed) error message
- LANG=C touch -d '1 hour ago' "${MILL_DOWNLOAD_PATH}/.expire_latest"
- )
+if [ -z "${MILL_VERSION}" ] ; then MILL_VERSION="${DEFAULT_MILL_VERSION}"; fi
- # POSIX shell variant of bash's -nt operator, see https://unix.stackexchange.com/a/449744/6993
- # if [ "${MILL_DOWNLOAD_PATH}/.latest" -nt "${MILL_DOWNLOAD_PATH}/.expire_latest" ] ; then
- if [ -n "$(find -L "${MILL_DOWNLOAD_PATH}/.latest" -prune -newer "${MILL_DOWNLOAD_PATH}/.expire_latest")" ]; then
- # we know a current latest version
- MILL_VERSION=$(head -n 1 "${MILL_DOWNLOAD_PATH}"/.latest 2> /dev/null)
- fi
+MILL_USER_CACHE_DIR="${XDG_CACHE_HOME:-${HOME}/.cache}/mill"
- if [ -z "${MILL_VERSION}" ] ; then
- # we don't know a current latest version
- echo "Retrieving latest mill version ..." 1>&2
- LANG=C ${CURL_CMD} -s -i -f -I ${MILL_REPO_URL}/releases/latest 2> /dev/null | grep --ignore-case Location: | sed s'/^.*tag\///' | tr -d '\r\n' > "${MILL_DOWNLOAD_PATH}/.latest"
- MILL_VERSION=$(head -n 1 "${MILL_DOWNLOAD_PATH}"/.latest 2> /dev/null)
- fi
-
- if [ -z "${MILL_VERSION}" ] ; then
- # Last resort
- MILL_VERSION="${DEFAULT_MILL_VERSION}"
- echo "Falling back to hardcoded mill version ${MILL_VERSION}" 1>&2
- else
- echo "Using mill version ${MILL_VERSION}" 1>&2
- fi
-fi
+if [ -z "${MILL_FINAL_DOWNLOAD_FOLDER}" ] ; then MILL_FINAL_DOWNLOAD_FOLDER="${MILL_USER_CACHE_DIR}/download"; fi
MILL_NATIVE_SUFFIX="-native"
MILL_JVM_SUFFIX="-jvm"
@@ -141,17 +58,11 @@ FULL_MILL_VERSION=$MILL_VERSION
ARTIFACT_SUFFIX=""
set_artifact_suffix(){
if [ "$(expr substr $(uname -s) 1 5 2>/dev/null)" = "Linux" ]; then
- if [ "$(uname -m)" = "aarch64" ]; then
- ARTIFACT_SUFFIX="-native-linux-aarch64"
- else
- ARTIFACT_SUFFIX="-native-linux-amd64"
- fi
+ if [ "$(uname -m)" = "aarch64" ]; then ARTIFACT_SUFFIX="-native-linux-aarch64"
+ else ARTIFACT_SUFFIX="-native-linux-amd64"; fi
elif [ "$(uname)" = "Darwin" ]; then
- if [ "$(uname -m)" = "arm64" ]; then
- ARTIFACT_SUFFIX="-native-mac-aarch64"
- else
- ARTIFACT_SUFFIX="-native-mac-amd64"
- fi
+ if [ "$(uname -m)" = "arm64" ]; then ARTIFACT_SUFFIX="-native-mac-aarch64"
+ else ARTIFACT_SUFFIX="-native-mac-amd64"; fi
else
echo "This native mill launcher supports only Linux and macOS." 1>&2
exit 1
@@ -188,136 +99,67 @@ case "$MILL_VERSION" in
;;
esac
-MILL="${MILL_DOWNLOAD_PATH}/$MILL_VERSION$ARTIFACT_SUFFIX"
-
-try_to_use_system_mill() {
- if [ "$(uname)" != "Linux" ]; then
- return 0
- fi
-
- MILL_IN_PATH="$(command -v mill || true)"
-
- if [ -z "${MILL_IN_PATH}" ]; then
- return 0
- fi
-
- SYSTEM_MILL_FIRST_TWO_BYTES=$(head --bytes=2 "${MILL_IN_PATH}")
- if [ "${SYSTEM_MILL_FIRST_TWO_BYTES}" = "#!" ]; then
- # MILL_IN_PATH is (very likely) a shell script and not the mill
- # executable, ignore it.
- return 0
- fi
-
- SYSTEM_MILL_PATH=$(readlink -e "${MILL_IN_PATH}")
- SYSTEM_MILL_SIZE=$(stat --format=%s "${SYSTEM_MILL_PATH}")
- SYSTEM_MILL_MTIME=$(stat --format=%y "${SYSTEM_MILL_PATH}")
-
- if [ ! -d "${MILL_USER_CACHE_DIR}" ]; then
- mkdir -p "${MILL_USER_CACHE_DIR}"
- fi
-
- SYSTEM_MILL_INFO_FILE="${MILL_USER_CACHE_DIR}/system-mill-info"
- if [ -f "${SYSTEM_MILL_INFO_FILE}" ]; then
- parseSystemMillInfo() {
- LINE_NUMBER="${1}"
- # Select the line number of the SYSTEM_MILL_INFO_FILE, cut the
- # variable definition in that line in two halves and return
- # the value, and finally remove the quotes.
- sed -n "${LINE_NUMBER}p" "${SYSTEM_MILL_INFO_FILE}" |\
- cut -d= -f2 |\
- sed 's/"\(.*\)"/\1/'
- }
-
- CACHED_SYSTEM_MILL_PATH=$(parseSystemMillInfo 1)
- CACHED_SYSTEM_MILL_VERSION=$(parseSystemMillInfo 2)
- CACHED_SYSTEM_MILL_SIZE=$(parseSystemMillInfo 3)
- CACHED_SYSTEM_MILL_MTIME=$(parseSystemMillInfo 4)
-
- if [ "${SYSTEM_MILL_PATH}" = "${CACHED_SYSTEM_MILL_PATH}" ] \
- && [ "${SYSTEM_MILL_SIZE}" = "${CACHED_SYSTEM_MILL_SIZE}" ] \
- && [ "${SYSTEM_MILL_MTIME}" = "${CACHED_SYSTEM_MILL_MTIME}" ]; then
- if [ "${CACHED_SYSTEM_MILL_VERSION}" = "${MILL_VERSION}" ]; then
- MILL="${SYSTEM_MILL_PATH}"
- return 0
- else
- return 0
- fi
- fi
- fi
-
- SYSTEM_MILL_VERSION=$(${SYSTEM_MILL_PATH} --version | head -n1 | sed -n 's/^Mill.*version \(.*\)/\1/p')
-
- cat < "${SYSTEM_MILL_INFO_FILE}"
-CACHED_SYSTEM_MILL_PATH="${SYSTEM_MILL_PATH}"
-CACHED_SYSTEM_MILL_VERSION="${SYSTEM_MILL_VERSION}"
-CACHED_SYSTEM_MILL_SIZE="${SYSTEM_MILL_SIZE}"
-CACHED_SYSTEM_MILL_MTIME="${SYSTEM_MILL_MTIME}"
-EOF
-
- if [ "${SYSTEM_MILL_VERSION}" = "${MILL_VERSION}" ]; then
- MILL="${SYSTEM_MILL_PATH}"
- fi
-}
-try_to_use_system_mill
+MILL="${MILL_FINAL_DOWNLOAD_FOLDER}/$MILL_VERSION$ARTIFACT_SUFFIX"
# If not already downloaded, download it
if [ ! -s "${MILL}" ] || [ "$MILL_TEST_DRY_RUN_LAUNCHER_SCRIPT" = "1" ] ; then
case $MILL_VERSION in
0.0.* | 0.1.* | 0.2.* | 0.3.* | 0.4.* )
- DOWNLOAD_SUFFIX=""
- DOWNLOAD_FROM_MAVEN=0
+ MILL_DOWNLOAD_SUFFIX=""
+ MILL_DOWNLOAD_FROM_MAVEN=0
;;
0.5.* | 0.6.* | 0.7.* | 0.8.* | 0.9.* | 0.10.* | 0.11.0-M* )
- DOWNLOAD_SUFFIX="-assembly"
- DOWNLOAD_FROM_MAVEN=0
+ MILL_DOWNLOAD_SUFFIX="-assembly"
+ MILL_DOWNLOAD_FROM_MAVEN=0
;;
*)
- DOWNLOAD_SUFFIX="-assembly"
- DOWNLOAD_FROM_MAVEN=1
+ MILL_DOWNLOAD_SUFFIX="-assembly"
+ MILL_DOWNLOAD_FROM_MAVEN=1
;;
esac
case $MILL_VERSION in
0.12.0 | 0.12.1 | 0.12.2 | 0.12.3 | 0.12.4 | 0.12.5 | 0.12.6 | 0.12.7 | 0.12.8 | 0.12.9 | 0.12.10 | 0.12.11 )
- DOWNLOAD_EXT="jar"
+ MILL_DOWNLOAD_EXT="jar"
;;
0.12.* )
- DOWNLOAD_EXT="exe"
+ MILL_DOWNLOAD_EXT="exe"
;;
0.* )
- DOWNLOAD_EXT="jar"
+ MILL_DOWNLOAD_EXT="jar"
;;
*)
- DOWNLOAD_EXT="exe"
+ MILL_DOWNLOAD_EXT="exe"
;;
esac
- DOWNLOAD_FILE=$(mktemp mill.XXXXXX)
- if [ "$DOWNLOAD_FROM_MAVEN" = "1" ] ; then
- DOWNLOAD_URL="https://repo1.maven.org/maven2/com/lihaoyi/mill-dist${ARTIFACT_SUFFIX}/${MILL_VERSION}/mill-dist${ARTIFACT_SUFFIX}-${MILL_VERSION}.${DOWNLOAD_EXT}"
+ MILL_TEMP_DOWNLOAD_FILE="${MILL_OUTPUT_DIR:-out}/mill-temp-download"
+ mkdir -p "$(dirname "${MILL_TEMP_DOWNLOAD_FILE}")"
+
+ if [ "$MILL_DOWNLOAD_FROM_MAVEN" = "1" ] ; then
+ MILL_DOWNLOAD_URL="https://repo1.maven.org/maven2/com/lihaoyi/mill-dist${ARTIFACT_SUFFIX}/${MILL_VERSION}/mill-dist${ARTIFACT_SUFFIX}-${MILL_VERSION}.${MILL_DOWNLOAD_EXT}"
else
MILL_VERSION_TAG=$(echo "$MILL_VERSION" | sed -E 's/([^-]+)(-M[0-9]+)?(-.*)?/\1\2/')
- DOWNLOAD_URL="${GITHUB_RELEASE_CDN}${MILL_REPO_URL}/releases/download/${MILL_VERSION_TAG}/${MILL_VERSION}${DOWNLOAD_SUFFIX}"
+ MILL_DOWNLOAD_URL="${GITHUB_RELEASE_CDN}${MILL_REPO_URL}/releases/download/${MILL_VERSION_TAG}/${MILL_VERSION}${MILL_DOWNLOAD_SUFFIX}"
unset MILL_VERSION_TAG
fi
+
if [ "$MILL_TEST_DRY_RUN_LAUNCHER_SCRIPT" = "1" ] ; then
- echo $DOWNLOAD_URL
+ echo $MILL_DOWNLOAD_URL
echo $MILL
exit 0
fi
- # TODO: handle command not found
- echo "Downloading mill ${MILL_VERSION} from ${DOWNLOAD_URL} ..." 1>&2
- ${CURL_CMD} -f -L -o "${DOWNLOAD_FILE}" "${DOWNLOAD_URL}"
- chmod +x "${DOWNLOAD_FILE}"
- mkdir -p "${MILL_DOWNLOAD_PATH}"
- mv "${DOWNLOAD_FILE}" "${MILL}"
- unset DOWNLOAD_FILE
- unset DOWNLOAD_SUFFIX
-fi
+ echo "Downloading mill ${MILL_VERSION} from ${MILL_DOWNLOAD_URL} ..." 1>&2
+ curl -f -L -o "${MILL_TEMP_DOWNLOAD_FILE}" "${MILL_DOWNLOAD_URL}"
+
+ chmod +x "${MILL_TEMP_DOWNLOAD_FILE}"
+
+ mkdir -p "${MILL_FINAL_DOWNLOAD_FOLDER}"
+ mv "${MILL_TEMP_DOWNLOAD_FILE}" "${MILL}"
-if [ -z "$MILL_MAIN_CLI" ] ; then
- MILL_MAIN_CLI="${0}"
+ unset MILL_TEMP_DOWNLOAD_FILE
+ unset MILL_DOWNLOAD_SUFFIX
fi
MILL_FIRST_ARG=""
@@ -327,7 +169,7 @@ if [ "$1" = "--bsp" ] || [ "${1#"-i"}" != "$1" ] || [ "$1" = "--interactive" ] |
shift
fi
-unset MILL_DOWNLOAD_PATH
+unset MILL_FINAL_DOWNLOAD_FOLDER
unset MILL_OLD_DOWNLOAD_PATH
unset OLD_MILL
unset MILL_VERSION
diff --git a/modules/integration/src/test/scala/scala/cli/integration/ScalaCliSuite.scala b/modules/integration/src/test/scala/scala/cli/integration/ScalaCliSuite.scala
index 45da79c1a5..83c676ebab 100644
--- a/modules/integration/src/test/scala/scala/cli/integration/ScalaCliSuite.scala
+++ b/modules/integration/src/test/scala/scala/cli/integration/ScalaCliSuite.scala
@@ -3,7 +3,6 @@ package scala.cli.integration
import java.util.concurrent.TimeUnit
import scala.concurrent.duration.{Duration, FiniteDuration}
-import scala.util.Properties
abstract class ScalaCliSuite extends munit.FunSuite {
implicit class BeforeEachOpts(munitContext: BeforeEach) {
@@ -33,8 +32,11 @@ abstract class ScalaCliSuite extends munit.FunSuite {
override def afterAll(): Unit = {
super.afterAll()
// Clean up cached JDKs after all tests have run on Linux native CI runners
- if isCI && Properties.isLinux then TestUtil.cleanCachedJdks()
+ if isCI then TestUtil.cleanCachedJdks()
else System.err.println("Skipping cached JDKs cleanup")
+ if isCI then TestUtil.cleanCachedUsualSuspectDeps()
+ else System.err.println("Skipping cached JDKs cleanup")
+
}
}
diff --git a/modules/integration/src/test/scala/scala/cli/integration/TestUtil.scala b/modules/integration/src/test/scala/scala/cli/integration/TestUtil.scala
index 1a3e3c0396..51080402ef 100644
--- a/modules/integration/src/test/scala/scala/cli/integration/TestUtil.scala
+++ b/modules/integration/src/test/scala/scala/cli/integration/TestUtil.scala
@@ -465,4 +465,9 @@ object TestUtil {
System.err.println("Cleaning cached JDKs in Coursier cache…")
cleanCoursierCache(Seq("zulu", "temurin", "adoptium", "corretto", "liberica", "graalvm"))
}
+
+ def cleanCachedUsualSuspectDeps(): Unit = {
+ System.err.println("Cleaning usual suspect dependencies in Coursier cache…")
+ cleanCoursierCache(Seq("lihaoyi", "plokhotnyuk", "scalameta", "chuusai", "circe", "junit"))
+ }
}
diff --git a/project/deps/package.mill.scala b/project/deps/package.mill.scala
index 183a94bff9..d3df27477e 100644
--- a/project/deps/package.mill.scala
+++ b/project/deps/package.mill.scala
@@ -1,7 +1,8 @@
package build.project.deps
-import coursier.version.Version
-import mill._
-import scalalib._
+
+import mill.*
+import mill.api.BuildInfo
+import scalalib.*
object Cli {
def runnerScala30LegacyVersion =
@@ -115,7 +116,7 @@ object TestDeps {
object InternalDeps {
object Versions {
- def mill: String = _root_.mill.main.BuildInfo.millVersion
+ def mill: String = BuildInfo.millVersion
def lefouMillwRef = "166bcdf5741de8569e0630e18c3b2ef7e252cd96"
}
}
diff --git a/project/publish/package.mill.scala b/project/publish/package.mill.scala
index 0151871a20..19bbd20dcd 100644
--- a/project/publish/package.mill.scala
+++ b/project/publish/package.mill.scala
@@ -1,20 +1,20 @@
package build.project.publish
-import $ivy.`de.tototec::de.tobiasroeser.mill.vcs.version::0.4.0`
-import $ivy.`org.eclipse.jgit:org.eclipse.jgit:7.3.0.202506031305-r`
+
import build.project.settings
import com.lumidion.sonatype.central.client.core.{PublishingType, SonatypeCredentials}
import settings.{PublishLocalNoFluff, workspaceDirName}
-import de.tobiasroeser.mill.vcs.version._
-import mill._
+import mill.*
import mill.javalib.publish.Artifact
-import scalalib._
+import mill.util.{Tasks, VcsVersion}
+import scalalib.*
import org.eclipse.jgit.api.Git
+import mill.api.{BuildCtx, ModuleCtx, Task}
import java.nio.charset.Charset
-import scala.concurrent.duration._
-import scala.jdk.CollectionConverters._
+import scala.concurrent.duration.*
+import scala.jdk.CollectionConverters.*
-lazy val (ghOrg: String, ghName: String) = {
+def gh: (ghOrg: String, ghName: String) = {
def default = ("VirtusLab", "scala-cli")
val isCI = System.getenv("CI") != null
if (isCI) {
@@ -62,7 +62,9 @@ lazy val (ghOrg: String, ghName: String) = {
default
}
-private def computePublishVersion(state: VcsState, simple: Boolean): String =
+lazy val (ghOrg: String, ghName: String) = gh
+
+private def computePublishVersion(state: VcsVersion.State, simple: Boolean): String =
if (state.commitsSinceLastTag > 0)
if (simple) {
val versionOrEmpty = state.lastTag
@@ -140,16 +142,20 @@ trait ScalaCliPublishModule extends SonatypeCentralPublishModule with PublishLoc
)
)
override def publishVersion: T[String] = finalPublishVersion()
- override def sourceJar: T[PathRef] = Task {
- import mill.util.Jvm.createJar
- val allSources0 = allSources().map(_.path).filter(os.exists).toSet
- createJar(
- allSources0 ++ resources().map(_.path).filter(os.exists),
- manifest(),
- (input, relPath) =>
- !allSources0(input) ||
- (!relPath.segments.contains(".scala") && !relPath.segments.contains(workspaceDirName))
- )
+
+ override def sourceJar: T[PathRef] = Task {
+ PathRef {
+ import mill.util.Jvm.createJar
+ val allSources0 = allSources().map(_.path).filter(os.exists)
+ createJar(
+ jar = Task.dest / "out.jar",
+ inputPaths = allSources0 ++ resources().map(_.path).filter(os.exists),
+ manifest = manifest(),
+ fileFilter = (input, relPath) =>
+ !allSources0.toSet(input) ||
+ (!relPath.segments.contains(".scala") && !relPath.segments.contains(workspaceDirName))
+ )
+ }
}
}
@@ -211,7 +217,7 @@ def publishSonatype(
publisher.publishAll(
publishingType = publishingType,
singleBundleName = finalBundleName,
- artifacts = artifacts: _*
+ artifacts = artifacts*
)
}
@@ -235,7 +241,7 @@ def setShouldPublish() = Task.Command {
val charSet = Charset.defaultCharset()
val nl = System.lineSeparator()
os.write.append(
- os.Path(envFile, Task.workspace),
+ os.Path(envFile, BuildCtx.workspaceRoot),
s"SHOULD_PUBLISH=${shouldPublish()}$nl".getBytes(charSet)
)
}
diff --git a/project/settings/package.mill.scala b/project/settings/package.mill.scala
index 1b0941638e..a91df7dda5 100644
--- a/project/settings/package.mill.scala
+++ b/project/settings/package.mill.scala
@@ -1,6 +1,5 @@
package build.project.settings
-import $ivy.`com.goyeau::mill-scalafix::0.5.1`
-import $ivy.`io.github.alexarchambault.mill::mill-native-image::0.1.31-1`
+
import build.project.deps
import deps.{
Deps,
@@ -14,18 +13,18 @@ import build.project.utils
import utils.isArmArchitecture
import com.goyeau.mill.scalafix.ScalafixModule
import coursier.Repository
-import de.tobiasroeser.mill.vcs.version.{VcsState, VcsVersion}
import io.github.alexarchambault.millnativeimage.NativeImage
-import mill._
-import mill.api.Loose
-import mill.scalalib._
-import upickle.default._
+import mill.*
+import mill.scalalib.*
+import upickle.default.*
import java.io.File
import java.nio.charset.StandardCharsets
import java.util.Locale
import scala.annotation.unused
import scala.util.Properties
+import mill.util.{Tasks, VcsVersion}
+import mill.api.{BuildCtx, Task}
private def isCI = System.getenv("CI") != null
@@ -100,12 +99,12 @@ def cs: T[String] = Task(persistent = true) {
val archiveCache = coursier.cache.ArchiveCache().withCache(cache)
val task = cache.logger.using(archiveCache.get(coursier.util.Artifact(url)))
val maybeFile =
- try task.unsafeRun()(cache.ec)
+ try task.unsafeRun()(using cache.ec)
catch {
case t: Throwable =>
throw new Exception(s"Error getting and extracting $url", t)
}
- val f = maybeFile.fold(ex => throw new Exception(ex), os.Path(_, Task.workspace))
+ val f = maybeFile.fold(ex => throw new Exception(ex), os.Path(_, BuildCtx.workspaceRoot))
val exec =
if (Properties.isWin && os.isDir(f) && f.last.endsWith(".zip"))
os.list(f).find(_.last.endsWith(".exe")).getOrElse(
@@ -142,6 +141,13 @@ def platformSuffix: String = {
def localRepoResourcePath = "local-repo.zip"
+trait LocatedInModules extends Module {
+ override def moduleDir: os.Path = {
+ val oldModuleDir: os.Path = super.moduleDir
+ oldModuleDir / os.up / "modules" / oldModuleDir.last
+ }
+}
+
trait CliLaunchers extends SbtModule { self =>
def launcherTypeResourcePath: os.RelPath =
@@ -149,6 +155,7 @@ trait CliLaunchers extends SbtModule { self =>
def defaultFilesResourcePath: os.RelPath = os.rel / "scala" / "cli" / "commands" / "publish"
trait CliNativeImage extends NativeImage {
+ override def generateNativeImageWithFileSystemChecker: Boolean = false
def writeDefaultNativeImageScript(scriptDest: String): Command[Unit] =
Task.Command(super.writeNativeImageScript(scriptDest, "")())
@@ -274,21 +281,23 @@ trait CliLaunchers extends SbtModule { self =>
proc.call(stdin = os.Inherit, stdout = os.Inherit)
}
def staticLibDir: T[PathRef] = Task {
- val dir = nativeImageDockerWorkingDir() / staticLibDirName
- os.makeDir.all(dir)
+ BuildCtx.withFilesystemCheckerDisabled {
+ val dir = nativeImageDockerWorkingDir() / staticLibDirName
+ os.makeDir.all(dir)
+
+ if (Properties.isWin) {
+ copyLibsodiumStaticTo(cs(), dir, BuildCtx.workspaceRoot)
+ copyLibsodiumjniTo(cs(), dir, BuildCtx.workspaceRoot)
+ copyCsjniutilTo(cs(), dir, BuildCtx.workspaceRoot)
+ }
- if (Properties.isWin) {
- copyLibsodiumStaticTo(cs(), dir, Task.workspace)
- copyLibsodiumjniTo(cs(), dir, Task.workspace)
- copyCsjniutilTo(cs(), dir, Task.workspace)
- }
+ if (launcherKind == "static") {
+ copyAlpineLibsodiumTo(cs(), dir, BuildCtx.workspaceRoot)
+ copyLibsodiumjniTo(cs(), dir, BuildCtx.workspaceRoot)
+ }
- if (launcherKind == "static") {
- copyAlpineLibsodiumTo(cs(), dir, Task.workspace)
- copyLibsodiumjniTo(cs(), dir, Task.workspace)
+ PathRef(dir)
}
-
- PathRef(dir)
}
}
@@ -354,7 +363,7 @@ trait CliLaunchers extends SbtModule { self =>
}
def buildHelperImage: T[Unit] = Task {
os.proc("docker", "build", "-t", Docker.customMuslBuilderImageName, ".")
- .call(cwd = Task.workspace / "project" / "musl-image", stdout = os.Inherit)
+ .call(cwd = BuildCtx.workspaceRoot / "project" / "musl-image", stdout = os.Inherit)
()
}
override def writeDefaultNativeImageScript(scriptDest: String): Command[Unit] =
@@ -382,7 +391,7 @@ trait CliLaunchers extends SbtModule { self =>
mainClass().getOrElse(sys.error("Don't know what main class to use"))
}
- def transitiveJarsAgg: T[Agg[PathRef]] = {
+ def transitiveJarsSeq: T[Seq[PathRef]] = {
def allModuleDeps(todo: List[JavaModule]): List[JavaModule] =
todo match {
case Nil => Nil
@@ -391,7 +400,7 @@ trait CliLaunchers extends SbtModule { self =>
}
Task {
- mill.define.Task.traverse(allModuleDeps(this :: Nil).distinct)(m =>
+ Task.traverse(allModuleDeps(this :: Nil).distinct)(m =>
Task.Anon(m.jar())
)()
}
@@ -428,11 +437,13 @@ trait CliLaunchers extends SbtModule { self =>
cp,
mainClass0
) ++ args
- os.proc(command.map(x => x: os.Shellable): _*).call(
+ os.proc(command.map(x => x: os.Shellable)*).call(
stdin = os.Inherit,
stdout = os.Inherit
)
- Task.log.streams.out.println(s"Config generated in ${outputDir.relativeTo(Task.workspace)}")
+ Task.log.streams.out.println(
+ s"Config generated in ${outputDir.relativeTo(BuildCtx.workspaceRoot)}"
+ )
}
@unused
@@ -440,7 +451,7 @@ trait CliLaunchers extends SbtModule { self =>
val cp = jarClassPath().map(_.path).mkString(File.pathSeparator)
val mainClass0 = mainClass().getOrElse(sys.error("No main class"))
val command = Seq("java", "-cp", cp, mainClass0) ++ args
- os.proc(command.map(x => x: os.Shellable): _*).call(
+ os.proc(command.map(x => x: os.Shellable)*).call(
stdin = os.Inherit,
stdout = os.Inherit
)
@@ -451,7 +462,7 @@ trait CliLaunchers extends SbtModule { self =>
}
def jarClassPath: T[Seq[PathRef]] = Task {
- val cp = runClasspath() ++ transitiveJarsAgg()
+ val cp = runClasspath() ++ transitiveJarsSeq()
cp.filter(ref => os.exists(ref.path) && !os.isDir(ref.path))
}
@@ -479,7 +490,7 @@ trait CliLaunchers extends SbtModule { self =>
}
def standaloneLauncher: T[PathRef] = Task {
- val cachePath = os.Path(coursier.cache.FileCache().location, Task.workspace)
+ val cachePath = os.Path(coursier.cache.FileCache().location, BuildCtx.workspaceRoot)
def urlOf(path: os.Path): Option[String] =
if (path.startsWith(cachePath)) {
val segments = path.relativeTo(cachePath).segments
@@ -531,7 +542,7 @@ trait HasTests extends SbtModule {
super.scalacOptions() ++ extraOptions
}
trait ScalaCliTests extends ScalaCliModule with super.SbtTests with TestModule.Munit {
- override def ivyDeps: T[Agg[Dep]] = super.ivyDeps() ++ Agg(
+ override def mvnDeps: T[Seq[Dep]] = super.mvnDeps() ++ Seq(
Deps.expecty,
Deps.munit
)
@@ -558,25 +569,34 @@ trait PublishLocalNoFluff extends SonatypeCentralPublishModule {
}
// adapted from https://github.com/com-lihaoyi/mill/blob/fea79f0515dda1def83500f0f49993e93338c3de/scalalib/src/PublishModule.scala#L70-L85
// writes empty zips as source and doc JARs
- def publishLocalNoFluff(localIvyRepo: String = null): define.Command[PathRef] = Task.Command {
+ def publishLocalNoFluff(localIvyRepo: String = null): Command[PathRef] = Task.Command {
import mill.scalalib.publish.LocalIvyPublisher
val publisher = localIvyRepo match {
case null => LocalIvyPublisher
case repo =>
- new LocalIvyPublisher(os.Path(repo.replace("{VERSION}", publishVersion()), Task.workspace))
+ new LocalIvyPublisher(os.Path(
+ repo.replace("{VERSION}", publishVersion()),
+ BuildCtx.workspaceRoot
+ ))
}
- publisher.publishLocal(
- jar = jar().path,
- sourcesJar = emptyZip().path,
- docJar = emptyZip().path,
- pom = pom().path,
- ivy = ivy().path,
- artifact = artifactMetadata(),
- extras = extraPublish()
+ val artifact = artifactMetadata()
+ val jarPath = jar().path
+ val pomPath = pom().path
+ val ivyPath = ivy().path
+ val emptyPath = emptyZip().path
+
+ val contents = Map[os.SubPath, Array[Byte]](
+ os.sub / s"${artifact.id}-${artifact.version}.jar" -> os.read.bytes(jarPath),
+ os.sub / s"${artifact.id}-${artifact.version}-sources.jar" -> os.read.bytes(emptyPath),
+ os.sub / s"${artifact.id}-${artifact.version}-javadoc.jar" -> os.read.bytes(emptyPath),
+ os.sub / s"${artifact.id}-${artifact.version}.pom" -> os.read.bytes(pomPath),
+ os.sub / "ivy.xml" -> os.read.bytes(ivyPath)
)
+ publisher.publishLocal(artifact, contents)
+
jar()
}
}
@@ -585,13 +605,13 @@ trait LocalRepo extends Module {
def stubsModules: Seq[PublishLocalNoFluff]
def version: T[String]
- def localRepo: T[Seq[PathRef]] = Task {
- val repoRoot = os.rel / "out" / "repo" / "{VERSION}"
- val tasks = stubsModules.map(_.publishLocalNoFluff(repoRoot.toString))
- define.Task.sequence(tasks)
+ def localRepo: T[Seq[PathRef]] = {
+ val repoRoot = os.rel / "out" / "repo" / "{VERSION}"
+ val tasks: Seq[Command[PathRef]] = stubsModules.map(_.publishLocalNoFluff(repoRoot.toString))
+ Task.sequence(tasks)()
}
- private def vcsState: T[VcsState] =
+ private def vcsState: T[VcsVersion.State] =
if (isCI)
Task(persistent = true) {
VcsVersion.vcsState()
@@ -601,48 +621,50 @@ trait LocalRepo extends Module {
VcsVersion.vcsState()
}
def localRepoZip: T[PathRef] = Task {
- val repoVer = vcsState().format()
- val ver = version()
- localRepo()
- val repoDir = Task.workspace / "out" / "repo" / ver
- val destDir = Task.dest / ver / "repo.zip"
- val dest = destDir / "repo.zip"
-
- import java.io._
- import java.util.zip._
- os.makeDir.all(destDir)
- var fos: FileOutputStream = null
- var zos: ZipOutputStream = null
- try {
- fos = new FileOutputStream(dest.toIO)
- zos = new ZipOutputStream(new BufferedOutputStream(fos))
-
- val versionEntry = new ZipEntry("version")
- versionEntry.setTime(0L)
- zos.putNextEntry(versionEntry)
- zos.write(repoVer.getBytes(StandardCharsets.UTF_8))
- zos.flush()
-
- os.walk(repoDir).filter(_ != repoDir).foreach { p =>
- val isDir = os.isDir(p)
- val name = p.relativeTo(repoDir).toString + (if (isDir) "/" else "")
- val entry = new ZipEntry(name)
- entry.setTime(os.mtime(p))
- zos.putNextEntry(entry)
- if (!isDir) {
- zos.write(os.read.bytes(p))
- zos.flush()
+ BuildCtx.withFilesystemCheckerDisabled {
+ val repoVer = vcsState().format()
+ val ver = version()
+ localRepo()
+ val repoDir = BuildCtx.workspaceRoot / "out" / "repo" / ver
+ val destDir = Task.dest / ver / "repo.zip"
+ val dest = destDir / "repo.zip"
+
+ import java.io._
+ import java.util.zip._
+ os.makeDir.all(destDir)
+ var fos: FileOutputStream = null
+ var zos: ZipOutputStream = null
+ try {
+ fos = new FileOutputStream(dest.toIO)
+ zos = new ZipOutputStream(new BufferedOutputStream(fos))
+
+ val versionEntry = new ZipEntry("version")
+ versionEntry.setTime(0L)
+ zos.putNextEntry(versionEntry)
+ zos.write(repoVer.getBytes(StandardCharsets.UTF_8))
+ zos.flush()
+
+ os.walk(repoDir).filter(_ != repoDir).foreach { p =>
+ val isDir = os.isDir(p)
+ val name = p.relativeTo(repoDir).toString + (if (isDir) "/" else "")
+ val entry = new ZipEntry(name)
+ entry.setTime(os.mtime(p))
+ zos.putNextEntry(entry)
+ if (!isDir) {
+ zos.write(os.read.bytes(p))
+ zos.flush()
+ }
+ zos.closeEntry()
}
- zos.closeEntry()
+ zos.finish()
+ }
+ finally {
+ if (zos != null) zos.close()
+ if (fos != null) fos.close()
}
- zos.finish()
- }
- finally {
- if (zos != null) zos.close()
- if (fos != null) fos.close()
- }
- PathRef(dest)
+ PathRef(dest)
+ }
}
def localRepoJar: T[PathRef] = Task {
@@ -702,12 +724,12 @@ private def doFormatNativeImageConf(dir: os.Path, format: Boolean): List[os.Path
entries -= "methods"
ujson.Obj(entries)
}
- ujson.Arr(values: _*)
+ ujson.Arr(values*)
}
else if (sortByName(name))
json.arrOpt.fold(json) { arr =>
val values = arr.toVector.sortBy(_("name").str)
- ujson.Arr(values: _*)
+ ujson.Arr(values*)
}
else
json
@@ -749,7 +771,7 @@ trait FormatNativeImageConf extends JavaModule {
for (f <- needsFormatting)
System.err.println(
s" ${
- if (f.startsWith(Task.workspace)) f.relativeTo(Task.workspace).toString
+ if (f.startsWith(BuildCtx.workspaceRoot)) f.relativeTo(BuildCtx.workspaceRoot).toString
else f.toString
}"
)
@@ -777,18 +799,18 @@ trait ScalaCliScalafixModule extends ScalafixModule {
def scalafixConfig: T[Option[os.Path]] = Task {
if (scalaVersion().startsWith("2.")) super.scalafixConfig()
- else Some(Task.workspace / ".scalafix3.conf")
+ else Some(BuildCtx.workspaceRoot / ".scalafix3.conf")
}
- def scalacPluginIvyDeps: T[Loose.Agg[Dep]] = super.scalacPluginIvyDeps() ++ {
+ def scalacPluginMvnDeps: T[Seq[Dep]] = super.scalacPluginMvnDeps() ++ {
if (scalaVersion().startsWith("2.")) Seq(Deps.semanticDbScalac)
else Nil
}
// Explicitly setting sourceroot, so that Scala CLI doesn't use a wrong one.
- // Using Task.workspace is more or less required, for scalafix stuff to work fine.
+ // Using BuildCtx.workspaceRoot is more or less required, for scalafix stuff to work fine.
def scalacOptions: T[Seq[String]] = Task {
val sv = scalaVersion()
val isScala2 = sv.startsWith("2.")
- val sourceRoot = Task.workspace
+ val sourceRoot = BuildCtx.workspaceRoot
val parentOptions = {
val l = super.scalacOptions()
if (isScala2) l.filterNot(_.startsWith("-P:semanticdb:sourceroot:"))