| #!/usr/bin/env python3 |
| # Copyright 2023 The ChromiumOS Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """ |
| Implements styles for `Command.fg(style=)` that use `rich` terminal UI features. |
| """ |
| |
| import subprocess |
| from typing import List |
| |
| from .util import ensure_packages_exist |
| |
| ensure_packages_exist("rich") |
| import rich |
| import rich.console |
| import rich.live |
| import rich.spinner |
| import rich.text |
| |
| |
| class Styles(object): |
| "A collection of methods that can be passed to `Command.fg(style=)`" |
| |
| @staticmethod |
| def live_truncated(num_lines: int = 8): |
| "Prints only the last `num_lines` of output while the program is running and successful." |
| |
| def output(process: "subprocess.Popen[str]"): |
| assert process.stdout |
| spinner = rich.spinner.Spinner("dots") |
| lines: List[rich.text.Text] = [] |
| stdout: List[str] = [] |
| with rich.live.Live(refresh_per_second=30, transient=True) as live: |
| for line in iter(process.stdout.readline, ""): |
| stdout.append(line.strip()) |
| lines.append(rich.text.Text.from_ansi(line.strip(), no_wrap=True)) |
| while len(lines) > num_lines: |
| lines.pop(0) |
| live.update(rich.console.Group(rich.text.Text("…"), *lines, spinner)) |
| if process.wait() == 0: |
| console.print(rich.console.Group(rich.text.Text("…"), *lines)) |
| else: |
| for line in stdout: |
| print(line) |
| |
| return output |
| |
| @staticmethod |
| def quiet_with_progress(title: str): |
| "Prints only the last `num_lines` of output while the program is running and successful." |
| |
| def output(process: "subprocess.Popen[str]"): |
| assert process.stdout |
| with rich.live.Live( |
| rich.spinner.Spinner("dots", title), refresh_per_second=30, transient=True |
| ): |
| stdout = process.stdout.read() |
| |
| if process.wait() == 0: |
| console.print(f"[green]OK[/green] {title}") |
| else: |
| print(stdout) |
| console.print(f"[red]ERR[/red] {title}") |
| |
| return output |
| |
| |
| console = rich.console.Console() |