diff options
| author | Paolo Bonzini <pbonzini@redhat.com> | 2024-11-20 08:50:55 +0100 |
|---|---|---|
| committer | Dylan Baker <dylan@pnwbakers.com> | 2024-12-19 09:25:20 -0800 |
| commit | ef612343d90a79a49b9116e4cf7afb07eaa08ab4 (patch) | |
| tree | b0b2caab3e26787170c2cfdfa25d9529a5bd5a63 /mesonbuild/scripts | |
| parent | 15c2c9811411e5e84419bcee487fb3a84ac2756c (diff) | |
| download | meson-ef612343d90a79a49b9116e4cf7afb07eaa08ab4.tar.gz | |
scripts: make clang tools obey b_colorout
Right now, the clang-tidy and clang-format targets use the program default
and do not let b_colorout decide whether to colorize output.
However, the wrappers that run the tool are going to be changed to buffer
output, and that would disable colorization unconditionally. So pass
a --color option to the tools and use it when building the command line.
clang-format's -fcolor-diagnostics option simply does not work, and the
"right" (or at least working) option is --color which is undocumented.
--color is present all the way back to clang 10, but I digged into
clang-format's source code to figure out what's happening. The problem
is that -fcolor-diagnostics is a complete no-operation; in fact it is
a bool that is initialized to true. gdb shows:
(gdb) p ShowColors
$2 = {<llvm::cl::Option> = {
... <llvm::cl::opt_storage<bool, false, false>> = {Value = true, ... }, ...}
on entry to clang-format's main, meaning that specifying the option on
the command line does nothing at all.
To see how clang-format determines whether to use colors you need to look
at enters SMDiagnostic::print, which simply does
ColorMode Mode = ShowColors ? ColorMode::Auto : ColorMode::Disable;
showing once more that in fact the option cannot force-on the colors (
-fno-color-diagnostics instead works). Continuing in SMDiagnostic::print,
this RAII constructor would write the escape sequence to the terminal:
WithColor S(OS, raw_ostream::SAVEDCOLOR, true, false, Mode);
It ends up in WithColor::changeColor, which does
if (colorsEnabled())
OS.changeColor(Color, Bold, BG);
Digging further down, colorsEnabled() is where the Mode member is consulted:
bool WithColor::colorsEnabled() {
switch (Mode) {
case ColorMode::Enable:
return true;
case ColorMode::Disable:
return false;
case ColorMode::Auto:
return AutoDetectFunction(OS);
}
llvm_unreachable("All cases handled above.");
}
and the "AutoDetectFunction" is
static bool DefaultAutoDetectFunction(const raw_ostream &OS) {
return *UseColor == cl::BOU_UNSET ? OS.has_colors()
: *UseColor == cl::BOU_TRUE;
}
UseColor is controlled by the "--color" option, so if that option was
unset you go to OS.has_colors() even in the presence of -fcolor-diagnostics.
This has been around for over 5 years in clang-format, and it was present
even earlier, so use it in meson as well.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'mesonbuild/scripts')
| -rw-r--r-- | mesonbuild/scripts/clangformat.py | 13 | ||||
| -rw-r--r-- | mesonbuild/scripts/clangtidy.py | 4 |
2 files changed, 13 insertions, 4 deletions
diff --git a/mesonbuild/scripts/clangformat.py b/mesonbuild/scripts/clangformat.py index 9ce050458..88cc89071 100644 --- a/mesonbuild/scripts/clangformat.py +++ b/mesonbuild/scripts/clangformat.py @@ -6,6 +6,7 @@ from __future__ import annotations import argparse import subprocess from pathlib import Path +import sys from .run_tool import run_tool from ..environment import detect_clangformat @@ -13,12 +14,15 @@ from ..mesonlib import version_compare from ..programs import ExternalProgram import typing as T -def run_clang_format(fname: Path, exelist: T.List[str], check: bool, cformat_ver: T.Optional[str]) -> subprocess.CompletedProcess: +def run_clang_format(fname: Path, exelist: T.List[str], options: argparse.Namespace, cformat_ver: T.Optional[str]) -> subprocess.CompletedProcess: clangformat_10 = False - if check and cformat_ver: + if options.check and cformat_ver: if version_compare(cformat_ver, '>=10'): clangformat_10 = True exelist = exelist + ['--dry-run', '--Werror'] + # The option is not documented but it exists in version 10 + if options.color == 'always' or options.color == 'auto' and sys.stdout.isatty(): + exelist += ['--color=1'] else: original = fname.read_bytes() before = fname.stat().st_mtime @@ -26,7 +30,7 @@ def run_clang_format(fname: Path, exelist: T.List[str], check: bool, cformat_ver after = fname.stat().st_mtime if before != after: print('File reformatted: ', fname) - if check and not clangformat_10: + if options.check and not clangformat_10: # Restore the original if only checking. fname.write_bytes(original) ret.returncode = 1 @@ -35,6 +39,7 @@ def run_clang_format(fname: Path, exelist: T.List[str], check: bool, cformat_ver def run(args: T.List[str]) -> int: parser = argparse.ArgumentParser() parser.add_argument('--check', action='store_true') + parser.add_argument('--color', default='always') parser.add_argument('sourcedir') parser.add_argument('builddir') options = parser.parse_args(args) @@ -52,4 +57,4 @@ def run(args: T.List[str]) -> int: else: cformat_ver = None - return run_tool('clang-format', srcdir, builddir, run_clang_format, exelist, options.check, cformat_ver) + return run_tool('clang-format', srcdir, builddir, run_clang_format, exelist, options, cformat_ver) diff --git a/mesonbuild/scripts/clangtidy.py b/mesonbuild/scripts/clangtidy.py index a922f8514..fe34801e0 100644 --- a/mesonbuild/scripts/clangtidy.py +++ b/mesonbuild/scripts/clangtidy.py @@ -26,6 +26,7 @@ def run_clang_tidy(fname: Path, tidyexe: list, builddir: Path, fixesdir: T.Optio def run(args: T.List[str]) -> int: parser = argparse.ArgumentParser() parser.add_argument('--fix', action='store_true') + parser.add_argument('--color', default='always') parser.add_argument('sourcedir') parser.add_argument('builddir') options = parser.parse_args(args) @@ -38,6 +39,9 @@ def run(args: T.List[str]) -> int: print(f'Could not execute clang-tidy "{" ".join(tidyexe)}"') return 1 + if options.color == 'always' or options.color == 'auto' and sys.stdout.isatty(): + tidyexe += ['--use-color'] + fixesdir: T.Optional[Path] = None if options.fix: applyexe = detect_clangapply() |
