Skip to content

Commit 75481fc

Browse files
committed
Initial implementation
1 parent dab0fda commit 75481fc

File tree

4 files changed

+88
-0
lines changed

4 files changed

+88
-0
lines changed

colcon_ansi_colors_example/output_style/__init__.py

Whitespace-only changes.
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# Copyright 2025 Open Source Robotics Foundation, Inc.
2+
# Licensed under the Apache License, Version 2.0
3+
4+
import os
5+
6+
from colcon_core.output_style import OutputStyleExtensionPoint
7+
from colcon_core.output_style import Stylizer
8+
from colcon_core.plugin_system import satisfies_version
9+
10+
11+
class AnsiEscape(Stylizer):
12+
"""ANSI text style modifier."""
13+
14+
__slots__ = ()
15+
16+
def __new__(cls, start, end=0): # noqa: D102
17+
return super().__new__(
18+
cls, f'\033[{start}m',
19+
f'\033[{end}m' if end is not None else '')
20+
21+
def __add__(self, other): # noqa: D105
22+
if not isinstance(other, AnsiEscape):
23+
return super().__add__(other)
24+
return AnsiEscape(
25+
self._combine(self.start, other.start),
26+
self._combine(other.end, self.end))
27+
28+
@staticmethod
29+
def _combine(first, second):
30+
if not second or first == second:
31+
return first
32+
elif not first:
33+
return second
34+
first = first[2:-1]
35+
second = second[2:-1]
36+
return f'{first};{second}'
37+
38+
39+
AnsiEscape.Black = AnsiEscape(30)
40+
AnsiEscape.Blue = AnsiEscape(34)
41+
AnsiEscape.Bright = AnsiEscape(1, 22)
42+
AnsiEscape.Cyan = AnsiEscape(36)
43+
AnsiEscape.Default = AnsiEscape(39, None) + AnsiEscape(49, None)
44+
AnsiEscape.Faint = AnsiEscape(2, 22)
45+
AnsiEscape.Flashing = AnsiEscape(5, 25)
46+
AnsiEscape.Green = AnsiEscape(32)
47+
AnsiEscape.Invert = AnsiEscape(7, 27)
48+
AnsiEscape.Italic = AnsiEscape(3, 23)
49+
AnsiEscape.Magenta = AnsiEscape(35)
50+
AnsiEscape.Red = AnsiEscape(31)
51+
AnsiEscape.Strike = AnsiEscape(9, 29)
52+
AnsiEscape.Underline = AnsiEscape(4, 24)
53+
AnsiEscape.White = AnsiEscape(37)
54+
AnsiEscape.Yellow = AnsiEscape(33)
55+
56+
57+
class CatkinToolsOutputStyle(OutputStyleExtensionPoint):
58+
"""Basic ANSI colorizing for console output like catkin-tools."""
59+
60+
PRIORITY = 90
61+
62+
def __init__(self): # noqa: D107
63+
super().__init__()
64+
satisfies_version(
65+
OutputStyleExtensionPoint.EXTENSION_POINT_VERSION, '^1.0')
66+
67+
def apply_style(self, style): # noqa: D102
68+
if os.environ.get('NO_COLOR'):
69+
return
70+
71+
style.Critical = AnsiEscape.Bright + AnsiEscape.Red
72+
style.Default = AnsiEscape.Default
73+
style.Error = AnsiEscape.Red
74+
style.Measurement = AnsiEscape.Yellow
75+
style.PackageOrJobName = AnsiEscape.Cyan
76+
style.Pictogram = AnsiEscape.Bright + AnsiEscape.Green
77+
style.SectionStart = AnsiEscape.Default
78+
style.SectionEnd = AnsiEscape.Bright + AnsiEscape.Black
79+
style.Strong = AnsiEscape.Bright
80+
style.Success = AnsiEscape.Green
81+
style.Warning = AnsiEscape.Yellow
82+
style.Weak = AnsiEscape.Faint

setup.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ markers =
5252
linter
5353

5454
[options.entry_points]
55+
colcon_core.output_style =
56+
catkin_tools = colcon_ansi_colors_example.output_style.catkin_tools:CatkinToolsOutputStyle
5557

5658
[flake8]
5759
import-order-style = google

test/spell_check.words

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@ apache
33
colcon
44
iterdir
55
linter
6+
noqa
67
pathlib
8+
plugin
79
pydocstyle
810
pytest
911
scspell
1012
setuptools
13+
staticmethod
14+
stylizer
1115
thomas

0 commit comments

Comments
 (0)