[2.x] fix: Fixes --no-colors setting for sbtn (#8517)

This commit is contained in:
Match 2026-01-13 11:44:09 -08:00 committed by GitHub
parent bb02c3331c
commit 88e2f2704f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 86 additions and 12 deletions

View File

@ -1034,11 +1034,11 @@ object Terminal {
private def doWrite(rawBytes: Array[Byte]): Unit = withPrintStream { ps =>
val (toWrite, len) =
if (rawBytes.contains(27.toByte)) {
if (!Terminal.isAnsiSupported || !Terminal.isColorEnabled)
if (!self.isAnsiSupported || !self.isColorEnabled)
EscHelpers.strip(
rawBytes,
stripAnsi = !Terminal.isAnsiSupported,
stripColor = !Terminal.isColorEnabled
stripAnsi = !self.isAnsiSupported,
stripColor = !self.isColorEnabled
)
else (rawBytes, rawBytes.length)
} else (rawBytes, rawBytes.length)

View File

@ -0,0 +1,66 @@
/*
* sbt
* Copyright 2023, Scala center
* Copyright 2011 - 2022, Lightbend, Inc.
* Copyright 2008 - 2010, Mark Harrah
* Licensed under Apache License 2.0 (see LICENSE)
*/
package sbt.internal.util
import org.scalatest.flatspec.AnyFlatSpec
import java.io.{ ByteArrayOutputStream, InputStream }
class TerminalColorSpec extends AnyFlatSpec {
private def createTerminal(
colorEnabled: Boolean,
ansiSupported: Boolean,
out: ByteArrayOutputStream
): Terminal.TerminalImpl =
new Terminal.TerminalImpl(
new Terminal.WriteableInputStream(new InputStream { def read() = -1 }, "test"),
out,
new ByteArrayOutputStream(),
"test"
) {
private[sbt] def getSizeImpl: (Int, Int) = (80, 24)
override def isColorEnabled: Boolean = colorEnabled
override def isAnsiSupported: Boolean = ansiSupported
override private[sbt] def progressState: ProgressState = new ProgressState(1)
override def isSuccessEnabled: Boolean = true
override def isSupershellEnabled: Boolean = false
override def isEchoEnabled: Boolean = true
override def setEchoEnabled(toggle: Boolean): Unit = ()
override def getBooleanCapability(capability: String): Boolean = false
override def getNumericCapability(capability: String): Integer = null
override def getStringCapability(capability: String): String = null
override private[sbt] def getAttributes: Map[String, String] = Map.empty
override private[sbt] def setAttributes(attributes: Map[String, String]): Unit = ()
override private[sbt] def setSize(width: Int, height: Int): Unit = ()
override private[sbt] def enterRawMode(): Unit = ()
override private[sbt] def exitRawMode(): Unit = ()
}
private val ESC = "\u001b"
private val coloredText = s"$ESC[31mred text$ESC[0m"
"Terminal with colors disabled" should "strip color codes from output" in {
val out = new ByteArrayOutputStream()
val term = createTerminal(colorEnabled = false, ansiSupported = true, out)
term.outputStream.write(coloredText.getBytes("UTF-8"))
term.outputStream.flush()
val output = out.toString("UTF-8")
assert(!output.contains(ESC))
assert(output.contains("red text"))
}
"Terminal with colors enabled" should "preserve color codes in output" in {
val out = new ByteArrayOutputStream()
val term = createTerminal(colorEnabled = true, ansiSupported = true, out)
term.outputStream.write(coloredText.getBytes("UTF-8"))
term.outputStream.flush()
val output = out.toString("UTF-8")
assert(output.contains(ESC))
assert(output.contains("red text"))
}
}

View File

@ -1140,18 +1140,25 @@ object NetworkClient {
override def success(msg: String): Unit = appender.success(msg)
}
}
private def simpleConsoleInterface(doPrintln: String => Unit): ConsoleInterface =
private def simpleConsoleInterface(
doPrintln: String => Unit,
useColor: Boolean = Terminal.isColorEnabled
): ConsoleInterface =
new ConsoleInterface {
import scala.Console.{ GREEN, RED, RESET, YELLOW }
override def appendLog(level: Level.Value, message: => String): Unit = synchronized {
val prefix = level match {
case Level.Error => s"[$RED$level$RESET]"
case Level.Warn => s"[$YELLOW$level$RESET]"
case _ => s"[$RESET$level$RESET]"
}
val prefix =
if (useColor) level match {
case Level.Error => s"[$RED$level$RESET]"
case Level.Warn => s"[$YELLOW$level$RESET]"
case _ => s"[$RESET$level$RESET]"
}
else s"[$level]"
message.linesIterator.foreach(line => doPrintln(s"$prefix $line"))
}
override def success(msg: String): Unit = doPrintln(s"[${GREEN}success$RESET] $msg")
override def success(msg: String): Unit =
if (useColor) doPrintln(s"[${GREEN}success$RESET] $msg")
else doPrintln(s"[success] $msg")
}
private[client] class Arguments(
val baseDirectory: File,
@ -1331,7 +1338,7 @@ object NetworkClient {
if (terminal.getLastLine.isDefined) terminal.printStream.println()
terminal.printStream.println(line)
}
val interface = NetworkClient.simpleConsoleInterface(doPrint)
val interface = NetworkClient.simpleConsoleInterface(doPrint, terminal.isColorEnabled)
val printStream = terminal.printStream
new NetworkClient(arguments, interface, inputStream, errorStream, printStream, useJNI)
}
@ -1342,7 +1349,8 @@ object NetworkClient {
errorStream: PrintStream,
useJNI: Boolean,
): NetworkClient = {
val interface = NetworkClient.simpleConsoleInterface(printStream.println)
val interface =
NetworkClient.simpleConsoleInterface(printStream.println, Terminal.isColorEnabled)
new NetworkClient(arguments, interface, inputStream, errorStream, printStream, useJNI)
}
def main(args: Array[String]): Unit = {