Skip to content

Commit e9fcacd

Browse files
committed
fix(cli[colors]): Let explicit color override NO_COLOR
why: The test environment sets NO_COLOR, but explicit color requests are command choices and should still force ANSI output for tests and --color=always-style paths. what: - Make ColorMode.ALWAYS take precedence over NO_COLOR - Keep ColorMode.AUTO respecting NO_COLOR - Add regression coverage for both precedence paths
1 parent c15a705 commit e9fcacd

2 files changed

Lines changed: 50 additions & 4 deletions

File tree

src/vcspull/cli/_colors.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,36 @@ def __init__(self, mode: ColorMode = ColorMode.AUTO) -> None:
4343
def _should_enable_color(self) -> bool:
4444
"""Determine if color should be enabled.
4545
46+
Explicit color modes are command choices and take precedence over
47+
environment defaults:
48+
49+
>>> import os
50+
>>> from vcspull.cli._colors import ColorMode, Colors
51+
>>> previous = os.environ.get("NO_COLOR")
52+
>>> os.environ["NO_COLOR"] = "1"
53+
>>> Colors(ColorMode.ALWAYS)._should_enable_color()
54+
True
55+
>>> Colors(ColorMode.NEVER)._should_enable_color()
56+
False
57+
>>> if previous is None:
58+
... _ = os.environ.pop("NO_COLOR", None)
59+
... else:
60+
... os.environ["NO_COLOR"] = previous
61+
4662
Returns
4763
-------
4864
bool
4965
True if colors should be enabled
5066
"""
51-
# Respect NO_COLOR environment variable
52-
if os.environ.get("NO_COLOR"):
53-
return False
54-
5567
if self.mode == ColorMode.NEVER:
5668
return False
5769
if self.mode == ColorMode.ALWAYS:
5870
return True
5971

72+
# Respect NO_COLOR environment variable for AUTO mode.
73+
if os.environ.get("NO_COLOR"):
74+
return False
75+
6076
# AUTO mode: check if stdout is a TTY
6177
return sys.stdout.isatty()
6278

tests/cli/test_colors.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"""Tests for vcspull CLI color mode resolution."""
2+
3+
from __future__ import annotations
4+
5+
import typing as t
6+
7+
from vcspull.cli._colors import ColorMode, Colors
8+
9+
if t.TYPE_CHECKING:
10+
from _pytest.monkeypatch import MonkeyPatch
11+
12+
13+
def test_color_mode_always_overrides_no_color(monkeypatch: MonkeyPatch) -> None:
14+
"""An explicit color request wins over the NO_COLOR environment default."""
15+
monkeypatch.setenv("NO_COLOR", "1")
16+
17+
colors = Colors(ColorMode.ALWAYS)
18+
19+
assert colors._enabled
20+
assert colors.info("repo") != "repo"
21+
22+
23+
def test_color_mode_auto_respects_no_color(monkeypatch: MonkeyPatch) -> None:
24+
"""Automatic color mode still respects NO_COLOR."""
25+
monkeypatch.setenv("NO_COLOR", "1")
26+
27+
colors = Colors(ColorMode.AUTO)
28+
29+
assert not colors._enabled
30+
assert colors.info("repo") == "repo"

0 commit comments

Comments
 (0)