From 548e9518864e009f590068bf71f49d7e2de45372 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Sat, 27 Sep 2025 12:14:02 -0400 Subject: [PATCH 01/33] . --- .../mill/javalib/SemanticDbJavaModule.scala | 4 +- .../mill/javalib/zinc/PositionMapper.scala | 114 ---------- .../javalib/zinc/TransformingReporter.scala | 211 ------------------ .../src/mill/javalib/zinc/ZincWorker.scala | 15 +- .../src/mill/meta/AsmPositionUpdater.scala | 43 ---- runner/meta/src/mill/meta/CodeGen.scala | 4 +- .../src/mill/meta/MillBuildRootModule.scala | 57 +---- 7 files changed, 16 insertions(+), 432 deletions(-) delete mode 100644 libs/javalib/worker/src/mill/javalib/zinc/PositionMapper.scala delete mode 100644 libs/javalib/worker/src/mill/javalib/zinc/TransformingReporter.scala delete mode 100644 runner/meta/src/mill/meta/AsmPositionUpdater.scala diff --git a/libs/javalib/src/mill/javalib/SemanticDbJavaModule.scala b/libs/javalib/src/mill/javalib/SemanticDbJavaModule.scala index f90665f7850c..115b28a027ff 100644 --- a/libs/javalib/src/mill/javalib/SemanticDbJavaModule.scala +++ b/libs/javalib/src/mill/javalib/SemanticDbJavaModule.scala @@ -236,7 +236,7 @@ object SemanticDbJavaModule extends ExternalModule with CoursierModule { ) } - private val userCodeStartMarker = "//SOURCECODE_ORIGINAL_CODE_START_MARKER" + private val userCodeStartMarker = "///SOURCE_CODE_START" private def postProcessed( generatedSourceSemdb: os.Path, @@ -255,7 +255,7 @@ object SemanticDbJavaModule extends ExternalModule with CoursierModule { val generatedSource = sourceroot / generatedSourceSubPath val generatedSourceLines = os.read.lines(generatedSource) val source = generatedSourceLines - .collectFirst { case s"//SOURCECODE_ORIGINAL_FILE_PATH=$rest" => os.Path(rest.trim) } + .collectFirst { case s"///SOURCE_CODE_START:$rest" => os.Path(rest.trim) } .getOrElse { sys.error(s"Cannot get original source from generated source $generatedSource") } diff --git a/libs/javalib/worker/src/mill/javalib/zinc/PositionMapper.scala b/libs/javalib/worker/src/mill/javalib/zinc/PositionMapper.scala deleted file mode 100644 index 7d05e0dd528e..000000000000 --- a/libs/javalib/worker/src/mill/javalib/zinc/PositionMapper.scala +++ /dev/null @@ -1,114 +0,0 @@ -package mill.javalib.zinc - -import mill.constants.CodeGenConstants -import xsbti.VirtualFile - -import java.nio.charset.StandardCharsets -import scala.jdk.CollectionConverters.* - -object PositionMapper { - - import sbt.util.InterfaceUtil - - private val userCodeStartMarker = "//SOURCECODE_ORIGINAL_CODE_START_MARKER" - - /** Transforms positions of problems if coming from a build file. */ - private def lookup(buildSources: Map[String, xsbti.Position => xsbti.Position])( - oldPos: xsbti.Position - ): xsbti.Position = { - val src = oldPos.sourcePath() - if src.isPresent then { - buildSources.get(src.get()) match { - case Some(f) => f(oldPos) - case _ => oldPos - } - } else { - oldPos - } - } - - def create(sources: Array[VirtualFile]) - : (Map[os.Path, os.Path], Option[xsbti.Position => xsbti.Position]) = { - val buildSources0 = { - def isBuild(vf: VirtualFile) = - CodeGenConstants.buildFileExtensions.asScala.exists(ex => - vf.id().endsWith(s".$ex") - ) - - sources.collect({ - case vf if isBuild(vf) => - val str = new String(vf.input().readAllBytes(), StandardCharsets.UTF_8) - - val lines = str.linesWithSeparators.toVector - val adjustedFile = lines - .collectFirst { case s"//SOURCECODE_ORIGINAL_FILE_PATH=$rest" => rest.trim } - .getOrElse(sys.error(vf.id())) - - (vf.id(), adjustedFile, remap(lines, adjustedFile)) - }) - } - - val map = buildSources0 - .map { - case (generated, original, _) => - os.Path(generated) -> os.Path(original) - } - .toMap - val lookupOpt = Option.when(buildSources0.nonEmpty) { - lookup(buildSources0.map { case (generated, _, f) => (generated, f) }.toMap) - } - (map, lookupOpt) - } - - private def remap( - lines: Vector[String], - adjustedFile: String - ): xsbti.Position => xsbti.Position = { - val markerLine = lines.indexWhere(_.startsWith(userCodeStartMarker)) - - val topWrapperLen = lines.take(markerLine + 1).map(_.length).sum - - val originPath = Some(adjustedFile) - val originFile = Some(java.nio.file.Paths.get(adjustedFile).toFile) - - def userCode(offset: java.util.Optional[Integer]): Boolean = - intValue(offset, -1) > topWrapperLen - - def inner(pos0: xsbti.Position): xsbti.Position = { - if userCode(pos0.startOffset()) || userCode(pos0.offset()) then { - val IArray(line, offset, startOffset, endOffset, startLine, endLine) = - IArray( - pos0.line(), - pos0.offset(), - pos0.startOffset(), - pos0.endOffset(), - pos0.startLine(), - pos0.endLine() - ) - .map(intValue(_, 1) - 1) - - val (baseLine, baseOffset) = (markerLine, topWrapperLen) - - InterfaceUtil.position( - line0 = Some(line - baseLine), - content = pos0.lineContent(), - offset0 = Some(offset - baseOffset), - pointer0 = InterfaceUtil.jo2o(pos0.pointer()), - pointerSpace0 = InterfaceUtil.jo2o(pos0.pointerSpace()), - sourcePath0 = originPath, - sourceFile0 = originFile, - startOffset0 = Some(startOffset - baseOffset), - endOffset0 = Some(endOffset - baseOffset), - startLine0 = Some(startLine - baseLine), - startColumn0 = InterfaceUtil.jo2o(pos0.startColumn()), - endLine0 = Some(endLine - baseLine), - endColumn0 = InterfaceUtil.jo2o(pos0.endColumn()) - ) - } else { - pos0 - } - } - - inner - } -} diff --git a/libs/javalib/worker/src/mill/javalib/zinc/TransformingReporter.scala b/libs/javalib/worker/src/mill/javalib/zinc/TransformingReporter.scala deleted file mode 100644 index d7744bbcbd8a..000000000000 --- a/libs/javalib/worker/src/mill/javalib/zinc/TransformingReporter.scala +++ /dev/null @@ -1,211 +0,0 @@ -package mill.javalib.zinc - -private trait TransformingReporter( - color: Boolean, - optPositionMapper: (xsbti.Position => xsbti.Position) | Null -) extends xsbti.Reporter { - - // Overriding this is necessary because for some reason the LoggedReporter doesn't transform positions - // of Actions and DiagnosticRelatedInformation - abstract override def log(problem0: xsbti.Problem): Unit = { - val localMapper = optPositionMapper - val problem = { - if localMapper == null then problem0 - else TransformingReporter.transformProblem(color, problem0, localMapper) - } - super.log(problem) - } -} - -private object TransformingReporter { - - import sbt.util.InterfaceUtil - - import scala.jdk.CollectionConverters.given - - /** implements a transformation that returns the same object if the mapper has no effect. */ - private def transformProblem( - color: Boolean, - problem0: xsbti.Problem, - mapper: xsbti.Position => xsbti.Position - ): xsbti.Problem = { - val pos0 = problem0.position() - val related0 = problem0.diagnosticRelatedInformation() - val actions0 = problem0.actions() - val pos = mapper(pos0) - val related = transformRelateds(related0, mapper) - val actions = transformActions(actions0, mapper) - val posIsNew = pos ne pos0 - if posIsNew || (related ne related0) || (actions ne actions0) then - val rendered = { - // if we transformed the position, then we must re-render the message - if posIsNew then Some(dottyStyleMessage(color, problem0, pos)) - else InterfaceUtil.jo2o(problem0.rendered()) - } - InterfaceUtil.problem( - cat = problem0.category(), - pos = pos, - msg = problem0.message(), - sev = problem0.severity(), - rendered = rendered, - diagnosticCode = InterfaceUtil.jo2o(problem0.diagnosticCode()), - diagnosticRelatedInformation = anyToList(related), - actions = anyToList(actions) - ) - else - problem0 - } - - private type JOrSList[T] = java.util.List[T] | List[T] - - private def anyToList[T](ts: JOrSList[T]): List[T] = ts match { - case ts: List[T] => ts - case ts: java.util.List[T] => ts.asScala.toList - } - - /** Render the message in the style of dotty */ - private def dottyStyleMessage( - color: Boolean, - problem0: xsbti.Problem, - pos: xsbti.Position - ): String = { - val base = problem0.message() - val severity = problem0.severity() - - def shade(msg: String) = - if color then - severity match { - case xsbti.Severity.Error => Console.RED + msg + Console.RESET - case xsbti.Severity.Warn => Console.YELLOW + msg + Console.RESET - case xsbti.Severity.Info => Console.BLUE + msg + Console.RESET - } - else msg - - val normCode = { - problem0.diagnosticCode().filter(_.code() != "-1").map({ inner => - val prefix = s"[E${inner.code()}] " - inner.explanation().map(e => - s"$prefix$e: " - ).orElse(prefix) - }).orElse("") - } - - val optPath = InterfaceUtil.jo2o(pos.sourcePath()).map { path => - val line0 = intValue(pos.line(), -1) - val pointer0 = intValue(pos.pointer(), -1) - if line0 >= 0 && pointer0 >= 0 then - s"$path:$line0:${pointer0 + 1}" - else - path - } - - val normHeader = optPath.map(path => - s"${shade(s"-- $normCode$path")}\n" - ).getOrElse("") - - val optSnippet = { - val snip = pos.lineContent() - val space = pos.pointerSpace().orElse("") - val pointer = intValue(pos.pointer(), -99) - val endCol = intValue(pos.endColumn(), pointer + 1) - if snip.nonEmpty && space.nonEmpty && pointer >= 0 && endCol >= 0 then - val arrowCount = math.max(1, math.min(endCol - pointer, snip.length - space.length)) - Some( - s"""$snip - |$space${"^" * arrowCount}""".stripMargin - ) - else - None - } - - val content = optSnippet.match { - case Some(snippet) => - val initial = { - s"""$snippet - |$base - |""".stripMargin - } - val snippetLine = intValue(pos.line(), -1) - if snippetLine >= 0 then { - // add margin with line number - val lines = initial.linesWithSeparators.toVector - val pre = snippetLine.toString - val rest0 = " " * pre.length - val rest = pre +: Vector.fill(lines.size - 1)(rest0) - rest.lazyZip(lines).map((pre, line) => shade(s"$pre │") + line).mkString - } else { - initial - } - case None => - base - } - - normHeader + content - } - - /** Implements a transformation that returns the same list if the mapper has no effect */ - private def transformActions( - actions0: java.util.List[xsbti.Action], - mapper: xsbti.Position => xsbti.Position - ): JOrSList[xsbti.Action] = { - if actions0.iterator().asScala.exists(a => - a.edit().changes().iterator().asScala.exists(e => - mapper(e.position()) ne e.position() - ) - ) - then { - actions0.iterator().asScala.map(transformAction(_, mapper)).toList - } else { - actions0 - } - } - - /** Implements a transformation that returns the same list if the mapper has no effect */ - private def transformRelateds( - related0: java.util.List[xsbti.DiagnosticRelatedInformation], - mapper: xsbti.Position => xsbti.Position - ): JOrSList[xsbti.DiagnosticRelatedInformation] = { - - if related0.iterator().asScala.exists(r => mapper(r.position()) ne r.position()) then - related0.iterator().asScala.map(transformRelated(_, mapper)).toList - else - related0 - } - - private def transformRelated( - related0: xsbti.DiagnosticRelatedInformation, - mapper: xsbti.Position => xsbti.Position - ): xsbti.DiagnosticRelatedInformation = { - InterfaceUtil.diagnosticRelatedInformation(mapper(related0.position()), related0.message()) - } - - private def transformAction( - action0: xsbti.Action, - mapper: xsbti.Position => xsbti.Position - ): xsbti.Action = { - InterfaceUtil.action( - title = action0.title(), - description = InterfaceUtil.jo2o(action0.description()), - edit = transformEdit(action0.edit(), mapper) - ) - } - - private def transformEdit( - edit0: xsbti.WorkspaceEdit, - mapper: xsbti.Position => xsbti.Position - ): xsbti.WorkspaceEdit = { - InterfaceUtil.workspaceEdit( - edit0.changes().iterator().asScala.map(transformTEdit(_, mapper)).toList - ) - } - - private def transformTEdit( - edit0: xsbti.TextEdit, - mapper: xsbti.Position => xsbti.Position - ): xsbti.TextEdit = { - InterfaceUtil.textEdit( - position = mapper(edit0.position()), - newText = edit0.newText() - ) - } -} diff --git a/libs/javalib/worker/src/mill/javalib/zinc/ZincWorker.scala b/libs/javalib/worker/src/mill/javalib/zinc/ZincWorker.scala index d0814146fffa..bfaaa76a536b 100644 --- a/libs/javalib/worker/src/mill/javalib/zinc/ZincWorker.scala +++ b/libs/javalib/worker/src/mill/javalib/zinc/ZincWorker.scala @@ -394,13 +394,12 @@ class ZincWorker( def mkNewReporter(mapper: (xsbti.Position => xsbti.Position) | Null) = reporter match { case None => - new ManagedLoggedReporter(maxErrors, logger) with RecordingReporter - with TransformingReporter(ctx.logPromptColored, mapper) {} + new ManagedLoggedReporter(maxErrors, logger) with RecordingReporter {} + case Some(forwarder) => new ManagedLoggedReporter(maxErrors, logger) with ForwardingReporter(forwarder) - with RecordingReporter - with TransformingReporter(ctx.logPromptColored, mapper) {} + with RecordingReporter {} } val analysisMap0 = upstreamCompileOutput.map(c => c.classes.path -> c.analysisFile).toMap @@ -455,8 +454,8 @@ class ZincWorker( scalacOptions } - val (originalSourcesMap, posMapperOpt) = PositionMapper.create(virtualSources) - val newReporter = mkNewReporter(posMapperOpt.orNull) +// val (originalSourcesMap, posMapperOpt) = PositionMapper.create(virtualSources) + val newReporter = mkNewReporter(null) val inputs = incrementalCompiler.inputs( classpath = classpath, @@ -524,8 +523,8 @@ class ZincWorker( for (rep <- reporter) { for (f <- sources) { rep.fileVisited(f.toNIO) - for (f0 <- originalSourcesMap.get(f)) - rep.fileVisited(f0.toNIO) +// for (f0 <- originalSourcesMap.get(f)) +// rep.fileVisited(f0.toNIO) } rep.finish() } diff --git a/runner/meta/src/mill/meta/AsmPositionUpdater.scala b/runner/meta/src/mill/meta/AsmPositionUpdater.scala deleted file mode 100644 index 701d54e344c5..000000000000 --- a/runner/meta/src/mill/meta/AsmPositionUpdater.scala +++ /dev/null @@ -1,43 +0,0 @@ -package mill.meta - -// originally based on https://github.com/VirtusLab/scala-cli/blob/67db91cfbaa74de806fd1d5ed00096affa0125c0/modules/build/src/main/scala/scala/build/postprocessing/AsmPositionUpdater.scala - -import org.objectweb.asm -import java.io.InputStream - -object AsmPositionUpdater { - - private class LineNumberTableMethodVisitor( - lineNumberOffset: Int, - delegate: asm.MethodVisitor - ) extends asm.MethodVisitor(asm.Opcodes.ASM9, delegate) { - override def visitLineNumber(line: Int, start: asm.Label): Unit = - super.visitLineNumber(math.max(0, line + lineNumberOffset), start) - } - - private class LineNumberTableClassVisitor( - lineNumberOffset: Int, - cw: asm.ClassWriter - ) extends asm.ClassVisitor(asm.Opcodes.ASM9, cw) { - - override def visitMethod( - access: Int, - name: String, - descriptor: String, - signature: String, - exceptions: Array[String] - ): asm.MethodVisitor = { - val main = super.visitMethod(access, name, descriptor, signature, exceptions) - new LineNumberTableMethodVisitor(lineNumberOffset, main) - - } - } - - def postProcess(lineNumberOffset: Int, clsInputStream: InputStream): Array[Byte] = { - val reader = new asm.ClassReader(clsInputStream) - val writer = new asm.ClassWriter(reader, 0) - val checker = new LineNumberTableClassVisitor(lineNumberOffset, writer) - reader.accept(checker, 0) - writer.toByteArray - } -} diff --git a/runner/meta/src/mill/meta/CodeGen.scala b/runner/meta/src/mill/meta/CodeGen.scala index fbebae524d0d..9b127838d833 100644 --- a/runner/meta/src/mill/meta/CodeGen.scala +++ b/runner/meta/src/mill/meta/CodeGen.scala @@ -84,9 +84,7 @@ object CodeGen { val scriptCode = allScriptCode(scriptPath) - val markerComment = - s"""//SOURCECODE_ORIGINAL_FILE_PATH=$scriptPath - |//SOURCECODE_ORIGINAL_CODE_START_MARKER""".stripMargin + val markerComment = s"///SOURCE_CODE_START:$scriptPath" val siblingScripts = scriptSources .filter(_ != scriptPath) diff --git a/runner/meta/src/mill/meta/MillBuildRootModule.scala b/runner/meta/src/mill/meta/MillBuildRootModule.scala index 2da0d0ad3859..afb88bbe629f 100644 --- a/runner/meta/src/mill/meta/MillBuildRootModule.scala +++ b/runner/meta/src/mill/meta/MillBuildRootModule.scala @@ -254,7 +254,11 @@ trait MillBuildRootModule()(implicit super.scalacOptions() ++ // This warning comes up for package names with dashes in them like "package build.`foo-bar`", // but Mill generally handles these fine, so no need to warn the user - Seq("-deprecation", "-Wconf:msg=will be encoded on the classpath:silent") + Seq( + "-deprecation", + "-Wconf:msg=will be encoded on the classpath:silent", + "-Ymagic-offset-header:SOURCE_CODE_START" + ) } /** Used in BSP IntelliJ, which can only work with directories */ @@ -304,60 +308,11 @@ trait MillBuildRootModule()(implicit javaRuntimeOptions = jOpts.runtime, reporter = Task.reporter.apply(hashCode), reportCachedProblems = zincReportCachedProblems() - ).map { - res => - // Perform the line-number updating in a copy of the classfiles, because - // mangling the original class files messes up zinc incremental compilation - val transformedClasses = Task.dest / "transformed-classes" - os.remove.all(transformedClasses) - os.copy(res.classes.path, transformedClasses) - - MillBuildRootModule.updateLineNumbers( - transformedClasses, - generatedScriptSources().wrapped.head.path - ) - - res.copy(classes = PathRef(transformedClasses)) - } + ) } } object MillBuildRootModule { - - private def updateLineNumbers(classesDir: os.Path, generatedScriptSourcesPath: os.Path) = { - for (p <- os.walk(classesDir) if p.ext == "class") { - val rel = p.subRelativeTo(classesDir) - // Hack to reverse engineer the `.mill` name from the `.class` file name - val sourceNamePrefixOpt0 = rel.last match { - case s"${pre}_$_.class" => Some(pre) - case s"${pre}$$$_.class" => Some(pre) - case s"${pre}.class" => Some(pre) - case _ => None - } - - val sourceNamePrefixOpt = sourceNamePrefixOpt0 match { - case Some("package") if (rel / os.up) == os.rel / "build_" => Some("build") - case p => p - } - - for (prefix <- sourceNamePrefixOpt) { - val sourceFile = generatedScriptSourcesPath / rel / os.up / s"$prefix.mill" - if (os.exists(sourceFile)) { - - val lineNumberOffset = - os.read.lines(sourceFile).indexOf("//SOURCECODE_ORIGINAL_CODE_START_MARKER") + 1 - os.write.over( - p, - os - .read - .stream(p) - .readBytesThrough(stream => AsmPositionUpdater.postProcess(-lineNumberOffset, stream)) - ) - } - } - } - } - class BootstrapModule()(implicit rootModuleInfo: RootModule.Info ) extends MainRootModule() with MillBuildRootModule() { From 48b0d016098e2fcffdfb683e8b5f6ad3d746ea28 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Wed, 29 Oct 2025 12:28:36 +0800 Subject: [PATCH 02/33] wip --- .../src/mill/daemon/MillScalaParserImpl.scala | 3 ++- runner/meta/src/mill/meta/CodeGen.scala | 27 +++++++------------ .../meta/src/mill/meta/FileImportGraph.scala | 9 ++++--- .../src/mill/meta/MillBuildRootModule.scala | 7 ++--- 4 files changed, 20 insertions(+), 26 deletions(-) diff --git a/runner/daemon/src/mill/daemon/MillScalaParserImpl.scala b/runner/daemon/src/mill/daemon/MillScalaParserImpl.scala index dc76e7b70078..0757e67a6a52 100644 --- a/runner/daemon/src/mill/daemon/MillScalaParserImpl.scala +++ b/runner/daemon/src/mill/daemon/MillScalaParserImpl.scala @@ -35,6 +35,7 @@ object MillScalaParserImpl extends MillScalaParser { rawCode: String, fileName: String ): Either[String, (String, Seq[String], Seq[String])] = { + mill.constants.DebugLog.println("rawCode " + pprint.apply(rawCode)) val source = SourceFile.virtual(fileName, rawCode) def mergeErrors(errors: List[String]): String = s"$fileName failed to parse:" + System.lineSeparator + errors.mkString(System.lineSeparator) @@ -56,7 +57,7 @@ object MillScalaParserImpl extends MillScalaParser { if (!trees.head.startPos.exists) "" else new String(source.file.toByteArray).take(trees.head.startPos.start) } - + mill.constants.DebugLog.println("pkgs " + pprint.apply(pkgs)) (prefix, pkgs, stmts) } } diff --git a/runner/meta/src/mill/meta/CodeGen.scala b/runner/meta/src/mill/meta/CodeGen.scala index 9a156fa8eccf..d1dbe52682bc 100644 --- a/runner/meta/src/mill/meta/CodeGen.scala +++ b/runner/meta/src/mill/meta/CodeGen.scala @@ -18,6 +18,7 @@ object CodeGen { def generateWrappedAndSupportSources( projectRoot: os.Path, allScriptCode: Map[os.Path, String], + allPackageStatements: Map[os.Path, String], wrappedDest: os.Path, supportDest: os.Path, millTopLevelProjectRoot: os.Path, @@ -66,8 +67,6 @@ object CodeGen { } .mkString("\n ") - val pkg = pkgSelector0(Some(CGConst.globalPackagePrefix), None) - val aliasImports = Seq( // Provide `build` as an alias to the root `build_.package_`, since from the user's // perspective it looks like they're writing things that live in `package build`, @@ -75,9 +74,16 @@ object CodeGen { "import build_.{package_ => build}" ).mkString("\n") - val scriptCode = allScriptCode(scriptPath) + val strippedPackageStatementComment = allPackageStatements.get(scriptPath) match { + // Add another comment after the marker comment to substitute any package statement + // that was stripped during codegen and ensure the offsets line up properly + case Some(s) => "\n//" + s.drop(2) + case None => "" + } + + val markerComment = s"///SOURCE_CODE_START:$scriptPath" + strippedPackageStatementComment + - val markerComment = s"///SOURCE_CODE_START:$scriptPath" val siblingScripts = scriptSources .filter(_ != scriptPath) @@ -196,19 +202,6 @@ object CodeGen { val scriptCode = allScriptCode(scriptPath) - val markerComment = - s"""//SOURCECODE_ORIGINAL_FILE_PATH=$scriptPath - |//SOURCECODE_ORIGINAL_CODE_START_MARKER""".stripMargin - - val siblingScripts = scriptSources - .filter(_ != scriptPath) - .filter(p => (p / os.up) == (scriptPath / os.up)) - .map(_.last.split('.').head + "_") - - val importSiblingScripts = siblingScripts - .filter(s => s != "build_" && s != "package_") - .map(s => s"import $pkg.${backtickWrap(s)}.*").mkString("\n") - if (isBuildScript) { os.write.over(supportDestDir / "MillMiscInfo.scala", miscInfo, createFolders = true) } diff --git a/runner/meta/src/mill/meta/FileImportGraph.scala b/runner/meta/src/mill/meta/FileImportGraph.scala index 1b0064538f3a..62aeaf14d6a8 100644 --- a/runner/meta/src/mill/meta/FileImportGraph.scala +++ b/runner/meta/src/mill/meta/FileImportGraph.scala @@ -17,7 +17,9 @@ import mill.internal.Util.backtickWrap * @param metaBuild If `true`, a meta-build is enabled */ @internal -case class FileImportGraph(seenScripts: Map[os.Path, String], errors: Seq[String]) +case class FileImportGraph(seenScripts: Map[os.Path, String], + errors: Seq[String], + seenPkgStatements: Map[os.Path, String]) /** * Logic around traversing the `import $file` graph, extracting necessary info @@ -42,11 +44,11 @@ object FileImportGraph { walked: Seq[os.Path] ): FileImportGraph = { val seenScripts = mutable.Map.empty[os.Path, String] + val seenPkgStatements = mutable.Map.empty[os.Path, String] val errors = mutable.Buffer.empty[String] def processScript(s: os.Path, useDummy: Boolean = false): Unit = try { - val content = if (useDummy) "" else os.read(s) val fileName = s.relativeTo(topLevelProjectRoot).toString val buildHeaderError = @@ -79,6 +81,7 @@ object FileImportGraph { ) } seenScripts(s) = prefix + stmts.mkString + seenPkgStatements(s) = "package " + importSegments case Left(error) => seenScripts(s) = "" errors.append(error) @@ -95,7 +98,7 @@ object FileImportGraph { walked.foreach(processScript(_)) - new FileImportGraph(seenScripts.toMap, errors.toSeq) + new FileImportGraph(seenScripts.toMap, errors.toSeq, seenPkgStatements.toMap) } def findRootBuildFiles(projectRoot: os.Path) = { diff --git a/runner/meta/src/mill/meta/MillBuildRootModule.scala b/runner/meta/src/mill/meta/MillBuildRootModule.scala index f98c00ace18a..08021910d8fc 100644 --- a/runner/meta/src/mill/meta/MillBuildRootModule.scala +++ b/runner/meta/src/mill/meta/MillBuildRootModule.scala @@ -120,6 +120,7 @@ trait MillBuildRootModule()(using CodeGen.generateWrappedAndSupportSources( rootModuleInfo.projectRoot / os.up, parsed.seenScripts, + parsed.seenPkgStatements, wrapped, support, rootModuleInfo.topLevelProjectRoot, @@ -131,11 +132,7 @@ trait MillBuildRootModule()(using } def millBuildRootModuleResult = Task { - Tuple3( - runClasspath(), - compile().classes, - codeSignatures() - ) + Tuple3(runClasspath(), compile().classes, codeSignatures()) } def codeSignatures: T[Map[String, Int]] = Task(persistent = true) { From 3b0c097938bbf7afb347c87feea5ee748b10fc4d Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Wed, 29 Oct 2025 12:34:41 +0800 Subject: [PATCH 03/33] wip --- runner/daemon/src/mill/daemon/MillScalaParserImpl.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runner/daemon/src/mill/daemon/MillScalaParserImpl.scala b/runner/daemon/src/mill/daemon/MillScalaParserImpl.scala index 0757e67a6a52..cd0eb7aa8719 100644 --- a/runner/daemon/src/mill/daemon/MillScalaParserImpl.scala +++ b/runner/daemon/src/mill/daemon/MillScalaParserImpl.scala @@ -57,7 +57,7 @@ object MillScalaParserImpl extends MillScalaParser { if (!trees.head.startPos.exists) "" else new String(source.file.toByteArray).take(trees.head.startPos.start) } - mill.constants.DebugLog.println("pkgs " + pprint.apply(pkgs)) + (prefix, pkgs, stmts) } } From 6316a450ad6036844ecf906455952e172f757db7 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Wed, 29 Oct 2025 12:36:10 +0800 Subject: [PATCH 04/33] wip --- libs/javalib/worker/src/mill/javalib/zinc/ZincWorker.scala | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/libs/javalib/worker/src/mill/javalib/zinc/ZincWorker.scala b/libs/javalib/worker/src/mill/javalib/zinc/ZincWorker.scala index e323080412b4..68282c02155b 100644 --- a/libs/javalib/worker/src/mill/javalib/zinc/ZincWorker.scala +++ b/libs/javalib/worker/src/mill/javalib/zinc/ZincWorker.scala @@ -442,7 +442,6 @@ class ZincWorker( scalacOptions } -// val (originalSourcesMap, posMapperOpt) = PositionMapper.create(virtualSources) val newReporter = mkNewReporter(null) val inputs = incrementalCompiler.inputs( @@ -509,11 +508,7 @@ class ZincWorker( Result.Failure(e.toString) } finally { for (rep <- reporter) { - for (f <- sources) { - rep.fileVisited(f.toNIO) -// for (f0 <- originalSourcesMap.get(f)) -// rep.fileVisited(f0.toNIO) - } + for (f <- sources) rep.fileVisited(f.toNIO) rep.finish() } previousScalaColor match { From ec853af1af3e88a1d509d6824ac11105cc596edf Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Wed, 29 Oct 2025 13:18:20 +0800 Subject: [PATCH 05/33] . --- runner/meta/src/mill/meta/CodeGen.scala | 2 -- runner/meta/src/mill/meta/MillBuildRootModule.scala | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/runner/meta/src/mill/meta/CodeGen.scala b/runner/meta/src/mill/meta/CodeGen.scala index d1dbe52682bc..4140d146319d 100644 --- a/runner/meta/src/mill/meta/CodeGen.scala +++ b/runner/meta/src/mill/meta/CodeGen.scala @@ -83,8 +83,6 @@ object CodeGen { val markerComment = s"///SOURCE_CODE_START:$scriptPath" + strippedPackageStatementComment - - val siblingScripts = scriptSources .filter(_ != scriptPath) .filter(p => (p / os.up) == (scriptPath / os.up)) diff --git a/runner/meta/src/mill/meta/MillBuildRootModule.scala b/runner/meta/src/mill/meta/MillBuildRootModule.scala index 08021910d8fc..69354baf4214 100644 --- a/runner/meta/src/mill/meta/MillBuildRootModule.scala +++ b/runner/meta/src/mill/meta/MillBuildRootModule.scala @@ -39,7 +39,7 @@ trait MillBuildRootModule()(using override def moduleDir: os.Path = rootModuleInfo.projectRoot / os.up / millBuild private[mill] override def intellijModulePathJava: Path = (moduleDir / os.up).toNIO - override def scalaVersion: T[String] = BuildInfo.scalaVersion + override def scalaVersion: T[String] = "3.7.4-RC2" val scriptSourcesPaths = BuildCtx.watchValue { BuildCtx.withFilesystemCheckerDisabled { @@ -248,7 +248,7 @@ trait MillBuildRootModule()(using ) override def scalacPluginMvnDeps: T[Seq[Dep]] = Seq( - mvn"com.lihaoyi:::scalac-mill-moduledefs-plugin:${Versions.millModuledefsVersion}" + mvn"com.lihaoyi:scalac-mill-moduledefs-plugin_3.7.3:${Versions.millModuledefsVersion}" .exclude("com.lihaoyi" -> "sourcecode_3") ) From 24b8f12dcc4fe34455d9c9085c7f034f1fd75b39 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Wed, 29 Oct 2025 14:52:15 +0800 Subject: [PATCH 06/33] . --- runner/meta/src/mill/meta/CodeGen.scala | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/runner/meta/src/mill/meta/CodeGen.scala b/runner/meta/src/mill/meta/CodeGen.scala index 4140d146319d..840fda7dc493 100644 --- a/runner/meta/src/mill/meta/CodeGen.scala +++ b/runner/meta/src/mill/meta/CodeGen.scala @@ -347,6 +347,7 @@ object CodeGen { case None => () } + var generatedStub: String = "" newScriptCode = objectData.parent.applyTo( newScriptCode, if (objectData.parent.text == null) { @@ -366,14 +367,21 @@ object CodeGen { else ", " // no separator found, just use `,` by default } - newParent + sep + objectData.parent.text + val stub = "_MillRootModuleParents" + .take(objectData.parent.text.length) + .padTo(objectData.parent.text.length, ' ') + + generatedStub = s"class $stub extends $newParent$sep${objectData.parent.text}" + + stub } ) newScriptCode = objectData.name.applyTo(newScriptCode, CGConst.wrapperObjectName) - newScriptCode = objectData.obj.applyTo(newScriptCode, "abstract class") + newScriptCode = objectData.obj.applyTo(newScriptCode, "class") s"""$headerCode + |$generatedStub |$markerComment |$newScriptCode |""".stripMargin From 5262bcee0809526b60da629148119cfb9866cee6 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Wed, 29 Oct 2025 15:22:45 +0800 Subject: [PATCH 07/33] . --- .../src/RootModuleCompileErrorTests.scala | 124 +++++++++--------- runner/meta/src/mill/meta/CodeGen.scala | 15 +-- .../meta/src/mill/meta/FileImportGraph.scala | 8 +- 3 files changed, 67 insertions(+), 80 deletions(-) diff --git a/integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala b/integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala index 84c4f4200dc3..fdf97c363b11 100644 --- a/integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala +++ b/integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala @@ -12,71 +12,67 @@ object RootModuleCompileErrorTests extends UtestIntegrationTestSuite { assert(!res.isSuccess) - locally { - // For now these error messages still show generated/mangled code; not ideal, but it'll do - assert(res.err.contains("""build.mill:7:67""")) - assert(res.err.contains("""Not found: type UnknownRootModule""")) - assert(res.err.contains( - """abstract class package_ extends _root_.mill.util.MainRootModule, UnknownRootModule {""" - )) - assert( - res.err.contains(""" ^^^^^^^^^^^^^^^^^""") - ) - } - - locally { - // For now these error messages still show generated/mangled code; not ideal, but it'll do - assert(res.err.replace('\\', '/').contains("""foo/package.mill:6:96""")) - assert(res.err.contains("""Not found: type UnknownFooModule""")) - assert(res.err.contains( - """abstract class package_ extends _root_.mill.api.internal.SubfolderModule(build.millDiscover), UnknownFooModule {""" - )) - assert(res.err.contains( - """ ^^^^^^^^^^^^^^^^""" - )) - } - - locally { - assert(res.err.contains("""build.mill:8:22""")) - assert(res.err.contains("""Not found: unknownRootInternalDef""")) - assert(res.err.contains("""def scalaVersion = unknownRootInternalDef""")) - assert(res.err.contains(""" ^^^^^^^^^^^^^^^^^^^^^^""")) - } - - locally { - assert(res.err.contains("""build.mill:5:23""")) - assert(res.err.contains("""Not found: type UnknownBeforeModule""")) - assert(res.err.contains("""object before extends UnknownBeforeModule""")) - assert(res.err.contains(""" ^^^^^^^^^^^^^^^^^^^""")) - } + val normalizedError = res.err + .replace(workspacePath.toString, "") + .linesIterator + .filter(_.startsWith("[error] ")) + .toVector - locally { - assert(res.err.contains("""build.mill:12:22""")) - assert(res.err.contains("""Not found: type UnknownAfterModule""")) - assert(res.err.contains("""object after extends UnknownAfterModule""")) - assert(res.err.contains(""" ^^^^^^^^^^^^^^^^^^""")) - } - - locally { - assert(res.err.replace('\\', '/').contains("""foo/package.mill:7:22""")) - assert(res.err.contains("""Not found: unknownFooInternalDef""")) - assert(res.err.contains("""def scalaVersion = unknownFooInternalDef""")) - assert(res.err.contains(""" ^^^^^^^^^^^^^^^^^^^^^""")) - } - - locally { - assert(res.err.replace('\\', '/').contains("""foo/package.mill:4:23""")) - assert(res.err.contains("""Not found: type UnknownBeforeFooModule""")) - assert(res.err.contains("""object before extends UnknownBeforeFooModule""")) - assert(res.err.contains(""" ^^^^^^^^^^^^^^^^^^^^^^""")) - } - - locally { - assert(res.err.replace('\\', '/').contains("""foo/package.mill:11:22""")) - assert(res.err.contains("""Not found: type UnknownAfterFooModule""")) - assert(res.err.contains("""object after extends UnknownAfterFooModule""")) - assert(res.err.contains(""" ^^^^^^^^^^^^^^^^^^^^^""")) - } + // For now some error messages still show generated/mangled code; not ideal, but it'll do + assertGoldenLiteral( + normalizedError, + Vector( + "[error] -- [E006] Not Found Error: /out/mill-build/generatedScriptSources.dest/wrapped/build_/build.mill:17:65 ", + "[error] 17 |class _MillRootModulePa extends _root_.mill.util.MainRootModule, UnknownRootModule", + "[error] | ^^^^^^^^^^^^^^^^^", + "[error] | Not found: type UnknownRootModule", + "[error] |", + "[error] | longer explanation available when compiling with `-explain`", + "[error] -- [E006] Not Found Error: /out/mill-build/generatedScriptSources.dest/wrapped/build_/foo/package.mill:17:93 ", + "[error] 17 |class _MillRootModuleP extends _root_.mill.api.internal.SubfolderModule(build.millDiscover), UnknownFooModule", + "[error] | ^^^^^^^^^^^^^^^^", + "[error] | Not found: type UnknownFooModule", + "[error] |", + "[error] | longer explanation available when compiling with `-explain`", + "[error] -- [E006] Not Found Error: /build.mill:5:22 ", + "[error] 5 |object before extends UnknownBeforeModule", + "[error] | ^^^^^^^^^^^^^^^^^^^", + "[error] | Not found: type UnknownBeforeModule", + "[error] |", + "[error] | longer explanation available when compiling with `-explain`", + "[error] -- [E006] Not Found Error: /build.mill:8:21 ", + "[error] 8 | def scalaVersion = unknownRootInternalDef", + "[error] | ^^^^^^^^^^^^^^^^^^^^^^", + "[error] | Not found: unknownRootInternalDef", + "[error] |", + "[error] | longer explanation available when compiling with `-explain`", + "[error] -- [E006] Not Found Error: /build.mill:11:21 ", + "[error] 11 |object after extends UnknownAfterModule", + "[error] | ^^^^^^^^^^^^^^^^^^", + "[error] | Not found: type UnknownAfterModule", + "[error] |", + "[error] | longer explanation available when compiling with `-explain`", + "[error] -- [E006] Not Found Error: /foo/package.mill:4:22 ", + "[error] 4 |object before extends UnknownBeforeFooModule", + "[error] | ^^^^^^^^^^^^^^^^^^^^^^", + "[error] | Not found: type UnknownBeforeFooModule", + "[error] |", + "[error] | longer explanation available when compiling with `-explain`", + "[error] -- [E006] Not Found Error: /foo/package.mill:7:21 ", + "[error] 7 | def scalaVersion = unknownFooInternalDef", + "[error] | ^^^^^^^^^^^^^^^^^^^^^", + "[error] | Not found: unknownFooInternalDef", + "[error] |", + "[error] | longer explanation available when compiling with `-explain`", + "[error] -- [E006] Not Found Error: /foo/package.mill:10:21 ", + "[error] 10 |object after extends UnknownAfterFooModule", + "[error] | ^^^^^^^^^^^^^^^^^^^^^", + "[error] | Not found: type UnknownAfterFooModule", + "[error] |", + "[error] | longer explanation available when compiling with `-explain`", + "[error] 8 errors found" + ) + ) } } } diff --git a/runner/meta/src/mill/meta/CodeGen.scala b/runner/meta/src/mill/meta/CodeGen.scala index 840fda7dc493..dce96bd695fc 100644 --- a/runner/meta/src/mill/meta/CodeGen.scala +++ b/runner/meta/src/mill/meta/CodeGen.scala @@ -30,7 +30,7 @@ object CodeGen { // Provide `build` as an alias to the root `build_.package_`, since from the user's // perspective it looks like they're writing things that live in `package build`, // but at compile-time we rename things, we so provide an alias to preserve the fiction - val aliasImports = "import build_.{package_ => build}" + for (scriptPath <- scriptSources) { val scriptFolderPath = scriptPath / os.up @@ -336,16 +336,6 @@ object CodeGen { case None => () } - objectData.finalStat match { - case Some((_, finalStat)) => - val statLines = finalStat.text.linesWithSeparators.toSeq - val fenced = Seq( - "", - if statLines.sizeIs > 1 then statLines.tail.mkString else finalStat.text - ).mkString(System.lineSeparator()) - newScriptCode = finalStat.applyTo(newScriptCode, fenced) - case None => () - } var generatedStub: String = "" newScriptCode = objectData.parent.applyTo( @@ -382,8 +372,7 @@ object CodeGen { s"""$headerCode |$generatedStub - |$markerComment - |$newScriptCode + |$markerComment$newScriptCode |""".stripMargin case None => diff --git a/runner/meta/src/mill/meta/FileImportGraph.scala b/runner/meta/src/mill/meta/FileImportGraph.scala index 62aeaf14d6a8..6e066a74a243 100644 --- a/runner/meta/src/mill/meta/FileImportGraph.scala +++ b/runner/meta/src/mill/meta/FileImportGraph.scala @@ -17,9 +17,11 @@ import mill.internal.Util.backtickWrap * @param metaBuild If `true`, a meta-build is enabled */ @internal -case class FileImportGraph(seenScripts: Map[os.Path, String], - errors: Seq[String], - seenPkgStatements: Map[os.Path, String]) +case class FileImportGraph( + seenScripts: Map[os.Path, String], + errors: Seq[String], + seenPkgStatements: Map[os.Path, String] +) /** * Logic around traversing the `import $file` graph, extracting necessary info From dce77b00c7d50bc06a5564a659255ebfa53c767d Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Wed, 29 Oct 2025 15:31:58 +0800 Subject: [PATCH 08/33] . --- runner/meta/src/mill/meta/CodeGen.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/runner/meta/src/mill/meta/CodeGen.scala b/runner/meta/src/mill/meta/CodeGen.scala index dce96bd695fc..04de77837e8a 100644 --- a/runner/meta/src/mill/meta/CodeGen.scala +++ b/runner/meta/src/mill/meta/CodeGen.scala @@ -30,7 +30,6 @@ object CodeGen { // Provide `build` as an alias to the root `build_.package_`, since from the user's // perspective it looks like they're writing things that live in `package build`, // but at compile-time we rename things, we so provide an alias to preserve the fiction - for (scriptPath <- scriptSources) { val scriptFolderPath = scriptPath / os.up From 1ae0abe1bc3a69da71253cb491a092ac9c0bf8d1 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Wed, 29 Oct 2025 15:41:13 +0800 Subject: [PATCH 09/33] . --- runner/daemon/src/mill/daemon/MillScalaParserImpl.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/runner/daemon/src/mill/daemon/MillScalaParserImpl.scala b/runner/daemon/src/mill/daemon/MillScalaParserImpl.scala index cd0eb7aa8719..dc76e7b70078 100644 --- a/runner/daemon/src/mill/daemon/MillScalaParserImpl.scala +++ b/runner/daemon/src/mill/daemon/MillScalaParserImpl.scala @@ -35,7 +35,6 @@ object MillScalaParserImpl extends MillScalaParser { rawCode: String, fileName: String ): Either[String, (String, Seq[String], Seq[String])] = { - mill.constants.DebugLog.println("rawCode " + pprint.apply(rawCode)) val source = SourceFile.virtual(fileName, rawCode) def mergeErrors(errors: List[String]): String = s"$fileName failed to parse:" + System.lineSeparator + errors.mkString(System.lineSeparator) From 0a82f2c752041208155d17e0f6022e342bcf8a5a Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Wed, 29 Oct 2025 16:01:09 +0800 Subject: [PATCH 10/33] . --- .../src/RootModuleCompileErrorTests.scala | 12 ++++++------ runner/meta/src/mill/meta/CodeGen.scala | 4 +++- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala b/integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala index fdf97c363b11..1176afd37629 100644 --- a/integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala +++ b/integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala @@ -22,15 +22,15 @@ object RootModuleCompileErrorTests extends UtestIntegrationTestSuite { assertGoldenLiteral( normalizedError, Vector( - "[error] -- [E006] Not Found Error: /out/mill-build/generatedScriptSources.dest/wrapped/build_/build.mill:17:65 ", - "[error] 17 |class _MillRootModulePa extends _root_.mill.util.MainRootModule, UnknownRootModule", - "[error] | ^^^^^^^^^^^^^^^^^", + "[error] -- [E006] Not Found Error: /build.mill:12:66 ", + "[error] 12 |", + "[error] | ^^^^^^^^^^^^^^^^^", "[error] | Not found: type UnknownRootModule", "[error] |", "[error] | longer explanation available when compiling with `-explain`", - "[error] -- [E006] Not Found Error: /out/mill-build/generatedScriptSources.dest/wrapped/build_/foo/package.mill:17:93 ", - "[error] 17 |class _MillRootModuleP extends _root_.mill.api.internal.SubfolderModule(build.millDiscover), UnknownFooModule", - "[error] | ^^^^^^^^^^^^^^^^", + "[error] -- [E006] Not Found Error: /foo/package.mill:11:94 ", + "[error] 11 |", + "[error] | ^^^^^^^^^^^^^^^^", "[error] | Not found: type UnknownFooModule", "[error] |", "[error] | longer explanation available when compiling with `-explain`", diff --git a/runner/meta/src/mill/meta/CodeGen.scala b/runner/meta/src/mill/meta/CodeGen.scala index 04de77837e8a..b80bb3a3962d 100644 --- a/runner/meta/src/mill/meta/CodeGen.scala +++ b/runner/meta/src/mill/meta/CodeGen.scala @@ -370,8 +370,10 @@ object CodeGen { newScriptCode = objectData.obj.applyTo(newScriptCode, "class") s"""$headerCode - |$generatedStub + | |$markerComment$newScriptCode + | + |$generatedStub |""".stripMargin case None => From 8c33c8a8c7a4c170f860c658686acc0e5e5705be Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Wed, 29 Oct 2025 17:28:52 +0800 Subject: [PATCH 11/33] . --- runner/meta/src/mill/meta/CodeGen.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runner/meta/src/mill/meta/CodeGen.scala b/runner/meta/src/mill/meta/CodeGen.scala index b80bb3a3962d..10e4c865e3c0 100644 --- a/runner/meta/src/mill/meta/CodeGen.scala +++ b/runner/meta/src/mill/meta/CodeGen.scala @@ -360,7 +360,7 @@ object CodeGen { .take(objectData.parent.text.length) .padTo(objectData.parent.text.length, ' ') - generatedStub = s"class $stub extends $newParent$sep${objectData.parent.text}" + generatedStub = s"trait $stub extends $newParent$sep${objectData.parent.text}" stub } From e18de7343149f51a56b4294d3990a0a6cfa20588 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Wed, 29 Oct 2025 17:57:07 +0800 Subject: [PATCH 12/33] . --- runner/meta/src/mill/meta/CodeGen.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runner/meta/src/mill/meta/CodeGen.scala b/runner/meta/src/mill/meta/CodeGen.scala index 10e4c865e3c0..36bd82006572 100644 --- a/runner/meta/src/mill/meta/CodeGen.scala +++ b/runner/meta/src/mill/meta/CodeGen.scala @@ -76,8 +76,8 @@ object CodeGen { val strippedPackageStatementComment = allPackageStatements.get(scriptPath) match { // Add another comment after the marker comment to substitute any package statement // that was stripped during codegen and ensure the offsets line up properly + case None || Some("") => "" case Some(s) => "\n//" + s.drop(2) - case None => "" } val markerComment = s"///SOURCE_CODE_START:$scriptPath" + strippedPackageStatementComment From 531939d8830102adf14e5edf7628c31f82525992 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Wed, 29 Oct 2025 17:57:11 +0800 Subject: [PATCH 13/33] . --- runner/meta/src/mill/meta/CodeGen.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runner/meta/src/mill/meta/CodeGen.scala b/runner/meta/src/mill/meta/CodeGen.scala index 36bd82006572..0afba3ad0c80 100644 --- a/runner/meta/src/mill/meta/CodeGen.scala +++ b/runner/meta/src/mill/meta/CodeGen.scala @@ -76,7 +76,7 @@ object CodeGen { val strippedPackageStatementComment = allPackageStatements.get(scriptPath) match { // Add another comment after the marker comment to substitute any package statement // that was stripped during codegen and ensure the offsets line up properly - case None || Some("") => "" + case None | Some("") => "" case Some(s) => "\n//" + s.drop(2) } From 6349cd06d223df24e5fa971a428f2852e4ba2218 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Wed, 29 Oct 2025 18:01:49 +0800 Subject: [PATCH 14/33] . --- runner/meta/src/mill/meta/CodeGen.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/runner/meta/src/mill/meta/CodeGen.scala b/runner/meta/src/mill/meta/CodeGen.scala index 0afba3ad0c80..feaeef925aca 100644 --- a/runner/meta/src/mill/meta/CodeGen.scala +++ b/runner/meta/src/mill/meta/CodeGen.scala @@ -76,7 +76,8 @@ object CodeGen { val strippedPackageStatementComment = allPackageStatements.get(scriptPath) match { // Add another comment after the marker comment to substitute any package statement // that was stripped during codegen and ensure the offsets line up properly - case None | Some("") => "" + case None => "" + case Some("") => "\n" case Some(s) => "\n//" + s.drop(2) } From 3e1ff4df05e0e88e86d5df0f27d56194ca1dbd88 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Wed, 29 Oct 2025 18:05:26 +0800 Subject: [PATCH 15/33] . --- runner/meta/src/mill/meta/CodeGen.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/runner/meta/src/mill/meta/CodeGen.scala b/runner/meta/src/mill/meta/CodeGen.scala index feaeef925aca..d6e9cd2d5434 100644 --- a/runner/meta/src/mill/meta/CodeGen.scala +++ b/runner/meta/src/mill/meta/CodeGen.scala @@ -76,8 +76,7 @@ object CodeGen { val strippedPackageStatementComment = allPackageStatements.get(scriptPath) match { // Add another comment after the marker comment to substitute any package statement // that was stripped during codegen and ensure the offsets line up properly - case None => "" - case Some("") => "\n" + case None => "\n" case Some(s) => "\n//" + s.drop(2) } From c58f23734648d9767d9e9c7b78901c9dfe304168 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Wed, 29 Oct 2025 18:14:38 +0800 Subject: [PATCH 16/33] . --- runner/meta/src/mill/meta/CodeGen.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runner/meta/src/mill/meta/CodeGen.scala b/runner/meta/src/mill/meta/CodeGen.scala index d6e9cd2d5434..ed06d2218318 100644 --- a/runner/meta/src/mill/meta/CodeGen.scala +++ b/runner/meta/src/mill/meta/CodeGen.scala @@ -76,7 +76,7 @@ object CodeGen { val strippedPackageStatementComment = allPackageStatements.get(scriptPath) match { // Add another comment after the marker comment to substitute any package statement // that was stripped during codegen and ensure the offsets line up properly - case None => "\n" + case Some("package ") => "\n//" + s.drop(2) case Some(s) => "\n//" + s.drop(2) } From 058f52cecea0e4fdf22ef6d8f2b72c7da95ca87b Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Wed, 29 Oct 2025 18:15:56 +0800 Subject: [PATCH 17/33] . --- runner/meta/src/mill/meta/CodeGen.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runner/meta/src/mill/meta/CodeGen.scala b/runner/meta/src/mill/meta/CodeGen.scala index ed06d2218318..d616f63c3d23 100644 --- a/runner/meta/src/mill/meta/CodeGen.scala +++ b/runner/meta/src/mill/meta/CodeGen.scala @@ -76,7 +76,7 @@ object CodeGen { val strippedPackageStatementComment = allPackageStatements.get(scriptPath) match { // Add another comment after the marker comment to substitute any package statement // that was stripped during codegen and ensure the offsets line up properly - case Some("package ") => "\n//" + s.drop(2) + case Some("package ") => "\n" case Some(s) => "\n//" + s.drop(2) } From 68effe9a9410469b4b3496d24d16c992024ccb8f Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Wed, 29 Oct 2025 18:21:50 +0800 Subject: [PATCH 18/33] . --- runner/meta/src/mill/meta/CodeGen.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runner/meta/src/mill/meta/CodeGen.scala b/runner/meta/src/mill/meta/CodeGen.scala index d616f63c3d23..b7a4918d9225 100644 --- a/runner/meta/src/mill/meta/CodeGen.scala +++ b/runner/meta/src/mill/meta/CodeGen.scala @@ -360,7 +360,7 @@ object CodeGen { .take(objectData.parent.text.length) .padTo(objectData.parent.text.length, ' ') - generatedStub = s"trait $stub extends $newParent$sep${objectData.parent.text}" + generatedStub = s"abstract class $stub extends $newParent$sep${objectData.parent.text}" stub } From 03832a51132149a086da84894885eccdef8d596c Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Wed, 29 Oct 2025 18:25:17 +0800 Subject: [PATCH 19/33] . --- runner/meta/src/mill/meta/CodeGen.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/runner/meta/src/mill/meta/CodeGen.scala b/runner/meta/src/mill/meta/CodeGen.scala index b7a4918d9225..79072ceabbb3 100644 --- a/runner/meta/src/mill/meta/CodeGen.scala +++ b/runner/meta/src/mill/meta/CodeGen.scala @@ -76,6 +76,7 @@ object CodeGen { val strippedPackageStatementComment = allPackageStatements.get(scriptPath) match { // Add another comment after the marker comment to substitute any package statement // that was stripped during codegen and ensure the offsets line up properly + case None => "\n" case Some("package ") => "\n" case Some(s) => "\n//" + s.drop(2) } From 1388ac7821c0aae3f2736b85fa47aa79218f2ff7 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Wed, 29 Oct 2025 19:54:53 +0800 Subject: [PATCH 20/33] . --- runner/meta/src/mill/meta/CodeGen.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runner/meta/src/mill/meta/CodeGen.scala b/runner/meta/src/mill/meta/CodeGen.scala index 79072ceabbb3..14b256481ef5 100644 --- a/runner/meta/src/mill/meta/CodeGen.scala +++ b/runner/meta/src/mill/meta/CodeGen.scala @@ -375,7 +375,7 @@ object CodeGen { |$markerComment$newScriptCode | |$generatedStub - |""".stripMargin + |""".stripMargin.replaceAll("\r\n", "\n") case None => s"""$headerCode @@ -383,7 +383,7 @@ object CodeGen { | extends $newParent { this: ${CGConst.wrapperObjectName}.type => |$markerComment |$scriptCode - |}""".stripMargin + |}""".stripMargin.replaceAll("\r\n", "\n") } } From a35bf1cb9439e4e7d0aa4c9c7bd2915db32adf4e Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Wed, 29 Oct 2025 20:22:52 +0800 Subject: [PATCH 21/33] . --- .../src/RootModuleCompileErrorTests.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala b/integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala index 1176afd37629..a3c20ed63fd3 100644 --- a/integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala +++ b/integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala @@ -17,6 +17,7 @@ object RootModuleCompileErrorTests extends UtestIntegrationTestSuite { .linesIterator .filter(_.startsWith("[error] ")) .toVector + .map(_.replace('\\', '/')) // For now some error messages still show generated/mangled code; not ideal, but it'll do assertGoldenLiteral( From 219d9a5057b48eb529b1e62dc0f030e418281508 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Wed, 29 Oct 2025 20:26:29 +0800 Subject: [PATCH 22/33] . --- .../src/RootModuleCompileErrorTests.scala | 22 +++---------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala b/integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala index a3c20ed63fd3..d24cf8fa67f9 100644 --- a/integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala +++ b/integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala @@ -15,7 +15,7 @@ object RootModuleCompileErrorTests extends UtestIntegrationTestSuite { val normalizedError = res.err .replace(workspacePath.toString, "") .linesIterator - .filter(_.startsWith("[error] ")) + .filter(s => s.startsWith("[error] ") && !s.contains("| ")) .toVector .map(_.replace('\\', '/')) @@ -23,52 +23,36 @@ object RootModuleCompileErrorTests extends UtestIntegrationTestSuite { assertGoldenLiteral( normalizedError, Vector( - "[error] -- [E006] Not Found Error: /build.mill:12:66 ", + "[error] -- [E006] Not Found Error: /build.mill:12:75 ", "[error] 12 |", - "[error] | ^^^^^^^^^^^^^^^^^", - "[error] | Not found: type UnknownRootModule", "[error] |", "[error] | longer explanation available when compiling with `-explain`", - "[error] -- [E006] Not Found Error: /foo/package.mill:11:94 ", + "[error] -- [E006] Not Found Error: /foo/package.mill:11:103 ", "[error] 11 |", - "[error] | ^^^^^^^^^^^^^^^^", - "[error] | Not found: type UnknownFooModule", "[error] |", "[error] | longer explanation available when compiling with `-explain`", "[error] -- [E006] Not Found Error: /build.mill:5:22 ", "[error] 5 |object before extends UnknownBeforeModule", - "[error] | ^^^^^^^^^^^^^^^^^^^", - "[error] | Not found: type UnknownBeforeModule", "[error] |", "[error] | longer explanation available when compiling with `-explain`", "[error] -- [E006] Not Found Error: /build.mill:8:21 ", "[error] 8 | def scalaVersion = unknownRootInternalDef", - "[error] | ^^^^^^^^^^^^^^^^^^^^^^", - "[error] | Not found: unknownRootInternalDef", "[error] |", "[error] | longer explanation available when compiling with `-explain`", "[error] -- [E006] Not Found Error: /build.mill:11:21 ", "[error] 11 |object after extends UnknownAfterModule", - "[error] | ^^^^^^^^^^^^^^^^^^", - "[error] | Not found: type UnknownAfterModule", "[error] |", "[error] | longer explanation available when compiling with `-explain`", "[error] -- [E006] Not Found Error: /foo/package.mill:4:22 ", "[error] 4 |object before extends UnknownBeforeFooModule", - "[error] | ^^^^^^^^^^^^^^^^^^^^^^", - "[error] | Not found: type UnknownBeforeFooModule", "[error] |", "[error] | longer explanation available when compiling with `-explain`", "[error] -- [E006] Not Found Error: /foo/package.mill:7:21 ", "[error] 7 | def scalaVersion = unknownFooInternalDef", - "[error] | ^^^^^^^^^^^^^^^^^^^^^", - "[error] | Not found: unknownFooInternalDef", "[error] |", "[error] | longer explanation available when compiling with `-explain`", "[error] -- [E006] Not Found Error: /foo/package.mill:10:21 ", "[error] 10 |object after extends UnknownAfterFooModule", - "[error] | ^^^^^^^^^^^^^^^^^^^^^", - "[error] | Not found: type UnknownAfterFooModule", "[error] |", "[error] | longer explanation available when compiling with `-explain`", "[error] 8 errors found" From 53cf9c3aded7eb3be6a6d0980f66ef9800f56421 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Wed, 29 Oct 2025 21:38:06 +0800 Subject: [PATCH 23/33] . --- runner/meta/src/mill/meta/CodeGen.scala | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/runner/meta/src/mill/meta/CodeGen.scala b/runner/meta/src/mill/meta/CodeGen.scala index 14b256481ef5..6287d4c55e09 100644 --- a/runner/meta/src/mill/meta/CodeGen.scala +++ b/runner/meta/src/mill/meta/CodeGen.scala @@ -120,7 +120,7 @@ object CodeGen { val prelude = s"""|import MillMiscInfo._ |import _root_.mill.util.TokenReaders.given - |""".stripMargin + |""".stripMargin.replaceAll("\r\n", "\n") os.write.over(supportDestDir / "MillMiscInfo.scala", miscInfo, createFolders = true) @@ -161,7 +161,7 @@ object CodeGen { | $runModuleDepsSnippet | ${definitions.mkString("\n ")} |} - |""".stripMargin + |""".stripMargin.replaceAll("\r\n", "\n") } os.write.over( @@ -176,7 +176,7 @@ object CodeGen { | $childAliases |} |${renderTemplate("trait package_", parsedHeaderData)} - |""".stripMargin, + |""".stripMargin.replaceAll("\r\n", "\n"), createFolders = true ) @@ -219,7 +219,7 @@ object CodeGen { |} | |export $wrapperName._ - |""".stripMargin + |""".stripMargin.replaceAll("\r\n", "\n") } else { generateBuildScript( projectRoot = projectRoot, @@ -266,7 +266,7 @@ object CodeGen { |$header | |$body - |""".stripMargin + |""".stripMargin.replaceAll("\r\n", "\n") } def generateBuildFileImpl(pkg: String) = { @@ -274,7 +274,7 @@ object CodeGen { |package $pkg | |object BuildFileImpl extends mill.api.internal.BuildFileCls(${CGConst.wrapperObjectName}) - |""".stripMargin + |""".stripMargin.replaceAll("\r\n", "\n") } private def generateBuildScript( @@ -300,7 +300,7 @@ object CodeGen { s"""|import MillMiscInfo._ |import _root_.mill.util.TokenReaders.given |import _root_.mill.api.JsonFormatters.given - |""".stripMargin + |""".stripMargin.replaceAll("\r\n", "\n") val objectData = parser.parseObjectData(scriptCode) @@ -320,7 +320,7 @@ object CodeGen { | ${exportSiblingScripts.linesWithSeparators.mkString(" ")} | ${millDiscover(segments.nonEmpty)} |} - |""".stripMargin + |""".stripMargin.replaceAll("\r\n", "\n") val newParent = if (segments.isEmpty) "_root_.mill.util.MainRootModule" @@ -397,7 +397,7 @@ object CodeGen { | millSourcePath0 = os.Path(${literalize(scriptFolderPath.toString)}), | segments = _root_.scala.Seq(${segments.map(pprint.Util.literalize(_)).mkString(", ")}) |) - |""".stripMargin + |""".stripMargin.replaceAll("\r\n", "\n") } def millDiscover(segmentsNonEmpty: Boolean): String = { @@ -420,7 +420,7 @@ object CodeGen { | output0 = ${literalize(output.toString)}, | topLevelProjectRoot0 = ${literalize(millTopLevelProjectRoot.toString)} |) - |""".stripMargin + |""".stripMargin.replaceAll("\r\n", "\n") } } From 90bead662e57ef4f2049b8c4b0ab0351fedef599 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Wed, 29 Oct 2025 22:12:35 +0800 Subject: [PATCH 24/33] . --- runner/meta/src/mill/meta/CodeGen.scala | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/runner/meta/src/mill/meta/CodeGen.scala b/runner/meta/src/mill/meta/CodeGen.scala index 6287d4c55e09..d584150ab493 100644 --- a/runner/meta/src/mill/meta/CodeGen.scala +++ b/runner/meta/src/mill/meta/CodeGen.scala @@ -161,7 +161,7 @@ object CodeGen { | $runModuleDepsSnippet | ${definitions.mkString("\n ")} |} - |""".stripMargin.replaceAll("\r\n", "\n") + |""".stripMargin } os.write.over( @@ -176,7 +176,7 @@ object CodeGen { | $childAliases |} |${renderTemplate("trait package_", parsedHeaderData)} - |""".stripMargin.replaceAll("\r\n", "\n"), + |""".stripMargin, createFolders = true ) @@ -219,7 +219,7 @@ object CodeGen { |} | |export $wrapperName._ - |""".stripMargin.replaceAll("\r\n", "\n") + |""".stripMargin } else { generateBuildScript( projectRoot = projectRoot, @@ -266,7 +266,7 @@ object CodeGen { |$header | |$body - |""".stripMargin.replaceAll("\r\n", "\n") + |""".stripMargin } def generateBuildFileImpl(pkg: String) = { @@ -274,7 +274,7 @@ object CodeGen { |package $pkg | |object BuildFileImpl extends mill.api.internal.BuildFileCls(${CGConst.wrapperObjectName}) - |""".stripMargin.replaceAll("\r\n", "\n") + |""".stripMargin } private def generateBuildScript( @@ -300,7 +300,7 @@ object CodeGen { s"""|import MillMiscInfo._ |import _root_.mill.util.TokenReaders.given |import _root_.mill.api.JsonFormatters.given - |""".stripMargin.replaceAll("\r\n", "\n") + |""".stripMargin val objectData = parser.parseObjectData(scriptCode) @@ -320,7 +320,7 @@ object CodeGen { | ${exportSiblingScripts.linesWithSeparators.mkString(" ")} | ${millDiscover(segments.nonEmpty)} |} - |""".stripMargin.replaceAll("\r\n", "\n") + |""".stripMargin val newParent = if (segments.isEmpty) "_root_.mill.util.MainRootModule" @@ -375,7 +375,7 @@ object CodeGen { |$markerComment$newScriptCode | |$generatedStub - |""".stripMargin.replaceAll("\r\n", "\n") + |""".stripMargin case None => s"""$headerCode @@ -383,7 +383,7 @@ object CodeGen { | extends $newParent { this: ${CGConst.wrapperObjectName}.type => |$markerComment |$scriptCode - |}""".stripMargin.replaceAll("\r\n", "\n") + |}""".stripMargin } } @@ -397,7 +397,7 @@ object CodeGen { | millSourcePath0 = os.Path(${literalize(scriptFolderPath.toString)}), | segments = _root_.scala.Seq(${segments.map(pprint.Util.literalize(_)).mkString(", ")}) |) - |""".stripMargin.replaceAll("\r\n", "\n") + |""".stripMargin } def millDiscover(segmentsNonEmpty: Boolean): String = { @@ -420,7 +420,7 @@ object CodeGen { | output0 = ${literalize(output.toString)}, | topLevelProjectRoot0 = ${literalize(millTopLevelProjectRoot.toString)} |) - |""".stripMargin.replaceAll("\r\n", "\n") + |""".stripMargin } } From bbd2964a30c5aed68b1ab36c1a3a30f25a452bb4 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Thu, 30 Oct 2025 08:30:37 +0800 Subject: [PATCH 25/33] . --- runner/meta/src/mill/meta/CodeGen.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runner/meta/src/mill/meta/CodeGen.scala b/runner/meta/src/mill/meta/CodeGen.scala index d584150ab493..243e3b0e917b 100644 --- a/runner/meta/src/mill/meta/CodeGen.scala +++ b/runner/meta/src/mill/meta/CodeGen.scala @@ -120,7 +120,7 @@ object CodeGen { val prelude = s"""|import MillMiscInfo._ |import _root_.mill.util.TokenReaders.given - |""".stripMargin.replaceAll("\r\n", "\n") + |""" os.write.over(supportDestDir / "MillMiscInfo.scala", miscInfo, createFolders = true) From 27207844c87ea98506ec0b5649edbbb43bc471c6 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Thu, 30 Oct 2025 08:35:46 +0800 Subject: [PATCH 26/33] . --- .github/workflows/run-tests.yml | 476 ++++++++++++++++---------------- 1 file changed, 238 insertions(+), 238 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index b8b7274b8ae7..df4ec5671c04 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -1,262 +1,262 @@ # Uncommment this to replace the rest of the file when you want to debug stuff in CI -#name: Run Debug -# -#on: -# push: -# pull_request: -# workflow_dispatch: -# -#jobs: -# debug: -# runs-on: ubuntu-latest -## runs-on: windows-latest -# steps: -# - uses: actions/checkout@v5 -# with: { fetch-depth: 1 } -# -# - run: "echo temurin:11 > .mill-jvm-version" -# -# - uses: sbt/setup-sbt@v1 -# -# -# - run: ./mill 'integration.migrating[init].local.daemon.testOnly' mill.integration.MillInitSbtGatlingTests -# - - - -# We run full CI on push builds to main and on all pull requests -# -# To maximize bug-catching changes while keeping CI times reasonable, we run -# tests scattered between Java 11/17/24, across linux/mac/windows, intel/arm - - -name: Run Tests +name: Run Debug on: push: - branches-ignore: - - '**-patch-**' pull_request: - types: - - opened - - reopened - - synchronize - - ready_for_review workflow_dispatch: -# cancel older runs of a pull request; -# this will not cancel anything for normal git pushes -concurrency: - # * For runs on other repos, always use the `ref_name` so each branch only can have one concurrent run - # * For runs on `com-lihaoyi/mill`, use `head_ref` to allow one concurrent run per PR, but `run_id` to - # allow multiple concurrent runs in master - group: cancel-old-pr-runs-${{ github.workflow }}-${{ (github.repository != 'com-lihaoyi/mill' && github.ref_name) || (github.head_ref || github.run_id) }} - cancel-in-progress: true - jobs: - # Jobs are listed in rough order of priority: if multiple jobs fail, the first job - # in the list should be the one that's most worth looking into - build-linux: - if: (github.event.action == 'ready_for_review') || (github.event.pull_request.draft == false) - uses: ./.github/workflows/pre-build.yml - with: - os: ubuntu-latest - shell: bash - - build-windows: - if: (github.event.action == 'ready_for_review') || (github.event.pull_request.draft == false) - uses: ./.github/workflows/pre-build.yml - with: - os: windows-latest - shell: powershell - - test-docs: - if: (github.event.action == 'ready_for_review') || (github.event.pull_request.draft == false) + debug: runs-on: ubuntu-latest +# runs-on: windows-latest steps: - uses: actions/checkout@v5 with: { fetch-depth: 1 } - - run: ./mill -i website.fastPages + website.checkBrokenLinks - - cross-plat: - if: (github.event.action == 'ready_for_review') || (github.event.pull_request.draft == false) - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - # Run these with Mill native launcher as a smoketest - include: - - os: ubuntu-24.04-arm - millargs: "'example.thirdparty[{mockito,netty,arrow}].native.daemon'" - java-version: 17 - - - os: macos-latest - millargs: "'example.thirdparty[{acyclic,fansi,gatling}].native.daemon'" - java-version: 11 - - - os: macos-13 - millargs: "'example.thirdparty[{jimfs,commons-io}].native.daemon'" - java-version: 24 - steps: - - uses: actions/checkout@v5 - with: { fetch-depth: 1 } - - - uses: ./.github/actions/pre-build-setup - with: - os: ${{ matrix.os }} - java-version: ${{ matrix.java-version }} - shell: bash - - - uses: ./.github/actions/post-build-setup - with: - java-version: ${{ matrix.java-version }} - os: ${{ matrix.os }} - - - uses: ./.github/actions/post-build-selective - with: - millargs: ${{ matrix.millargs }} - shell: bash - - linux: - needs: build-linux - strategy: - fail-fast: false - matrix: - - include: - # For most tests, run them arbitrarily on Java 11 or Java 17 on Linux, and - # on the opposite version on Windows below, so we get decent coverage of - # each test on each Java version and each operating system - # We also try to group tests together to manually balance out the runtimes of each jobs - - java-version: 17 - millargs: "'{contrib,core,testkit,runner,dist}.__.test'" - - - java-version: 17 - millargs: "'libs.{scalalib,init,tabcomplete}.__.test'" - install-sbt: true - - - java-version: 11 - millargs: "'libs.{scalajslib,scalanativelib,kotlinlib,pythonlib,javascriptlib}.__.test'" - - - java-version: 17 - millargs: "example.kotlinlib.__.local.daemon" - - - java-version: 11 - millargs: "example.scalalib.__.local.daemon" - - - java-version: 21 - millargs: "example.javalib.__.local.daemon" - - - java-version: 17 - millargs: "'example.androidlib.__.local.daemon'" - setup-android: true - - - java-version: 17 - millargs: "'example.thirdparty[androidtodo].packaged.daemon'" - setup-android: true - - - java-version: 24 - millargs: "'example.migrating.scalalib.__.local.daemon'" - install-sbt: true - - - java-version: 24 - millargs: "'example.{pythonlib,javascriptlib}.__.local.daemon'" - - - java-version: 21 - millargs: "'example.{cli,fundamentals,depth,extending,large}.__.local.daemon'" - - - java-version: 21 - millargs: "'integration.{feature,ide}.__.packaged.daemon'" - - # run this specifically in `native` mode to make sure our non-JVM native image - # launcher is able to bootstrap everything necessary without a JVM installed - - java-version: 17 - millargs: "'integration.bootstrap[no-java-bootstrap].native.daemon'" - - # These invalidation tests need to be exercised in both execution modes - # to make sure they work with and without -i/--no-server being passed - - java-version: 24 - millargs: "'integration.invalidation.__.packaged.nodaemon'" - - - java-version: 17 - millargs: "'integration.migrating.__.packaged.daemon'" - install-sbt: true - - uses: ./.github/workflows/post-build-selective.yml - with: - setup-android: ${{ matrix.setup-android || false }} - install-sbt: ${{ matrix.install-sbt || false }} - install-xvfb: ${{ matrix.install-xvfb || false }} - java-version: ${{ matrix.java-version }} - millargs: ${{ matrix.millargs }} - shell: bash + - run: "echo temurin:11 > .mill-jvm-version" - windows: - needs: build-windows - strategy: - fail-fast: false - matrix: - include: - - java-version: 24 - millargs: "'integration.invalidation.__.packaged.daemon'" + - uses: sbt/setup-sbt@v1 - - java-version: 11 - # turn of parallelism since it sometimes causes issues with concurrent migrations - millargs: '"example.migrating.javalib.__.packaged.daemon"' - extra: "--jobs=1" - - java-version: 11 - millargs: '"libs.{util,javalib,androidlib,graphviz}.__.test"' - - java-version: 17 - millargs: '"example.scalalib.{basic,publishing}.__.packaged.daemon"' + - run: ./mill 'integration.failure[compile-error].packaged.nodaemon' - - java-version: 17 - millargs: "'integration.failure.__.packaged.nodaemon'" - - java-version: 17 - millargs: "'integration.bootstrap[no-java-bootstrap].native.daemon'" - uses: ./.github/workflows/post-build-selective.yml - with: - os: windows-latest - java-version: ${{ matrix.java-version }} - millargs: ${{ matrix.millargs }} - extra: ${{ matrix.extra || '' }} - shell: powershell - itest: - needs: build-linux - strategy: - fail-fast: false - matrix: - include: - # bootstrap tests - - java-version: 11 - buildcmd: ci/test-dist-run.sh && ci/test-mill-bootstrap.sh +# We run full CI on push builds to main and on all pull requests +# +# To maximize bug-catching changes while keeping CI times reasonable, we run +# tests scattered between Java 11/17/24, across linux/mac/windows, intel/arm - uses: ./.github/workflows/post-build-raw.yml - with: - java-version: ${{ matrix.java-version }} - buildcmd: ${{ matrix.buildcmd }} - # Scalafmt, Mima, and Scalafix job runs last because it's the least important: - # usually just an automated or mechanical manual fix to do before merging - lint-autofix: - needs: build-linux - uses: ./.github/workflows/post-build-raw.yml - with: - java-version: '17' - buildcmd: | - set -eux - ./mill -i mill.scalalib.scalafmt.ScalafmtModule/scalafmt --check + __.fix --check + mill.javalib.palantirformat.PalantirFormatModule/ --check + mill.kotlinlib.ktlint.KtlintModule/checkFormatAll - mima: - needs: build-linux - uses: ./.github/workflows/post-build-raw.yml - with: - java-version: '17' - buildcmd: | - set -eux - ./mill -i __.mimaReportBinaryIssues +#name: Run Tests +# +#on: +# push: +# branches-ignore: +# - '**-patch-**' +# pull_request: +# types: +# - opened +# - reopened +# - synchronize +# - ready_for_review +# workflow_dispatch: +# +## cancel older runs of a pull request; +## this will not cancel anything for normal git pushes +#concurrency: +# # * For runs on other repos, always use the `ref_name` so each branch only can have one concurrent run +# # * For runs on `com-lihaoyi/mill`, use `head_ref` to allow one concurrent run per PR, but `run_id` to +# # allow multiple concurrent runs in master +# group: cancel-old-pr-runs-${{ github.workflow }}-${{ (github.repository != 'com-lihaoyi/mill' && github.ref_name) || (github.head_ref || github.run_id) }} +# cancel-in-progress: true +# +#jobs: +# # Jobs are listed in rough order of priority: if multiple jobs fail, the first job +# # in the list should be the one that's most worth looking into +# build-linux: +# if: (github.event.action == 'ready_for_review') || (github.event.pull_request.draft == false) +# uses: ./.github/workflows/pre-build.yml +# with: +# os: ubuntu-latest +# shell: bash +# +# build-windows: +# if: (github.event.action == 'ready_for_review') || (github.event.pull_request.draft == false) +# uses: ./.github/workflows/pre-build.yml +# with: +# os: windows-latest +# shell: powershell +# +# test-docs: +# if: (github.event.action == 'ready_for_review') || (github.event.pull_request.draft == false) +# runs-on: ubuntu-latest +# steps: +# - uses: actions/checkout@v5 +# with: { fetch-depth: 1 } +# +# - run: ./mill -i website.fastPages + website.checkBrokenLinks +# +# cross-plat: +# if: (github.event.action == 'ready_for_review') || (github.event.pull_request.draft == false) +# runs-on: ${{ matrix.os }} +# strategy: +# fail-fast: false +# matrix: +# # Run these with Mill native launcher as a smoketest +# include: +# - os: ubuntu-24.04-arm +# millargs: "'example.thirdparty[{mockito,netty,arrow}].native.daemon'" +# java-version: 17 +# +# - os: macos-latest +# millargs: "'example.thirdparty[{acyclic,fansi,gatling}].native.daemon'" +# java-version: 11 +# +# - os: macos-13 +# millargs: "'example.thirdparty[{jimfs,commons-io}].native.daemon'" +# java-version: 24 +# steps: +# - uses: actions/checkout@v5 +# with: { fetch-depth: 1 } +# +# - uses: ./.github/actions/pre-build-setup +# with: +# os: ${{ matrix.os }} +# java-version: ${{ matrix.java-version }} +# shell: bash +# +# - uses: ./.github/actions/post-build-setup +# with: +# java-version: ${{ matrix.java-version }} +# os: ${{ matrix.os }} +# +# - uses: ./.github/actions/post-build-selective +# with: +# millargs: ${{ matrix.millargs }} +# shell: bash +# +# linux: +# needs: build-linux +# strategy: +# fail-fast: false +# matrix: +# +# include: +# # For most tests, run them arbitrarily on Java 11 or Java 17 on Linux, and +# # on the opposite version on Windows below, so we get decent coverage of +# # each test on each Java version and each operating system +# # We also try to group tests together to manually balance out the runtimes of each jobs +# - java-version: 17 +# millargs: "'{contrib,core,testkit,runner,dist}.__.test'" +# +# - java-version: 17 +# millargs: "'libs.{scalalib,init,tabcomplete}.__.test'" +# install-sbt: true +# +# - java-version: 11 +# millargs: "'libs.{scalajslib,scalanativelib,kotlinlib,pythonlib,javascriptlib}.__.test'" +# +# - java-version: 17 +# millargs: "example.kotlinlib.__.local.daemon" +# +# - java-version: 11 +# millargs: "example.scalalib.__.local.daemon" +# +# - java-version: 21 +# millargs: "example.javalib.__.local.daemon" +# +# - java-version: 17 +# millargs: "'example.androidlib.__.local.daemon'" +# setup-android: true +# +# - java-version: 17 +# millargs: "'example.thirdparty[androidtodo].packaged.daemon'" +# setup-android: true +# +# - java-version: 24 +# millargs: "'example.migrating.scalalib.__.local.daemon'" +# install-sbt: true +# +# - java-version: 24 +# millargs: "'example.{pythonlib,javascriptlib}.__.local.daemon'" +# +# - java-version: 21 +# millargs: "'example.{cli,fundamentals,depth,extending,large}.__.local.daemon'" +# +# - java-version: 21 +# millargs: "'integration.{feature,ide}.__.packaged.daemon'" +# +# # run this specifically in `native` mode to make sure our non-JVM native image +# # launcher is able to bootstrap everything necessary without a JVM installed +# - java-version: 17 +# millargs: "'integration.bootstrap[no-java-bootstrap].native.daemon'" +# +# # These invalidation tests need to be exercised in both execution modes +# # to make sure they work with and without -i/--no-server being passed +# - java-version: 24 +# millargs: "'integration.invalidation.__.packaged.nodaemon'" +# +# - java-version: 17 +# millargs: "'integration.migrating.__.packaged.daemon'" +# install-sbt: true +# +# uses: ./.github/workflows/post-build-selective.yml +# with: +# setup-android: ${{ matrix.setup-android || false }} +# install-sbt: ${{ matrix.install-sbt || false }} +# install-xvfb: ${{ matrix.install-xvfb || false }} +# java-version: ${{ matrix.java-version }} +# millargs: ${{ matrix.millargs }} +# shell: bash +# +# windows: +# needs: build-windows +# strategy: +# fail-fast: false +# matrix: +# include: +# - java-version: 24 +# millargs: "'integration.invalidation.__.packaged.daemon'" +# +# - java-version: 11 +# # turn of parallelism since it sometimes causes issues with concurrent migrations +# millargs: '"example.migrating.javalib.__.packaged.daemon"' +# extra: "--jobs=1" +# - java-version: 11 +# millargs: '"libs.{util,javalib,androidlib,graphviz}.__.test"' +# +# - java-version: 17 +# millargs: '"example.scalalib.{basic,publishing}.__.packaged.daemon"' +# +# - java-version: 17 +# millargs: "'integration.failure.__.packaged.nodaemon'" +# +# - java-version: 17 +# millargs: "'integration.bootstrap[no-java-bootstrap].native.daemon'" +# +# uses: ./.github/workflows/post-build-selective.yml +# with: +# os: windows-latest +# java-version: ${{ matrix.java-version }} +# millargs: ${{ matrix.millargs }} +# extra: ${{ matrix.extra || '' }} +# shell: powershell +# +# itest: +# needs: build-linux +# strategy: +# fail-fast: false +# matrix: +# include: +# # bootstrap tests +# - java-version: 11 +# buildcmd: ci/test-dist-run.sh && ci/test-mill-bootstrap.sh +# +# uses: ./.github/workflows/post-build-raw.yml +# with: +# java-version: ${{ matrix.java-version }} +# buildcmd: ${{ matrix.buildcmd }} +# +# # Scalafmt, Mima, and Scalafix job runs last because it's the least important: +# # usually just an automated or mechanical manual fix to do before merging +# lint-autofix: +# needs: build-linux +# uses: ./.github/workflows/post-build-raw.yml +# with: +# java-version: '17' +# buildcmd: | +# set -eux +# ./mill -i mill.scalalib.scalafmt.ScalafmtModule/scalafmt --check + __.fix --check + mill.javalib.palantirformat.PalantirFormatModule/ --check + mill.kotlinlib.ktlint.KtlintModule/checkFormatAll +# mima: +# needs: build-linux +# uses: ./.github/workflows/post-build-raw.yml +# with: +# java-version: '17' +# buildcmd: | +# set -eux +# ./mill -i __.mimaReportBinaryIssues From 54ed28c3552f33a43608b8aa84c4197d1bbbd575 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Thu, 30 Oct 2025 08:38:43 +0800 Subject: [PATCH 27/33] . --- .github/workflows/run-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index df4ec5671c04..71e885994505 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -10,8 +10,8 @@ on: jobs: debug: - runs-on: ubuntu-latest -# runs-on: windows-latest +# runs-on: ubuntu-latest + runs-on: windows-latest steps: - uses: actions/checkout@v5 with: { fetch-depth: 1 } From 6b812baed52ec646d112c1c3ca0079678ffba5f1 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Thu, 30 Oct 2025 08:39:03 +0800 Subject: [PATCH 28/33] . --- .github/workflows/run-tests.yml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 71e885994505..d45bbfe0e310 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -9,7 +9,20 @@ on: workflow_dispatch: jobs: - debug: + debug-linux: + runs-on: ubuntu-latest +# runs-on: windows-latest + steps: + - uses: actions/checkout@v5 + with: { fetch-depth: 1 } + + - run: "echo temurin:11 > .mill-jvm-version" + + - uses: sbt/setup-sbt@v1 + + + - run: ./mill 'integration.failure[compile-error].packaged.nodaemon' + debug-win: # runs-on: ubuntu-latest runs-on: windows-latest steps: From 20196ff8eb9ed09da4f8aee7ed5417ecdc86875b Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Thu, 30 Oct 2025 09:14:13 +0800 Subject: [PATCH 29/33] . --- .../compile-error/src/CompileErrorTests.scala | 48 ++++++++++++------- .../src/RootModuleCompileErrorTests.scala | 2 +- runner/meta/src/mill/meta/CodeGen.scala | 6 +-- 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/integration/failure/compile-error/src/CompileErrorTests.scala b/integration/failure/compile-error/src/CompileErrorTests.scala index 4a5ab1247e36..e010f2c6c7ec 100644 --- a/integration/failure/compile-error/src/CompileErrorTests.scala +++ b/integration/failure/compile-error/src/CompileErrorTests.scala @@ -10,25 +10,37 @@ object CompileErrorTests extends UtestIntegrationTestSuite { val res = tester.eval("foo.scalaVersion") assert(!res.isSuccess) + val normalizedError = res.err + .replace(tester.workspacePath.toString, "") + .linesIterator + .filter(s => s.startsWith("[error] ")) + .toVector + .map(_.replace('\\', '/')) - locally { - assert(res.err.contains("""bar.mill:15:9""")) - assert(res.err.contains("""println(doesntExist)""")) - assert(res.err.contains("""Not found: doesntExist""")) - } - - locally { - assert(res.err.contains("""qux.mill:4:34""")) - assert(res.err.contains("""myMsg.substring("0")""")) - assert(res.err.contains("""Found: ("0" : String)""")) - assert(res.err.contains("""Required: Int""")) - } - - locally { - assert(res.err.contains("""build.mill:11:5""")) - assert(res.err.contains("""foo.noSuchMethod""")) - assert(res.err.contains("""value noSuchMethod is not a member""")) - } + // For now some error messages still show generated/mangled code; not ideal, but it'll do + assertGoldenLiteral( + normalizedError, + Vector( + "[error] -- [E007] Type Mismatch Error: /qux.mill:4:33 ", + "[error] 4 |def myOtherMsg = myMsg.substring(\"0\")", + "[error] | ^^^", + "[error] | Found: (\"0\" : String)", + "[error] | Required: Int", + "[error] |", + "[error] | longer explanation available when compiling with `-explain`", + "[error] -- [E006] Not Found Error: /bar.mill:15:8 ", + "[error] 15 |println(doesntExist)", + "[error] | ^^^^^^^^^^^", + "[error] | Not found: doesntExist", + "[error] |", + "[error] | longer explanation available when compiling with `-explain`", + "[error] -- [E008] Not Found Error: /build.mill:11:4 ", + "[error] 11 |foo.noSuchMethod", + "[error] |^^^^^^^^^^^^^^^^", + "[error] |value noSuchMethod is not a member of object package_.this.foo", + "[error] three errors found" + ) + ) } } } diff --git a/integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala b/integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala index d24cf8fa67f9..5247b14ec0df 100644 --- a/integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala +++ b/integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala @@ -15,7 +15,7 @@ object RootModuleCompileErrorTests extends UtestIntegrationTestSuite { val normalizedError = res.err .replace(workspacePath.toString, "") .linesIterator - .filter(s => s.startsWith("[error] ") && !s.contains("| ")) + .filter(s => s.startsWith("[error] ")) .toVector .map(_.replace('\\', '/')) diff --git a/runner/meta/src/mill/meta/CodeGen.scala b/runner/meta/src/mill/meta/CodeGen.scala index 243e3b0e917b..0156e858fdbb 100644 --- a/runner/meta/src/mill/meta/CodeGen.scala +++ b/runner/meta/src/mill/meta/CodeGen.scala @@ -214,8 +214,7 @@ object CodeGen { |$importSiblingScripts | |object $wrapperName { - |$markerComment - |$scriptCode + |$markerComment$scriptCode |} | |export $wrapperName._ @@ -381,8 +380,7 @@ object CodeGen { s"""$headerCode |abstract class ${CGConst.wrapperObjectName} | extends $newParent { this: ${CGConst.wrapperObjectName}.type => - |$markerComment - |$scriptCode + |$markerComment$scriptCode |}""".stripMargin } From f2f0a55a51ae6cc92ab579f013b4fc144ebc715a Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Thu, 30 Oct 2025 09:15:34 +0800 Subject: [PATCH 30/33] . --- .github/workflows/run-tests.yml | 475 ++++++++++++++++---------------- 1 file changed, 231 insertions(+), 244 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index d45bbfe0e310..b8b7274b8ae7 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -1,275 +1,262 @@ # Uncommment this to replace the rest of the file when you want to debug stuff in CI -name: Run Debug +#name: Run Debug +# +#on: +# push: +# pull_request: +# workflow_dispatch: +# +#jobs: +# debug: +# runs-on: ubuntu-latest +## runs-on: windows-latest +# steps: +# - uses: actions/checkout@v5 +# with: { fetch-depth: 1 } +# +# - run: "echo temurin:11 > .mill-jvm-version" +# +# - uses: sbt/setup-sbt@v1 +# +# +# - run: ./mill 'integration.migrating[init].local.daemon.testOnly' mill.integration.MillInitSbtGatlingTests +# + + + +# We run full CI on push builds to main and on all pull requests +# +# To maximize bug-catching changes while keeping CI times reasonable, we run +# tests scattered between Java 11/17/24, across linux/mac/windows, intel/arm + + +name: Run Tests on: push: + branches-ignore: + - '**-patch-**' pull_request: + types: + - opened + - reopened + - synchronize + - ready_for_review workflow_dispatch: +# cancel older runs of a pull request; +# this will not cancel anything for normal git pushes +concurrency: + # * For runs on other repos, always use the `ref_name` so each branch only can have one concurrent run + # * For runs on `com-lihaoyi/mill`, use `head_ref` to allow one concurrent run per PR, but `run_id` to + # allow multiple concurrent runs in master + group: cancel-old-pr-runs-${{ github.workflow }}-${{ (github.repository != 'com-lihaoyi/mill' && github.ref_name) || (github.head_ref || github.run_id) }} + cancel-in-progress: true + jobs: - debug-linux: + # Jobs are listed in rough order of priority: if multiple jobs fail, the first job + # in the list should be the one that's most worth looking into + build-linux: + if: (github.event.action == 'ready_for_review') || (github.event.pull_request.draft == false) + uses: ./.github/workflows/pre-build.yml + with: + os: ubuntu-latest + shell: bash + + build-windows: + if: (github.event.action == 'ready_for_review') || (github.event.pull_request.draft == false) + uses: ./.github/workflows/pre-build.yml + with: + os: windows-latest + shell: powershell + + test-docs: + if: (github.event.action == 'ready_for_review') || (github.event.pull_request.draft == false) runs-on: ubuntu-latest -# runs-on: windows-latest steps: - uses: actions/checkout@v5 with: { fetch-depth: 1 } - - run: "echo temurin:11 > .mill-jvm-version" + - run: ./mill -i website.fastPages + website.checkBrokenLinks - - uses: sbt/setup-sbt@v1 + cross-plat: + if: (github.event.action == 'ready_for_review') || (github.event.pull_request.draft == false) + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + # Run these with Mill native launcher as a smoketest + include: + - os: ubuntu-24.04-arm + millargs: "'example.thirdparty[{mockito,netty,arrow}].native.daemon'" + java-version: 17 + - os: macos-latest + millargs: "'example.thirdparty[{acyclic,fansi,gatling}].native.daemon'" + java-version: 11 - - run: ./mill 'integration.failure[compile-error].packaged.nodaemon' - debug-win: -# runs-on: ubuntu-latest - runs-on: windows-latest + - os: macos-13 + millargs: "'example.thirdparty[{jimfs,commons-io}].native.daemon'" + java-version: 24 steps: - uses: actions/checkout@v5 with: { fetch-depth: 1 } - - run: "echo temurin:11 > .mill-jvm-version" + - uses: ./.github/actions/pre-build-setup + with: + os: ${{ matrix.os }} + java-version: ${{ matrix.java-version }} + shell: bash - - uses: sbt/setup-sbt@v1 + - uses: ./.github/actions/post-build-setup + with: + java-version: ${{ matrix.java-version }} + os: ${{ matrix.os }} + - uses: ./.github/actions/post-build-selective + with: + millargs: ${{ matrix.millargs }} + shell: bash - - run: ./mill 'integration.failure[compile-error].packaged.nodaemon' + linux: + needs: build-linux + strategy: + fail-fast: false + matrix: + include: + # For most tests, run them arbitrarily on Java 11 or Java 17 on Linux, and + # on the opposite version on Windows below, so we get decent coverage of + # each test on each Java version and each operating system + # We also try to group tests together to manually balance out the runtimes of each jobs + - java-version: 17 + millargs: "'{contrib,core,testkit,runner,dist}.__.test'" + - java-version: 17 + millargs: "'libs.{scalalib,init,tabcomplete}.__.test'" + install-sbt: true + - java-version: 11 + millargs: "'libs.{scalajslib,scalanativelib,kotlinlib,pythonlib,javascriptlib}.__.test'" -# We run full CI on push builds to main and on all pull requests -# -# To maximize bug-catching changes while keeping CI times reasonable, we run -# tests scattered between Java 11/17/24, across linux/mac/windows, intel/arm + - java-version: 17 + millargs: "example.kotlinlib.__.local.daemon" + - java-version: 11 + millargs: "example.scalalib.__.local.daemon" -#name: Run Tests -# -#on: -# push: -# branches-ignore: -# - '**-patch-**' -# pull_request: -# types: -# - opened -# - reopened -# - synchronize -# - ready_for_review -# workflow_dispatch: -# -## cancel older runs of a pull request; -## this will not cancel anything for normal git pushes -#concurrency: -# # * For runs on other repos, always use the `ref_name` so each branch only can have one concurrent run -# # * For runs on `com-lihaoyi/mill`, use `head_ref` to allow one concurrent run per PR, but `run_id` to -# # allow multiple concurrent runs in master -# group: cancel-old-pr-runs-${{ github.workflow }}-${{ (github.repository != 'com-lihaoyi/mill' && github.ref_name) || (github.head_ref || github.run_id) }} -# cancel-in-progress: true -# -#jobs: -# # Jobs are listed in rough order of priority: if multiple jobs fail, the first job -# # in the list should be the one that's most worth looking into -# build-linux: -# if: (github.event.action == 'ready_for_review') || (github.event.pull_request.draft == false) -# uses: ./.github/workflows/pre-build.yml -# with: -# os: ubuntu-latest -# shell: bash -# -# build-windows: -# if: (github.event.action == 'ready_for_review') || (github.event.pull_request.draft == false) -# uses: ./.github/workflows/pre-build.yml -# with: -# os: windows-latest -# shell: powershell -# -# test-docs: -# if: (github.event.action == 'ready_for_review') || (github.event.pull_request.draft == false) -# runs-on: ubuntu-latest -# steps: -# - uses: actions/checkout@v5 -# with: { fetch-depth: 1 } -# -# - run: ./mill -i website.fastPages + website.checkBrokenLinks -# -# cross-plat: -# if: (github.event.action == 'ready_for_review') || (github.event.pull_request.draft == false) -# runs-on: ${{ matrix.os }} -# strategy: -# fail-fast: false -# matrix: -# # Run these with Mill native launcher as a smoketest -# include: -# - os: ubuntu-24.04-arm -# millargs: "'example.thirdparty[{mockito,netty,arrow}].native.daemon'" -# java-version: 17 -# -# - os: macos-latest -# millargs: "'example.thirdparty[{acyclic,fansi,gatling}].native.daemon'" -# java-version: 11 -# -# - os: macos-13 -# millargs: "'example.thirdparty[{jimfs,commons-io}].native.daemon'" -# java-version: 24 -# steps: -# - uses: actions/checkout@v5 -# with: { fetch-depth: 1 } -# -# - uses: ./.github/actions/pre-build-setup -# with: -# os: ${{ matrix.os }} -# java-version: ${{ matrix.java-version }} -# shell: bash -# -# - uses: ./.github/actions/post-build-setup -# with: -# java-version: ${{ matrix.java-version }} -# os: ${{ matrix.os }} -# -# - uses: ./.github/actions/post-build-selective -# with: -# millargs: ${{ matrix.millargs }} -# shell: bash -# -# linux: -# needs: build-linux -# strategy: -# fail-fast: false -# matrix: -# -# include: -# # For most tests, run them arbitrarily on Java 11 or Java 17 on Linux, and -# # on the opposite version on Windows below, so we get decent coverage of -# # each test on each Java version and each operating system -# # We also try to group tests together to manually balance out the runtimes of each jobs -# - java-version: 17 -# millargs: "'{contrib,core,testkit,runner,dist}.__.test'" -# -# - java-version: 17 -# millargs: "'libs.{scalalib,init,tabcomplete}.__.test'" -# install-sbt: true -# -# - java-version: 11 -# millargs: "'libs.{scalajslib,scalanativelib,kotlinlib,pythonlib,javascriptlib}.__.test'" -# -# - java-version: 17 -# millargs: "example.kotlinlib.__.local.daemon" -# -# - java-version: 11 -# millargs: "example.scalalib.__.local.daemon" -# -# - java-version: 21 -# millargs: "example.javalib.__.local.daemon" -# -# - java-version: 17 -# millargs: "'example.androidlib.__.local.daemon'" -# setup-android: true -# -# - java-version: 17 -# millargs: "'example.thirdparty[androidtodo].packaged.daemon'" -# setup-android: true -# -# - java-version: 24 -# millargs: "'example.migrating.scalalib.__.local.daemon'" -# install-sbt: true -# -# - java-version: 24 -# millargs: "'example.{pythonlib,javascriptlib}.__.local.daemon'" -# -# - java-version: 21 -# millargs: "'example.{cli,fundamentals,depth,extending,large}.__.local.daemon'" -# -# - java-version: 21 -# millargs: "'integration.{feature,ide}.__.packaged.daemon'" -# -# # run this specifically in `native` mode to make sure our non-JVM native image -# # launcher is able to bootstrap everything necessary without a JVM installed -# - java-version: 17 -# millargs: "'integration.bootstrap[no-java-bootstrap].native.daemon'" -# -# # These invalidation tests need to be exercised in both execution modes -# # to make sure they work with and without -i/--no-server being passed -# - java-version: 24 -# millargs: "'integration.invalidation.__.packaged.nodaemon'" -# -# - java-version: 17 -# millargs: "'integration.migrating.__.packaged.daemon'" -# install-sbt: true -# -# uses: ./.github/workflows/post-build-selective.yml -# with: -# setup-android: ${{ matrix.setup-android || false }} -# install-sbt: ${{ matrix.install-sbt || false }} -# install-xvfb: ${{ matrix.install-xvfb || false }} -# java-version: ${{ matrix.java-version }} -# millargs: ${{ matrix.millargs }} -# shell: bash -# -# windows: -# needs: build-windows -# strategy: -# fail-fast: false -# matrix: -# include: -# - java-version: 24 -# millargs: "'integration.invalidation.__.packaged.daemon'" -# -# - java-version: 11 -# # turn of parallelism since it sometimes causes issues with concurrent migrations -# millargs: '"example.migrating.javalib.__.packaged.daemon"' -# extra: "--jobs=1" -# - java-version: 11 -# millargs: '"libs.{util,javalib,androidlib,graphviz}.__.test"' -# -# - java-version: 17 -# millargs: '"example.scalalib.{basic,publishing}.__.packaged.daemon"' -# -# - java-version: 17 -# millargs: "'integration.failure.__.packaged.nodaemon'" -# -# - java-version: 17 -# millargs: "'integration.bootstrap[no-java-bootstrap].native.daemon'" -# -# uses: ./.github/workflows/post-build-selective.yml -# with: -# os: windows-latest -# java-version: ${{ matrix.java-version }} -# millargs: ${{ matrix.millargs }} -# extra: ${{ matrix.extra || '' }} -# shell: powershell -# -# itest: -# needs: build-linux -# strategy: -# fail-fast: false -# matrix: -# include: -# # bootstrap tests -# - java-version: 11 -# buildcmd: ci/test-dist-run.sh && ci/test-mill-bootstrap.sh -# -# uses: ./.github/workflows/post-build-raw.yml -# with: -# java-version: ${{ matrix.java-version }} -# buildcmd: ${{ matrix.buildcmd }} -# -# # Scalafmt, Mima, and Scalafix job runs last because it's the least important: -# # usually just an automated or mechanical manual fix to do before merging -# lint-autofix: -# needs: build-linux -# uses: ./.github/workflows/post-build-raw.yml -# with: -# java-version: '17' -# buildcmd: | -# set -eux -# ./mill -i mill.scalalib.scalafmt.ScalafmtModule/scalafmt --check + __.fix --check + mill.javalib.palantirformat.PalantirFormatModule/ --check + mill.kotlinlib.ktlint.KtlintModule/checkFormatAll -# mima: -# needs: build-linux -# uses: ./.github/workflows/post-build-raw.yml -# with: -# java-version: '17' -# buildcmd: | -# set -eux -# ./mill -i __.mimaReportBinaryIssues + - java-version: 21 + millargs: "example.javalib.__.local.daemon" + + - java-version: 17 + millargs: "'example.androidlib.__.local.daemon'" + setup-android: true + + - java-version: 17 + millargs: "'example.thirdparty[androidtodo].packaged.daemon'" + setup-android: true + + - java-version: 24 + millargs: "'example.migrating.scalalib.__.local.daemon'" + install-sbt: true + + - java-version: 24 + millargs: "'example.{pythonlib,javascriptlib}.__.local.daemon'" + + - java-version: 21 + millargs: "'example.{cli,fundamentals,depth,extending,large}.__.local.daemon'" + + - java-version: 21 + millargs: "'integration.{feature,ide}.__.packaged.daemon'" + + # run this specifically in `native` mode to make sure our non-JVM native image + # launcher is able to bootstrap everything necessary without a JVM installed + - java-version: 17 + millargs: "'integration.bootstrap[no-java-bootstrap].native.daemon'" + + # These invalidation tests need to be exercised in both execution modes + # to make sure they work with and without -i/--no-server being passed + - java-version: 24 + millargs: "'integration.invalidation.__.packaged.nodaemon'" + + - java-version: 17 + millargs: "'integration.migrating.__.packaged.daemon'" + install-sbt: true + + uses: ./.github/workflows/post-build-selective.yml + with: + setup-android: ${{ matrix.setup-android || false }} + install-sbt: ${{ matrix.install-sbt || false }} + install-xvfb: ${{ matrix.install-xvfb || false }} + java-version: ${{ matrix.java-version }} + millargs: ${{ matrix.millargs }} + shell: bash + + windows: + needs: build-windows + strategy: + fail-fast: false + matrix: + include: + - java-version: 24 + millargs: "'integration.invalidation.__.packaged.daemon'" + + - java-version: 11 + # turn of parallelism since it sometimes causes issues with concurrent migrations + millargs: '"example.migrating.javalib.__.packaged.daemon"' + extra: "--jobs=1" + - java-version: 11 + millargs: '"libs.{util,javalib,androidlib,graphviz}.__.test"' + + - java-version: 17 + millargs: '"example.scalalib.{basic,publishing}.__.packaged.daemon"' + + - java-version: 17 + millargs: "'integration.failure.__.packaged.nodaemon'" + + - java-version: 17 + millargs: "'integration.bootstrap[no-java-bootstrap].native.daemon'" + + uses: ./.github/workflows/post-build-selective.yml + with: + os: windows-latest + java-version: ${{ matrix.java-version }} + millargs: ${{ matrix.millargs }} + extra: ${{ matrix.extra || '' }} + shell: powershell + + itest: + needs: build-linux + strategy: + fail-fast: false + matrix: + include: + # bootstrap tests + - java-version: 11 + buildcmd: ci/test-dist-run.sh && ci/test-mill-bootstrap.sh + + uses: ./.github/workflows/post-build-raw.yml + with: + java-version: ${{ matrix.java-version }} + buildcmd: ${{ matrix.buildcmd }} + + # Scalafmt, Mima, and Scalafix job runs last because it's the least important: + # usually just an automated or mechanical manual fix to do before merging + lint-autofix: + needs: build-linux + uses: ./.github/workflows/post-build-raw.yml + with: + java-version: '17' + buildcmd: | + set -eux + ./mill -i mill.scalalib.scalafmt.ScalafmtModule/scalafmt --check + __.fix --check + mill.javalib.palantirformat.PalantirFormatModule/ --check + mill.kotlinlib.ktlint.KtlintModule/checkFormatAll + mima: + needs: build-linux + uses: ./.github/workflows/post-build-raw.yml + with: + java-version: '17' + buildcmd: | + set -eux + ./mill -i __.mimaReportBinaryIssues From b63c2b51023d45882e0880654e8c1d5792b4a297 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Thu, 30 Oct 2025 09:21:02 +0800 Subject: [PATCH 31/33] . --- .../src/RootModuleCompileErrorTests.scala | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala b/integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala index 5247b14ec0df..e9dff403bdea 100644 --- a/integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala +++ b/integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala @@ -25,34 +25,50 @@ object RootModuleCompileErrorTests extends UtestIntegrationTestSuite { Vector( "[error] -- [E006] Not Found Error: /build.mill:12:75 ", "[error] 12 |", + "[error] | ^^^^^^^^^^^^^^^^^", + "[error] | Not found: type UnknownRootModule", "[error] |", "[error] | longer explanation available when compiling with `-explain`", "[error] -- [E006] Not Found Error: /foo/package.mill:11:103 ", "[error] 11 |", + "[error] | ^^^^^^^^^^^^^^^^", + "[error] | Not found: type UnknownFooModule", "[error] |", "[error] | longer explanation available when compiling with `-explain`", "[error] -- [E006] Not Found Error: /build.mill:5:22 ", "[error] 5 |object before extends UnknownBeforeModule", + "[error] | ^^^^^^^^^^^^^^^^^^^", + "[error] | Not found: type UnknownBeforeModule", "[error] |", "[error] | longer explanation available when compiling with `-explain`", "[error] -- [E006] Not Found Error: /build.mill:8:21 ", "[error] 8 | def scalaVersion = unknownRootInternalDef", + "[error] | ^^^^^^^^^^^^^^^^^^^^^^", + "[error] | Not found: unknownRootInternalDef", "[error] |", "[error] | longer explanation available when compiling with `-explain`", "[error] -- [E006] Not Found Error: /build.mill:11:21 ", "[error] 11 |object after extends UnknownAfterModule", + "[error] | ^^^^^^^^^^^^^^^^^^", + "[error] | Not found: type UnknownAfterModule", "[error] |", "[error] | longer explanation available when compiling with `-explain`", "[error] -- [E006] Not Found Error: /foo/package.mill:4:22 ", "[error] 4 |object before extends UnknownBeforeFooModule", + "[error] | ^^^^^^^^^^^^^^^^^^^^^^", + "[error] | Not found: type UnknownBeforeFooModule", "[error] |", "[error] | longer explanation available when compiling with `-explain`", "[error] -- [E006] Not Found Error: /foo/package.mill:7:21 ", "[error] 7 | def scalaVersion = unknownFooInternalDef", + "[error] | ^^^^^^^^^^^^^^^^^^^^^", + "[error] | Not found: unknownFooInternalDef", "[error] |", "[error] | longer explanation available when compiling with `-explain`", "[error] -- [E006] Not Found Error: /foo/package.mill:10:21 ", "[error] 10 |object after extends UnknownAfterFooModule", + "[error] | ^^^^^^^^^^^^^^^^^^^^^", + "[error] | Not found: type UnknownAfterFooModule", "[error] |", "[error] | longer explanation available when compiling with `-explain`", "[error] 8 errors found" From ce942b9ca430472b698004c281ea438811f4c04a Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Thu, 30 Oct 2025 09:23:33 +0800 Subject: [PATCH 32/33] . --- runner/meta/src/mill/meta/CodeGen.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runner/meta/src/mill/meta/CodeGen.scala b/runner/meta/src/mill/meta/CodeGen.scala index 0156e858fdbb..a315a98bd2ef 100644 --- a/runner/meta/src/mill/meta/CodeGen.scala +++ b/runner/meta/src/mill/meta/CodeGen.scala @@ -120,7 +120,7 @@ object CodeGen { val prelude = s"""|import MillMiscInfo._ |import _root_.mill.util.TokenReaders.given - |""" + |""".stripMargin os.write.over(supportDestDir / "MillMiscInfo.scala", miscInfo, createFolders = true) From adc3bd99376bf08f8128e8e190410ffe95e0cdcf Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Thu, 30 Oct 2025 10:13:47 +0800 Subject: [PATCH 33/33] . --- runner/meta/src/mill/meta/CodeGen.scala | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/runner/meta/src/mill/meta/CodeGen.scala b/runner/meta/src/mill/meta/CodeGen.scala index a315a98bd2ef..f869351fcad1 100644 --- a/runner/meta/src/mill/meta/CodeGen.scala +++ b/runner/meta/src/mill/meta/CodeGen.scala @@ -371,10 +371,11 @@ object CodeGen { s"""$headerCode | - |$markerComment$newScriptCode - | - |$generatedStub - |""".stripMargin + |$markerComment$newScriptCode""".stripMargin + + // Not sure why we need to mix System.lineSeparator and \n here, but it seems to + // result in the correct error position reporting for the following code on both + // windows and mac + System.lineSeparator + "\n" + generatedStub case None => s"""$headerCode