Repository: scikit-build/scikit-build-core
Pull request #266 (2023-04-10 20:18:13)

fix: support colors without Rich present
Simple color mechanism.


codecov[bot]: ## [Codecov](https://codecov.io/gh/scikit-build/scikit-build-core/pull/266?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=scikit-build) Report
> Merging [#266](https://codecov.io/gh/scikit-build/scikit-build-core/pull/266?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=scikit-build) (516c8b2) into [main](https://codecov.io/gh/scikit-build/scikit-build-core/commit/f55716c69b7d5bbb92110c99d776647d50edb8e6?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=scikit-build) (f55716c) will **increase** coverage by `0.08%`.
> The diff coverage is `88.88%`.

```diff
@@            Coverage Diff             @@
##             main     #266      +/-   ##
==========================================
+ Coverage   88.46%   88.55%   +0.08%     
==========================================
  Files          54       54              
  Lines        2280     2289       +9     
==========================================
+ Hits         2017     2027      +10     
+ Misses        263      262       -1     
```


| [Impacted Files](https://codecov.io/gh/scikit-build/scikit-build-core/pull/266?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=scikit-build) | Coverage Δ | |
|---|---|---|
| [src/scikit\_build\_core/\_logging.py](https://codecov.io/gh/scikit-build/scikit-build-core/pull/266?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=scikit-build#diff-c3JjL3NjaWtpdF9idWlsZF9jb3JlL19sb2dnaW5nLnB5) | `84.84% <88.88%> (+4.14%)` | :arrow_up: |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=scikit-build). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=scikit-build)


Patch:
diff --git a/src/scikit_build_core/_logging.py b/src/scikit_build_core/_logging.py
index 1b201c1..f996f0a 100644
--- a/src/scikit_build_core/_logging.py
+++ b/src/scikit_build_core/_logging.py
@@ -1,6 +1,7 @@
 from __future__ import annotations
 
 import logging
+import os
 import re
 import sys
 import typing
@@ -78,19 +79,57 @@ class ScikitBuildLogger:
 logger = ScikitBuildLogger(raw_logger)
 
 
-def _strip_rich(msg: object) -> object:
-    if isinstance(msg, str):
-        return re.sub(r"\[.*?\]", "", msg)
-    return msg
+ANY_ESCAPE = re.compile(r"\[([\w\s/]*)\]")
+
+
+_COLORS = {
+    "red": "\33[91m",
+    "green": "\33[92m",
+    "yellow": "\33[93m",
+    "blue": "\33[94m",
+    "magenta": "\33[95m",
+    "cyan": "\33[96m",
+    "bold": "\33[1m",
+    "/red": "\33[0m",
+    "/green": "\33[0m",
+    "/blue": "\33[0m",
+    "/yellow": "\33[0m",
+    "/magenta": "\33[0m",
+    "/cyan": "\33[0m",
+    "/bold": "\33[22m",
+    "reset": "\33[0m",
+}
+_NO_COLORS = {color: "" for color in _COLORS}
+
+
+def colors() -> dict[str, str]:
+    if "NO_COLOR" in os.environ:
+        return _NO_COLORS
+    if os.environ.get("FORCE_COLOR", ""):
+        return _COLORS
+    if sys.stdout.isatty() and not sys.platform.startswith("win"):
+        return _COLORS
+    return _NO_COLORS
+
+
+def _process_rich(msg: object) -> str:
+    return ANY_ESCAPE.sub(
+        lambda m: "".join(colors()[x] for x in m.group(1).split()),
+        str(msg),
+    )
 
 
 def fake_rich_print(*args: object, **kwargs: object) -> None:
-    args_2 = (_strip_rich(arg) for arg in args)
+    args_2 = tuple(_process_rich(arg) for arg in args)
+    if args != args_2:
+        args_2 = (*args_2[:-1], args_2[-1] + colors()["reset"])
     print(*args_2, **kwargs)  # type: ignore[call-overload] # noqa: T201
 
 
-try:
-    from rich import print as rich_print
-except ModuleNotFoundError:
-    if not typing.TYPE_CHECKING:
+if typing.TYPE_CHECKING:
+    rich_print = fake_rich_print
+else:
+    try:
+        from rich import print as rich_print
+    except ModuleNotFoundError:
         rich_print = fake_rich_print


Test patch:
diff --git a/tests/test_logging.py b/tests/test_logging.py
index 97c79b3..4b37378 100644
--- a/tests/test_logging.py
+++ b/tests/test_logging.py
@@ -1,6 +1,13 @@
 from scikit_build_core._logging import fake_rich_print
 
 
-def test_fake_rich_print(capsys):
+def test_fake_rich_print_nocolor(capsys, monkeypatch):
+    monkeypatch.setenv("NO_COLOR", "1")
     fake_rich_print("[red]hello[/red] world", end="")
     assert capsys.readouterr().out == "hello world"
+
+
+def test_fake_rich_print_forcecolor(capsys, monkeypatch):
+    monkeypatch.setenv("FORCE_COLOR", "1")
+    fake_rich_print("[red bold]hello[/bold] world", end="")
+    assert capsys.readouterr().out == "\33[91m\33[1mhello\33[22m world\33[0m"