[clang] da0a7d5 - Add support for the NO_COLOR environment variable

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 7 08:55:27 PDT 2023


Author: Aaron Ballman
Date: 2023-06-07T11:55:06-04:00
New Revision: da0a7d5cfb0c65bcb54a1ba5ed6c93bb906648e4

URL: https://github.com/llvm/llvm-project/commit/da0a7d5cfb0c65bcb54a1ba5ed6c93bb906648e4
DIFF: https://github.com/llvm/llvm-project/commit/da0a7d5cfb0c65bcb54a1ba5ed6c93bb906648e4.diff

LOG: Add support for the NO_COLOR environment variable

Clang currently supports disabling color diagnostic output via
-fno-color-diagnostics. However, there is a somewhat long-standing push
to support use of an environment variable to override color output so
that users can set up their terminal such that most color output is
disabled (largely for accessibility reasons).

There are two competing de facto standards to accomplish this:
  NO_COLOR (https://no-color.org/) and
  CLICOLOR/CLICOLOR_FORCE (http://bixense.com/clicolors/).

This patch adds support for NO_COLOR as that appears to be the more
commonly supported feature, at least when comparing issues and pull
requests:
https://github.com/search?q=NO_COLOR&type=issues (2.2k issues, 35k pull requests)
https://github.com/search?q=CLICOLOR&type=issues (1k issues, 3k pull requests)

It's also the more straightforward and thoroughly-specified of the two
options. If NO_COLOR is present as an environment variable (regardless
of value), color output is suppressed unless the command line specifies
use of color output (command line takes precedence over the environment
variable).

Differential Revision: https://reviews.llvm.org/D152285

Added: 
    clang/test/Driver/no-color.c

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/docs/UsersManual.rst
    clang/lib/Frontend/CompilerInvocation.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 733a003f5321b..295b3b9c99f88 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -222,6 +222,8 @@ Non-comprehensive list of changes in this release
 - Clang now support ``__builtin_FUNCSIG()`` which returns the same information
   as the ``__FUNCSIG__`` macro (available only with ``-fms-extensions`` flag).
   This fixes (`#58951 <https://github.com/llvm/llvm-project/issues/58951>`_).
+- Clang now supports the `NO_COLOR <https://no-color.org/>`_ environment
+  variable as a way to disable color diagnostics.
 
 New Compiler Flags
 ------------------

diff  --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst
index 6b597242e3f93..8c98b693c4511 100644
--- a/clang/docs/UsersManual.rst
+++ b/clang/docs/UsersManual.rst
@@ -251,6 +251,11 @@ output format of the diagnostics that it generates.
                 ^
                 //
 
+   If the ``NO_COLOR`` environment variable is defined and not empty
+   (regardless of value), color diagnostics are disabled. If ``NO_COLOR`` is
+   defined and ``-fcolor-diagnostics`` is passed on the command line, Clang
+   will honor the command line argument.
+
 .. option:: -fansi-escape-codes
 
    Controls whether ANSI escape codes are used instead of the Windows Console

diff  --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index f74bca3b33b1d..0ce26fd68782c 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -2341,10 +2341,20 @@ clang::CreateAndPopulateDiagOpts(ArrayRef<const char *> Argv) {
   unsigned MissingArgIndex, MissingArgCount;
   InputArgList Args = getDriverOptTable().ParseArgs(
       Argv.slice(1), MissingArgIndex, MissingArgCount);
+
+  bool ShowColors = true;
+  if (std::optional<std::string> NoColor =
+          llvm::sys::Process::GetEnv("NO_COLOR");
+      NoColor && !NoColor->empty()) {
+    // If the user set the NO_COLOR environment variable, we'll honor that
+    // unless the command line overrides it.
+    ShowColors = false;
+  }
+
   // We ignore MissingArgCount and the return value of ParseDiagnosticArgs.
   // Any errors that would be diagnosed here will also be diagnosed later,
   // when the DiagnosticsEngine actually exists.
-  (void)ParseDiagnosticArgs(*DiagOpts, Args);
+  (void)ParseDiagnosticArgs(*DiagOpts, Args, /*Diags=*/nullptr, ShowColors);
   return DiagOpts;
 }
 

diff  --git a/clang/test/Driver/no-color.c b/clang/test/Driver/no-color.c
new file mode 100644
index 0000000000000..6c5d16039d1ff
--- /dev/null
+++ b/clang/test/Driver/no-color.c
@@ -0,0 +1,17 @@
+// RUN: env NO_COLOR=1 %clang -### %s 2>&1 | FileCheck --check-prefix=NO-COLOR %s
+// RUN: env NO_COLOR=1 %clang -fcolor-diagnostics -### %s 2>&1 | FileCheck --check-prefix=COLOR %s
+// RUN: env NO_COLOR=1 %clang -fdiagnostics-color=auto -### %s 2>&1 | FileCheck --check-prefix=NO-COLOR %s
+// RUN: env NO_COLOR=1 %clang -fdiagnostics-color=always -### %s 2>&1 | FileCheck --check-prefix=COLOR %s
+// RUN: env NO_COLOR=1 %clang -fdiagnostics-color=never -### %s 2>&1 | FileCheck --check-prefix=NO-COLOR %s
+
+// Note, the value of the environment variable does not matter, only that it is defined and not empty.
+// RUN: env NO_COLOR=0 %clang -### %s 2>&1 | FileCheck --check-prefix=NO-COLOR %s
+// Note, an empty value means we automatically decide whether to enable colors or not, and lit tests
+// are not run in a PTY, so colors are disabled by default. There is no easy way for us to test this
+// configuration where auto enables colors.
+// RUN: env NO_COLOR= %clang -### %s 2>&1 | FileCheck --check-prefix=NO-COLOR %s
+
+int main(void) {}
+
+// COLOR: -fcolor-diagnostics
+// NO-COLOR-NOT: -fcolor-diagnostics


        


More information about the cfe-commits mailing list