| #!/usr/bin/env vpython3 |
| # Copyright 2026 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| """Terminal styling and output utilities for CLI scripts.""" |
| |
| import sys |
| |
| |
| class TerminalStyle: |
| """ANSI escape codes for terminal styling.""" |
| BOLD = '\033[1m' |
| GREEN = '\033[92m' |
| RED = '\033[91m' |
| BLUE = '\033[94m' |
| RESET = '\033[0m' |
| |
| |
| def _supports_color(stream) -> bool: |
| """Checks if the output stream supports ANSI color codes.""" |
| return hasattr(stream, 'isatty') and stream.isatty() |
| |
| |
| def print_step(step: str, message: str) -> None: |
| """Prints a major step header, bolded and colored if supported.""" |
| if _supports_color(sys.stdout): |
| print(f'\n{TerminalStyle.BLUE}{TerminalStyle.BOLD}Step {step}: ' |
| f'{message}{TerminalStyle.RESET}') |
| else: |
| print(f'\nStep {step}: {message}') |
| |
| |
| def print_substep(message: str) -> None: |
| """Prints a sub-step or detail message.""" |
| print(f' -> {message}') |
| |
| |
| def print_error(message: str) -> None: |
| """Prints an error message to stderr in red if supported.""" |
| if _supports_color(sys.stderr): |
| print( |
| f'{TerminalStyle.RED}{TerminalStyle.BOLD}ERROR:' |
| f'{TerminalStyle.RESET} {message}', |
| file=sys.stderr) |
| else: |
| print(f'ERROR: {message}', file=sys.stderr) |
| |
| |
| def print_success(message: str) -> None: |
| """Prints a success message in green if supported.""" |
| if _supports_color(sys.stdout): |
| print(f'\n{TerminalStyle.GREEN}{TerminalStyle.BOLD}{message}' |
| f'{TerminalStyle.RESET}\n') |
| else: |
| print(f'\n{message}\n') |