Skip to content

feat: add optional colorized output support#1223

Open
penww wants to merge 1 commit into
ros2:rollingfrom
penww:feature/colorize
Open

feat: add optional colorized output support#1223
penww wants to merge 1 commit into
ros2:rollingfrom
penww:feature/colorize

Conversation

@penww
Copy link
Copy Markdown

@penww penww commented Apr 20, 2026

Description

Fixes #1222

Add ros2cli/color.py with an extensible colorizer framework that wraps sys.stdout and applies ANSI colors line-by-line. Colorizers are registered per (command, verb) pair; unregistered commands fall back to DefaultColorizer.

Colorized output is activated when ROS_COLORIZED_OUTPUT=1 and stdout is a TTY, or via the new --color CLI flag.

ros2color

Is this user-facing behavior change?

No.

  • No behavioral change when --color is not passed and ROS_COLORIZED_OUTPUT is unset.
  • It only takes effect when stdout is a TTY, so it does not break pipe commands.

Did you use Generative AI?

Yes, partially with Claude Sonnet 4.6

Additional Information

@penww penww force-pushed the feature/colorize branch from f1130bc to 885f419 Compare April 20, 2026 02:31
Add ros2cli/color.py with an extensible colorizer framework that wraps
sys.stdout and applies ANSI colors line-by-line. Colorizers are
registered per (command, verb) pair; unregistered commands fall back to
DefaultColorizer.

Colorized output is activated when ROS_COLORIZED_OUTPUT=1 and stdout is
a TTY, or via the new --color CLI flag.

Signed-off-by: Peng Wang <penwang@qti.qualcomm.com>
@penww penww force-pushed the feature/colorize branch from 885f419 to aef6481 Compare April 20, 2026 02:47
@StefanFabian
Copy link
Copy Markdown

This parses the output from existing commands to colorize them. Why did you choose this over adding the color output directly to the commands?
In my opinion, this would be less fragile, since any change to the output formatting could break your colorizers, if I'm not mistaken.

@kscottz
Copy link
Copy Markdown

kscottz commented Apr 20, 2026

@StefanFabian that's an astute observation. It feels like the right solution here is a standard base package that can be used by all of the CLI commands that then bubbles up to the final CLI. That's a big re-factor but probably worth it. It would make a fantastic student project for next year.

@penww
Copy link
Copy Markdown
Author

penww commented Apr 21, 2026

@StefanFabian @kscottz Thanks for your feedback. I fully agree with your observation that a colorizer is easy to break when output formatting changes. A more robust solution would be to update the output of all commands directly, but that would be a significant effort, as many commands currently rely on extensive use of raw print() and string concatenation.

print(args.node_name)
subscribers = get_subscriber_info(
node=node, remote_node_name=args.node_name, include_hidden=args.include_hidden)
print(' Subscribers:')
print_names_and_types(subscribers)
publishers = get_publisher_info(
node=node, remote_node_name=args.node_name, include_hidden=args.include_hidden)
print(' Publishers:')

def print_names_and_types(names_and_types):
print(*[2 * ' ' + s.name + ': ' + ', '.join(s.types) for s in names_and_types], sep='\n')

I will continue tracking this feature and am willing to commit the effort required for a larger refactor if it becomes necessary.

@fujitatomoya fujitatomoya self-assigned this Apr 21, 2026
Copy link
Copy Markdown
Collaborator

@fujitatomoya fujitatomoya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not intend to take this PR as it is. i do agree with @StefanFabian 's comment, this is so easy to break because it couples a side-module to the exact text format of every command's output.
what's worse with this PR is, every output-format change becomes a silent breakage vector and the coupling is invisible from the command's side. this will be hard to maintain, i believe.

A more robust solution would be to update the output of all commands directly, but that would be a significant effort, as many commands currently rely on extensive use of raw print() and string concatenation.

what i would do is, (as @kscottz gestured at it) formatting/printing utility that individual commands opt into, so that color is produced at the source where the semantic meaning of each token is known such as a node name, a topic type, a warning and so on. this utility can be applied to each command and sub-command with token attribution. this seems to be straight-forward change for me but this would be much bigger change, we probably need to have more discussion on the basic design 1st.

@kscottz
Copy link
Copy Markdown

kscottz commented Apr 22, 2026

This might be a good use case for Github's DRAFT PR feature.

@penww you're more than welcome to drop by Zulip / #ROS General to discuss more. This would be a heavy lift but it would also have super high impact and visibility.

@StefanFabian
Copy link
Copy Markdown

StefanFabian commented Apr 22, 2026

Agree with @kscottz and @fujitatomoya, but with all the critical feedback on how this has to be implemented differently, which may be perceived as negativity, I want to remark that I also do think this is a great idea, and would be a huge improvement for the CLI tools.

@fujitatomoya
Copy link
Copy Markdown
Collaborator

yeah, i believe this is good visual aid for all ros2cli users. just saying we could do this better to avoid maintainability issue.

@penww
Copy link
Copy Markdown
Author

penww commented Apr 23, 2026

Hi @fujitatomoya, fully understood — and thank you for confirming that this feature is valuable. I also agree that enabling it properly would require a fairly large refactor, which addresses my earlier concern about review complexity caused by large-scale changes.

Based on your suggestions, a model like print( colorizer.green(node.name) ) (or similar APIs) makes much more sense. I can draft an initial version along these lines and bring it up for discussion.

@kscottz, I’ve opened a discussion thread on Zulip at ROS General>ROS2 command line color support. and I’ll post updates there as I have new progress.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add optional colorized output support

4 participants