diff --git a/backend/src/main/scala/bloop/logging/BloopLogger.scala b/backend/src/main/scala/bloop/logging/BloopLogger.scala index b4bbb4af17..c673ca71dd 100644 --- a/backend/src/main/scala/bloop/logging/BloopLogger.scala +++ b/backend/src/main/scala/bloop/logging/BloopLogger.scala @@ -12,12 +12,14 @@ import com.martiansoftware.nailgun.NGCommunicator * @param name The name of this logger. * @param out The stream to use to write `INFO` and `WARN` level messages. * @param err The stream to use to write `FATAL`, `ERROR`, `DEBUG` and `TRACE` level messages. + * @param colorOutput print with or without color. */ final class BloopLogger( override val name: String, out: PrintStream, err: PrintStream, - private val debugCount: Int + private val debugCount: Int, + colorOutput: Boolean ) extends Logger { override def ansiCodesSupported() = true @@ -29,8 +31,8 @@ final class BloopLogger( override def isVerbose: Boolean = debugCount > 0 override def asDiscrete: Logger = - if (debugCount > 0) new BloopLogger(name, out, err, debugCount - 1) else this - override def asVerbose: Logger = new BloopLogger(name, out, err, debugCount + 1) + if (debugCount > 0) new BloopLogger(name, out, err, debugCount - 1, colorOutput) else this + override def asVerbose: Logger = new BloopLogger(name, out, err, debugCount + 1, colorOutput) @scala.annotation.tailrec private def trace(prefix: String, exception: Throwable): Unit = { @@ -52,20 +54,28 @@ final class BloopLogger( out.println(line) } - private def printWarning(line: String): Unit = { - out.println(s"${RESET}${YELLOW}[W]${RESET} $line") + private def colored(color: String, msg: String): String = { + if (colorOutput) + s"${RESET}${color}$msg${RESET}" + else + msg + } + + + private def printWarning(line: String): Unit = { + out.println(s"${colored(YELLOW, "[W]")} $line") } private def printError(line: String): Unit = { - err.println(s"${RESET}${RED}[E]${RESET} $line") + err.println(s"${colored(RED, "[E]")} $line") } private def printTrace(line: String): Unit = { - err.println(s"${RESET}${CYAN}[T]${RESET} $line") + err.println(s"${colored(CYAN, "[T]")} $line") } private def printDebug(line: String): Unit = { - err.println(s"${RESET}${GREEN}[D]${RESET} $line") + err.println(s"${colored(GREEN, "[D]")} $line") } } @@ -80,8 +90,8 @@ object BloopLogger { * @param isVerbose Tells whether the logger is verbose or not. * @return A `BloopLogger` whose output will be written in the specified streams. */ - def at(name: String, out: PrintStream, err: PrintStream, isVerbose: Boolean): BloopLogger = - new BloopLogger(name, out, err, if (isVerbose) 1 else 0) + def at(name: String, out: PrintStream, err: PrintStream, isVerbose: Boolean, colorOutput: Boolean): BloopLogger = + new BloopLogger(name, out, err, if (isVerbose) 1 else 0, colorOutput ) /** * Instantiates a new `BloopLogger` using the specified streams. @@ -91,8 +101,8 @@ object BloopLogger { * @param err The stream to use to write `FATAL`, `ERROR`, `DEBUG` and `TRACE` level messages. * @return A `BloopLogger` whose output will be written in the specified streams. */ - def at(name: String, out: PrintStream, err: PrintStream): BloopLogger = - at(name, out, err, false) + def at(name: String, out: PrintStream, err: PrintStream, colorOutput: Boolean): BloopLogger = + at(name, out, err, false, colorOutput) /** * Instantiates a new `BloopLogger` that writes to stdout and stderr. @@ -101,6 +111,6 @@ object BloopLogger { * @return A `BloopLogger` writing to stdout and stderr. Calling this method is equivalent to * calling `at(name, System.out, System.err)`. */ - def default(name: String): BloopLogger = at(name, System.out, System.err) + def default(name: String): BloopLogger = at(name, System.out, System.err, false) } diff --git a/benchmarks/src/main/scala/bloop/logging/BloopLoggerBenchmark.scala b/benchmarks/src/main/scala/bloop/logging/BloopLoggerBenchmark.scala index bacd7f1236..de25659bb5 100644 --- a/benchmarks/src/main/scala/bloop/logging/BloopLoggerBenchmark.scala +++ b/benchmarks/src/main/scala/bloop/logging/BloopLoggerBenchmark.scala @@ -6,7 +6,7 @@ import org.openjdk.jmh.annotations.Benchmark object BloopLoggerBenchmark { private val devnull = new PrintStream(_ => ()) - val logger = BloopLogger.at("benchmark", devnull, devnull) + val logger = BloopLogger.at("benchmark", devnull, devnull, false) } class BloopLoggerBenchmark { diff --git a/frontend/src/main/scala/bloop/Cli.scala b/frontend/src/main/scala/bloop/Cli.scala index a1a6af6ee1..0bbbdc9cf3 100644 --- a/frontend/src/main/scala/bloop/Cli.scala +++ b/frontend/src/main/scala/bloop/Cli.scala @@ -228,8 +228,14 @@ object Cli { val commonOpts = cliOptions.common val configDirectory = getConfigDir(cliOptions) - val logger = - BloopLogger.at(configDirectory.syntax, commonOpts.out, commonOpts.err, cliOptions.verbose) + val logger = BloopLogger.at( + configDirectory.syntax, + commonOpts.out, + commonOpts.err, + cliOptions.verbose, + !(cliOptions.noColor || commonOpts.env.containsKey("NO_COLOR")) + ) + val currentState = State.loadActiveStateFor(configDirectory, pool, cliOptions.common, logger) if (Files.exists(configDirectory.underlying)) { diff --git a/frontend/src/main/scala/bloop/cli/CliOptions.scala b/frontend/src/main/scala/bloop/cli/CliOptions.scala index c2e8c9655c..bcb19b1669 100644 --- a/frontend/src/main/scala/bloop/cli/CliOptions.scala +++ b/frontend/src/main/scala/bloop/cli/CliOptions.scala @@ -14,6 +14,8 @@ case class CliOptions( version: Boolean = false, @HelpMessage("If set, print out debugging information to stderr.") verbose: Boolean = false, + @HelpMessage("If set, do not color output.") + noColor: Boolean = false, @Recurse common: CommonOptions = CommonOptions.default, ) diff --git a/frontend/src/test/scala/bloop/engine/FileWatchingSpec.scala b/frontend/src/test/scala/bloop/engine/FileWatchingSpec.scala index 0e96b073fc..1101315396 100644 --- a/frontend/src/test/scala/bloop/engine/FileWatchingSpec.scala +++ b/frontend/src/test/scala/bloop/engine/FileWatchingSpec.scala @@ -90,7 +90,7 @@ class FileWatchingSpec { val cliOptions0 = CliOptions.default val newOut = new PrintStream(bloopOut) val loggerName = UUID.randomUUID().toString - val newLogger = BloopLogger.at(loggerName, newOut, newOut) + val newLogger = BloopLogger.at(loggerName, newOut, newOut, false) val newState = state.copy(logger = newLogger) val commonOptions = cliOptions0.common.copy(out = newOut) val cliOptions = cliOptions0.copy(common = commonOptions) @@ -137,7 +137,7 @@ class FileWatchingSpec { val cliOptions0 = CliOptions.default val newOut = new PrintStream(bloopOut) val loggerName = UUID.randomUUID().toString - val newLogger = BloopLogger.at(loggerName, newOut, newOut).asVerbose + val newLogger = BloopLogger.at(loggerName, newOut, newOut, false).asVerbose val newState = state.copy(logger = newLogger) val commonOptions1 = state.commonOptions.copy(out = newOut) val cliOptions = cliOptions0.copy(common = commonOptions1) diff --git a/frontend/src/test/scala/bloop/engine/InterpreterSpec.scala b/frontend/src/test/scala/bloop/engine/InterpreterSpec.scala index 96568e6494..6a78fb4616 100644 --- a/frontend/src/test/scala/bloop/engine/InterpreterSpec.scala +++ b/frontend/src/test/scala/bloop/engine/InterpreterSpec.scala @@ -72,7 +72,7 @@ object InterpreterSpec { val inMemory = new ByteArrayOutputStream() val newOut = new PrintStream(inMemory) val loggerName = UUID.randomUUID().toString - val newLogger = BloopLogger.at(loggerName, newOut, newOut) + val newLogger = BloopLogger.at(loggerName, newOut, newOut, false) val defaultCli = CliOptions.default val newCommonOptions = state.commonOptions.copy(out = newOut) val newState = state.copy(logger = newLogger, commonOptions = newCommonOptions) diff --git a/frontend/src/test/scala/bloop/logging/BloopLoggerSpec.scala b/frontend/src/test/scala/bloop/logging/BloopLoggerSpec.scala index 1b61de51d7..8ee3414b95 100644 --- a/frontend/src/test/scala/bloop/logging/BloopLoggerSpec.scala +++ b/frontend/src/test/scala/bloop/logging/BloopLoggerSpec.scala @@ -114,8 +114,8 @@ class BloopLoggerSpec { val bos1 = new ByteArrayOutputStream val ps1 = new PrintStream(bos1) - val l0 = BloopLogger.at("l0", ps0, ps0) - val l1 = BloopLogger.at("l1", ps1, ps1) + val l0 = BloopLogger.at("l0", ps0, ps0, false) + val l1 = BloopLogger.at("l1", ps1, ps1, false) l0.info("info0") l1.info("info1") @@ -135,12 +135,12 @@ class BloopLoggerSpec { val bos0 = new ByteArrayOutputStream val ps0 = new PrintStream(bos0) - val l0 = BloopLogger.at(loggerName, ps0, ps0) + val l0 = BloopLogger.at(loggerName, ps0, ps0, false) l0.info("info0") val bos1 = new ByteArrayOutputStream val ps1 = new PrintStream(bos1) - val l1 = BloopLogger.at(loggerName, ps1, ps1) + val l1 = BloopLogger.at(loggerName, ps1, ps1, false) l1.info("info1") val msgs0 = convertAndReadAllFrom(bos0) @@ -189,7 +189,7 @@ class BloopLoggerSpec { val err = new PrintStream(errStream) val loggerName = UUID.randomUUID().toString - val logger = BloopLogger.at(loggerName, out, err) + val logger = BloopLogger.at(loggerName, out, err, false) op(logger) val outMessages = convertAndReadAllFrom(outStream)