Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup logger #4653

Merged
merged 21 commits into from
Mar 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions bsp/src/mill/bsp/BSP.scala
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ object BSP extends ExternalModule with CoursierModule {
*/
def startSession(allBootstrapEvaluators: Evaluator.AllBootstrapEvaluators)
: Command[BspServerResult] = Task.Command(exclusive = true) {
Task.log.errorStream.println("BSP/startSession: Starting BSP session")
Task.log.streams.err.println("BSP/startSession: Starting BSP session")
val res = BspContext.bspServerHandle.runSession(allBootstrapEvaluators.value)
Task.log.errorStream.println(s"BSP/startSession: Finished BSP session, result: ${res}")
Task.log.streams.err.println(s"BSP/startSession: Finished BSP session, result: ${res}")
res
}

Expand Down
19 changes: 9 additions & 10 deletions bsp/src/mill/bsp/BspContext.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ private[mill] class BspContext(
BspContext.bspServerHandle =
try {
startBspServer(
streams = streams,
streams0 = streams,
logStream = bspLogStream,
canReload = true
).get
Expand All @@ -37,27 +37,26 @@ private[mill] class BspContext(
streams.err.println("BSP server started")

def startBspServer(
streams: SystemStreams,
streams0: SystemStreams,
logStream: Option[PrintStream],
canReload: Boolean
): Result[BspServerHandle] = {
val log: Logger = new Logger {
override def colored: Boolean = false
override def systemStreams: SystemStreams = new SystemStreams(
out = streams.out,
err = streams.err,
override def streams: SystemStreams = new SystemStreams(
out = streams0.out,
err = streams0.err,
in = DummyInputStream
)
def prompt = new Logger.Prompt.NoOp {
override def setPromptDetail(key: Seq[String], s: String): Unit = streams.err.println(s)
}

override def info(s: String): Unit = streams.err.println(s)
override def error(s: String): Unit = streams.err.println(s)
override def ticker(s: String): Unit = streams.err.println(s)
override def setPromptDetail(key: Seq[String], s: String): Unit = streams.err.println(s)
override def debug(s: String): Unit = streams.err.println(s)

override def debugEnabled: Boolean = true

override def rawOutputStream: PrintStream = systemStreams.out
override def debug(s: String): Unit = streams.err.println(s)
}

BspWorker(mill.api.WorkspaceRoot.workspaceRoot, home, log).flatMap { worker =>
Expand Down
4 changes: 2 additions & 2 deletions bsp/worker/src/mill/bsp/worker/MillBspLogger.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package mill.bsp.worker

import ch.epfl.scala.bsp4j._
import mill.api.{ColorLogger, Logger}
import mill.api.{Logger}
import mill.internal.ProxyLogger

/**
Expand All @@ -19,7 +19,7 @@ import mill.internal.ProxyLogger
*/
private class MillBspLogger(client: BuildClient, taskId: Int, logger: Logger)
extends ProxyLogger(logger)
with ColorLogger {
with Logger {
override def infoColor = fansi.Color.Blue
override def errorColor = fansi.Color.Red

Expand Down
6 changes: 3 additions & 3 deletions bsp/worker/src/mill/bsp/worker/MillBuildServer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import ch.epfl.scala.bsp4j
import ch.epfl.scala.bsp4j.*
import com.google.gson.JsonObject
import mill.api.ExecResult
import mill.api.{ColorLogger, CompileProblemReporter, DummyTestReporter, Result, TestReporter}
import mill.api.{Logger, CompileProblemReporter, DummyTestReporter, Result, TestReporter}
import mill.bsp.{BspServerResult, Constants}
import mill.bsp.worker.Utils.{makeBuildTarget, outputPaths, sanitizeUri}
import mill.define.Segment.Label
Expand Down Expand Up @@ -801,7 +801,7 @@ private class MillBuildServer(
goals: Seq[Task[?]],
reporter: Int => Option[CompileProblemReporter] = _ => Option.empty[CompileProblemReporter],
testReporter: TestReporter = DummyTestReporter,
logger: ColorLogger = null
logger: Logger = null
): ExecutionResults = {
val logger0 = Option(logger).getOrElse(evaluator.baseLogger)
mill.runner.MillMain.withOutLock(
Expand All @@ -812,7 +812,7 @@ private class MillBuildServer(
case n: NamedTask[_] => n.label
case t => t.toString
},
streams = logger0.systemStreams
streams = logger0.streams
) {
evaluator.execute(
goals,
Expand Down
64 changes: 61 additions & 3 deletions ci/mill-bootstrap.patch
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
diff --git a/build.mill b/build.mill
index 5c48e1e4e43..538e4b86e0c 100644
index 42be8622781..ecb84c31089 100644
--- a/build.mill
+++ b/build.mill
@@ -1,16 +1,16 @@
Expand Down Expand Up @@ -189,7 +189,7 @@ index e49f218f4be..9d03aa073f3 100644
def ivyDeps = Task {
if (!caseName.contains("realistic") && !caseName.contains("sourcecode")) super.ivyDeps()
diff --git a/dist/package.mill b/dist/package.mill
index fbbeacbc843..fb06c486273 100644
index fbbeacbc843..b3e00f8db5f 100644
--- a/dist/package.mill
+++ b/dist/package.mill
@@ -2,15 +2,14 @@ package build.dist
Expand All @@ -210,6 +210,15 @@ index fbbeacbc843..fb06c486273 100644
case m: PublishModule if (m ne build.dist) && (m ne build.dist.native) => m
}
def moduleDeps = Seq(build.runner, build.idea, build.main.init)
@@ -44,7 +43,7 @@ trait InstallModule extends build.MillPublishJavaModule {
(os.home / ".cache/mill/download" / (build.millVersion() + batExt)).toString()
)
)()
- Task.log.outputStream.println(path.toString())
+ Task.log.streams.out.println(path.toString())
PathRef(path)
}

@@ -185,10 +184,10 @@ object `package` extends RootModule with InstallModule {
val wd = os.Path(wd0, Task.workspace)
os.makeDir.all(wd)
Expand Down Expand Up @@ -650,7 +659,7 @@ index 3b577e29c65..7f45dcaeab6 100644
def forkEnv =
super.forkEnv() ++ Map("MILL_EXECUTABLE_PATH" -> build.dist.launcher().path.toString())
diff --git a/website/package.mill b/website/package.mill
index f88dc3fe8f6..eb1916dae76 100644
index f88dc3fe8f6..2e2d2be3716 100644
--- a/website/package.mill
+++ b/website/package.mill
@@ -26,7 +26,7 @@ object `package` extends RootModule {
Expand Down Expand Up @@ -753,3 +762,52 @@ index f88dc3fe8f6..eb1916dae76 100644
def blogFolder = Task {
os.copy(blogFolder0().path, Task.dest, mergeFolders = true)
expandDiagramsInDirectoryAdocFile(Task.dest, mill.main.VisualizeModule.classpath().map(_.path))
@@ -332,21 +332,21 @@ object `package` extends RootModule {

def localPages: T[PathRef] = Task {
val pages = generatePages(authorMode = true).apply().apply(oldDocSources().map(_.path))
- Task.log.outputStream.println(
+ Task.log.streams.out.println(
s"You can browse the pages at: ${(pages.path / "index.html").toNIO.toUri()}"
)
pages
}
def fastPages: T[PathRef] = Task {
val pages = generatePages(authorMode = true).apply().apply(Nil)
- Task.log.outputStream.println(
+ Task.log.streams.out.println(
s"You can browse the pages at: ${(pages.path / "index.html").toNIO.toUri()}"
)
pages
}

def generatePages(authorMode: Boolean) = Task.Anon { (extraSources: Seq[os.Path]) =>
- Task.log.errorStream.println("Creating Antora playbook ...")
+ Task.log.streams.err.println("Creating Antora playbook ...")
// dependency to sources
source()
val docSite = Task.dest
@@ -357,7 +357,7 @@ object `package` extends RootModule {
data = githubPagesPlaybookText(authorMode).apply().apply(extraSources),
createFolders = true
)
- Task.log.errorStream.println("Running Antora ...")
+ Task.log.streams.err.println("Running Antora ...")
runAntora(
npmDir = npmBase(),
workDir = docSite,
@@ -373,12 +373,12 @@ object `package` extends RootModule {
os.write(siteDir / ".nojekyll", "")

// sanitize devAntora source URLs
- Task.log.errorStream.println("Sanitizing links ...")
+ Task.log.streams.err.println("Sanitizing links ...")
sanitizeDevUrls(siteDir, devAntoraSources().path, build.baseDir / "docs", build.baseDir)

// only copy the "api" sub-dir; api docs contains a top-level index.html with we don't want
val unidocSrc = if (authorMode) site.unidocLocal().path else site.unidocSite().path
- Task.log.errorStream.println(s"Copying API docs from ${unidocSrc} ...")
+ Task.log.streams.err.println(s"Copying API docs from ${unidocSrc} ...")
os.copy(unidocSrc, siteDir / "api/latest", createFolders = true)

PathRef(siteDir)
2 changes: 1 addition & 1 deletion contrib/flyway/src/mill/contrib/flyway/FlywayModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ trait FlywayModule extends JavaModule {
val out =
s"""Schema version: ${currentSchemaVersion}
|${MigrationInfoDumper.dumpToAsciiTable(info.all)}""".stripMargin
Task.log.outputStream.println(out)
Task.log.streams.out.println(out)
out
}
}
Expand Down
7 changes: 0 additions & 7 deletions core/api/src/mill/api/ColorLogger.scala

This file was deleted.

97 changes: 52 additions & 45 deletions core/api/src/mill/api/Logger.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package mill.api

import java.io.{InputStream, PrintStream}
import java.io.PrintStream

/**
* The standard logging interface of the Mill build tool.
Expand All @@ -24,66 +24,73 @@ import java.io.{InputStream, PrintStream}
* but when `show` is used both are forwarded to stderr and stdout is only
* used to display the final `show` output for easy piping.
*/
trait Logger extends AutoCloseable {
trait Logger {
def infoColor: fansi.Attrs = fansi.Attrs.Empty
def errorColor: fansi.Attrs = fansi.Attrs.Empty
def colored: Boolean

private[mill] def unprefixedSystemStreams: SystemStreams = systemStreams
def systemStreams: SystemStreams

def errorStream: PrintStream = systemStreams.err
def outputStream: PrintStream = systemStreams.out

/**
* [[rawOutputStream]] is intended to be a version of [[outputStream]]
* without decoration: colors, prefixes, timestamps, etc. It is intended
* for the use of tasks like `show` which output data in a way that is
* easily readable by downstream programs.
*/
def rawOutputStream: PrintStream = systemStreams.out
def inStream: InputStream = systemStreams.in
private[mill] def unprefixedStreams: SystemStreams = streams
def streams: SystemStreams

def info(s: String): Unit
def debug(s: String): Unit
def error(s: String): Unit
def ticker(s: String): Unit

private[mill] def setPromptDetail(key: Seq[String], s: String): Unit = ticker(s)
private[mill] def reportKey(key: Seq[String]): Unit = ()
private[mill] def setPromptLine(
key: Seq[String],
verboseKeySuffix: String,
message: String
): Unit =
ticker(s"${key.mkString("-")} $message")
private[mill] def setPromptLine(): Unit = ()
private[mill] def setPromptHeaderPrefix(s: String): Unit = ()
private[mill] def clearPromptStatuses(): Unit = ()
private[mill] def removePromptLine(key: Seq[String]): Unit = ()
private[mill] def removePromptLine(): Unit = ()
private[mill] def withPromptPaused[T](t: => T): T = t
private[mill] def withPromptUnpaused[T](t: => T): T = t

/**
* @since Mill 0.10.5
*/
// We only default-implement it to keep binary compatibility in 0.10.x
def debugEnabled: Boolean = false

def close(): Unit = ()
private[mill] def prompt: Logger.Prompt

def enableTicker: Boolean = false

private[mill] def subLogger(path: os.Path, verboseKeySuffix: String, message: String): Logger =
private[mill] def subLogger(path: os.Path, keySuffix: String, message: String): Logger =
this

private[mill] def withPrompt[T](t: => T): T = {
setPromptLine()
private[mill] def withPromptLine[T](t: => T): T = {
prompt.setPromptLine(logPrefixKey, keySuffix, message)
try t
finally removePromptLine()
finally prompt.removePromptLine(logPrefixKey)
}

def withOutStream(outStream: PrintStream): Logger = this
private[mill] def message: String = ""
private[mill] def keySuffix: String = ""
private[mill] def logPrefixKey: Seq[String] = Nil
final def debugEnabled = prompt.debugEnabled
}

object Logger {

/**
* APIs that allow a logger to interact with the global prompt: setting and unsetting
* lines, enabling or disabling the prompt, etc. Normally passed through from logger
* to logger unchanged without any customization.
*/
trait Prompt {
private[mill] def setPromptDetail(key: Seq[String], s: String): Unit
private[mill] def reportKey(key: Seq[String]): Unit
private[mill] def setPromptLine(key: Seq[String], keySuffix: String, message: String): Unit
private[mill] def setPromptHeaderPrefix(s: String): Unit
private[mill] def clearPromptStatuses(): Unit
private[mill] def removePromptLine(key: Seq[String]): Unit
private[mill] def withPromptPaused[T](t: => T): T
private[mill] def withPromptUnpaused[T](t: => T): T

def debugEnabled: Boolean

def enableTicker: Boolean
}
object Prompt {
class NoOp extends Prompt {
private[mill] def setPromptDetail(key: Seq[String], s: String): Unit = ()
private[mill] def reportKey(key: Seq[String]): Unit = ()
private[mill] def setPromptLine(key: Seq[String], keySuffix: String, message: String): Unit =
()
private[mill] def setPromptHeaderPrefix(s: String): Unit = ()
private[mill] def clearPromptStatuses(): Unit = ()
private[mill] def removePromptLine(key: Seq[String]): Unit = ()
private[mill] def withPromptPaused[T](t: => T): T = t
private[mill] def withPromptUnpaused[T](t: => T): T = t

def debugEnabled: Boolean = false

def enableTicker: Boolean = false
}
}
}
6 changes: 3 additions & 3 deletions core/define/src/mill/define/Evaluator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ trait Evaluator extends AutoCloseable {
private[mill] def allowPositionalCommandArgs: Boolean
private[mill] def selectiveExecution: Boolean
private[mill] def workspace: os.Path
private[mill] def baseLogger: ColorLogger
private[mill] def baseLogger: Logger
private[mill] def outPath: os.Path
private[mill] def codeSignatures: Map[String, Int]
private[mill] def rootModule: BaseModule
private[mill] def workerCache: mutable.Map[Segments, (Int, Val)]
private[mill] def env: Map[String, String]

def withBaseLogger(newBaseLogger: ColorLogger): Evaluator
def withBaseLogger(newBaseLogger: Logger): Evaluator

def resolveSegments(
scriptArgs: Seq[String],
Expand All @@ -38,7 +38,7 @@ trait Evaluator extends AutoCloseable {
targets: Seq[Task[T]],
reporter: Int => Option[CompileProblemReporter] = _ => Option.empty[CompileProblemReporter],
testReporter: TestReporter = DummyTestReporter,
logger: ColorLogger = baseLogger,
logger: Logger = baseLogger,
serialCommandExec: Boolean = false,
selectiveExecution: Boolean = false
): Evaluator.Result[T]
Expand Down
Loading
Loading