From 2e50667c9bcb6a137925ce66ca966074bef06bcd Mon Sep 17 00:00:00 2001 From: d_m Date: Tue, 19 Sep 2023 22:01:00 -0400 Subject: [PATCH] Honor the NO_COLOR environment variable. As per https://no-color.org/ this change will disable ANSI colors if the NO_COLOR environment variable is set to any non-empty string. (If the environment variable is unset or set to the empty string then the default colors will still be used.) This builds on the work of https://github.com/scalameta/munit/pull/651 but attempts to minimize the size of the patch. --- .../main/java/munit/internal/junitinterface/Ansi.java | 9 ++++++++- .../munit/internal/junitinterface/JUnitReporter.scala | 8 ++++---- .../main/scala/munit/internal/console/AnsiColors.scala | 8 +++++++- .../src/main/scala/munit/internal/console/Lines.scala | 4 ++-- .../src/main/scala/munit/internal/difflib/Diff.scala | 8 +++++--- 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/junit-interface/src/main/java/munit/internal/junitinterface/Ansi.java b/junit-interface/src/main/java/munit/internal/junitinterface/Ansi.java index 41252f55..987d041a 100644 --- a/junit-interface/src/main/java/munit/internal/junitinterface/Ansi.java +++ b/junit-interface/src/main/java/munit/internal/junitinterface/Ansi.java @@ -22,8 +22,15 @@ public class Ansi { private static final String LIGHT_MAGENTA = "\u001B[95m"; private static final String LIGHT_CYAN = "\u001B[96m"; + private static final boolean noColor = shouldDisableColor(); + + private static final boolean shouldDisableColor() { + String noColorEnv = System.getenv("NO_COLOR"); + return noColorEnv != null && noColorEnv.length() > 0; + } + public static String c(String s, String colorSequence) { - if (colorSequence == null) return s; + if (colorSequence == null || noColor) return s; else return colorSequence + s + NORMAL; } diff --git a/munit/js-native/src/main/scala/munit/internal/junitinterface/JUnitReporter.scala b/munit/js-native/src/main/scala/munit/internal/junitinterface/JUnitReporter.scala index be7e5a2c..a65fdefc 100644 --- a/munit/js-native/src/main/scala/munit/internal/junitinterface/JUnitReporter.scala +++ b/munit/js-native/src/main/scala/munit/internal/junitinterface/JUnitReporter.scala @@ -230,11 +230,11 @@ final class JUnitReporter( } val canHighlight = !PlatformCompat.isNative new StringBuilder() - .append(AnsiColors.Reset) + .append(AnsiColors.use(AnsiColors.Reset)) .append( if (!canHighlight) "" - else if (highlight) AnsiColors.Bold - else AnsiColors.DarkGrey + else if (highlight) AnsiColors.use(AnsiColors.Bold) + else AnsiColors.use(AnsiColors.DarkGrey) ) .append(" at ") .append(settings.decodeName(e.getClassName + '.' + e.getMethodName)) @@ -259,7 +259,7 @@ final class JUnitReporter( } ) .append(')') - .append(AnsiColors.Reset) + .append(AnsiColors.use(AnsiColors.Reset)) .toString() } private def formatTime(elapsedMillis: Double): String = diff --git a/munit/shared/src/main/scala/munit/internal/console/AnsiColors.scala b/munit/shared/src/main/scala/munit/internal/console/AnsiColors.scala index dad6004d..4ad41ed8 100644 --- a/munit/shared/src/main/scala/munit/internal/console/AnsiColors.scala +++ b/munit/shared/src/main/scala/munit/internal/console/AnsiColors.scala @@ -15,8 +15,14 @@ object AnsiColors { val GREEN = "\u001B[32m" val DarkGrey = "\u001B[90m" + val noColor: Boolean = + Option(System.getenv("NO_COLOR")).exists(_ != "") + + def use(colorSequence: String): String = + if (noColor) "" else colorSequence + def c(s: String, colorSequence: String): String = - if (colorSequence == null) s + if (colorSequence == null || noColor) s else colorSequence + s + Reset def filterAnsi(s: String): String = { diff --git a/munit/shared/src/main/scala/munit/internal/console/Lines.scala b/munit/shared/src/main/scala/munit/internal/console/Lines.scala index abe295a7..9f792151 100644 --- a/munit/shared/src/main/scala/munit/internal/console/Lines.scala +++ b/munit/shared/src/main/scala/munit/internal/console/Lines.scala @@ -44,10 +44,10 @@ class Lines extends Serializable { .append(format(location.line - 1)) .append(slice(0)) .append('\n') - .append(AnsiColors.Reversed) + .append(AnsiColors.use(AnsiColors.Reversed)) .append(format(location.line)) .append(slice(1)) - .append(AnsiColors.Reset) + .append(AnsiColors.use(AnsiColors.Reset)) if (slice.length >= 3) out .append('\n') diff --git a/munit/shared/src/main/scala/munit/internal/difflib/Diff.scala b/munit/shared/src/main/scala/munit/internal/difflib/Diff.scala index 458c54e6..80369302 100644 --- a/munit/shared/src/main/scala/munit/internal/difflib/Diff.scala +++ b/munit/shared/src/main/scala/munit/internal/difflib/Diff.scala @@ -43,9 +43,11 @@ class Diff(val obtained: String, val expected: String) extends Serializable { private def appendDiffOnlyReport(sb: StringBuilder): Unit = { header("Diff", sb) - sb.append( - s" (${AnsiColors.LightRed}- obtained${AnsiColors.Reset}, ${AnsiColors.LightGreen}+ expected${AnsiColors.Reset})" - ).append("\n") + val red = AnsiColors.use(AnsiColors.LightRed) + val reset = AnsiColors.use(AnsiColors.Reset) + val green = AnsiColors.use(AnsiColors.LightGreen) + sb.append(s" (${red}- obtained${reset}, ${green}+ expected${reset})") + sb.append("\n") sb.append(unifiedDiff) }