summaryrefslogtreecommitdiff
path: root/main/core/src/mill/util/Loggers.scala
diff options
context:
space:
mode:
Diffstat (limited to 'main/core/src/mill/util/Loggers.scala')
-rw-r--r--main/core/src/mill/util/Loggers.scala190
1 files changed, 190 insertions, 0 deletions
diff --git a/main/core/src/mill/util/Loggers.scala b/main/core/src/mill/util/Loggers.scala
new file mode 100644
index 00000000..aab1a324
--- /dev/null
+++ b/main/core/src/mill/util/Loggers.scala
@@ -0,0 +1,190 @@
+package mill.util
+
+import java.io._
+import mill.api.Logger
+
+object DummyLogger extends Logger {
+ def colored = false
+
+ object errorStream extends PrintStream(_ => ())
+ object outputStream extends PrintStream(_ => ())
+ val inStream = new ByteArrayInputStream(Array())
+
+ def info(s: String) = ()
+ def error(s: String) = ()
+ def ticker(s: String) = ()
+ def debug(s: String) = ()
+}
+
+class CallbackStream(wrapped: OutputStream,
+ setPrintState0: PrintState => Unit) extends OutputStream{
+ def setPrintState(c: Char) = {
+ setPrintState0(
+ c match{
+ case '\n' => PrintState.Newline
+ case '\r' => PrintState.Newline
+ case _ => PrintState.Middle
+ }
+ )
+ }
+ override def write(b: Array[Byte]): Unit = {
+ if (b.nonEmpty) setPrintState(b(b.length-1).toChar)
+ wrapped.write(b)
+ }
+
+ override def write(b: Array[Byte], off: Int, len: Int): Unit = {
+ if (len != 0) setPrintState(b(off+len-1).toChar)
+ wrapped.write(b, off, len)
+ }
+
+ def write(b: Int) = {
+ setPrintState(b.toChar)
+ wrapped.write(b)
+ }
+}
+sealed trait PrintState
+object PrintState{
+ case object Ticker extends PrintState
+ case object Newline extends PrintState
+ case object Middle extends PrintState
+}
+
+case class PrintLogger(
+ colored: Boolean,
+ disableTicker: Boolean,
+ colors: ammonite.util.Colors,
+ outStream: PrintStream,
+ infoStream: PrintStream,
+ errStream: PrintStream,
+ inStream: InputStream,
+ debugEnabled: Boolean
+ ) extends Logger {
+
+ var printState: PrintState = PrintState.Newline
+
+ override val errorStream = new PrintStream(new CallbackStream(errStream, printState = _))
+ override val outputStream = new PrintStream(new CallbackStream(outStream, printState = _))
+
+
+ def info(s: String) = {
+ printState = PrintState.Newline
+ infoStream.println(colors.info()(s))
+ }
+ def error(s: String) = {
+ printState = PrintState.Newline
+ errStream.println(colors.error()(s))
+ }
+ def ticker(s: String) = {
+ if(!disableTicker) {
+ printState match{
+ case PrintState.Newline =>
+ infoStream.println(colors.info()(s))
+ case PrintState.Middle =>
+ infoStream.println()
+ infoStream.println(colors.info()(s))
+ case PrintState.Ticker =>
+ val p = new PrintWriter(infoStream)
+ val nav = new ammonite.terminal.AnsiNav(p)
+ nav.up(1)
+ nav.clearLine(2)
+ nav.left(9999)
+ p.flush()
+
+ infoStream.println(colors.info()(s))
+ }
+ printState = PrintState.Ticker
+ }
+ }
+
+ def debug(s: String) = if (debugEnabled) {
+ printState = PrintState.Newline
+ errStream.println(s)
+ }
+}
+
+case class FileLogger(colored: Boolean, file: os.Path, debugEnabled: Boolean) extends Logger {
+ private[this] var outputStreamUsed: Boolean = false
+
+ lazy val outputStream = {
+ if (!outputStreamUsed) os.remove.all(file)
+ outputStreamUsed = true
+ new PrintStream(new FileOutputStream(file.toIO.getAbsolutePath))
+ }
+
+ lazy val errorStream = {
+ if (!outputStreamUsed) os.remove.all(file)
+ outputStreamUsed = true
+ new PrintStream(new FileOutputStream(file.toIO.getAbsolutePath))
+ }
+
+ def info(s: String) = outputStream.println(s)
+ def error(s: String) = outputStream.println(s)
+ def ticker(s: String) = outputStream.println(s)
+ def debug(s: String) = if (debugEnabled) outputStream.println(s)
+ val inStream: InputStream = mill.api.DummyInputStream
+ override def close() = {
+ if (outputStreamUsed)
+ outputStream.close()
+ }
+}
+
+
+
+class MultiStream(stream1: OutputStream, stream2: OutputStream) extends PrintStream(new OutputStream {
+ def write(b: Int): Unit = {
+ stream1.write(b)
+ stream2.write(b)
+ }
+ override def write(b: Array[Byte]): Unit = {
+ stream1.write(b)
+ stream2.write(b)
+ }
+ override def write(b: Array[Byte], off: Int, len: Int) = {
+ stream1.write(b, off, len)
+ stream2.write(b, off, len)
+ }
+ override def flush() = {
+ stream1.flush()
+ stream2.flush()
+ }
+ override def close() = {
+ stream1.close()
+ stream2.close()
+ }
+})
+
+case class MultiLogger(colored: Boolean, logger1: Logger, logger2: Logger) extends Logger {
+
+
+ lazy val outputStream: PrintStream = new MultiStream(logger1.outputStream, logger2.outputStream)
+
+ lazy val errorStream: PrintStream = new MultiStream(logger1.errorStream, logger2.errorStream)
+
+ lazy val inStream = Seq(logger1, logger2).collectFirst{case t: PrintLogger => t} match{
+ case Some(x) => x.inStream
+ case None => new ByteArrayInputStream(Array())
+ }
+
+ def info(s: String) = {
+ logger1.info(s)
+ logger2.info(s)
+ }
+ def error(s: String) = {
+ logger1.error(s)
+ logger2.error(s)
+ }
+ def ticker(s: String) = {
+ logger1.ticker(s)
+ logger2.ticker(s)
+ }
+
+ def debug(s: String) = {
+ logger1.debug(s)
+ logger2.debug(s)
+ }
+
+ override def close() = {
+ logger1.close()
+ logger2.close()
+ }
+}