crosvm/tools/impl/tui.py
Dennis Kempin 11a48d4cca tools: refactoring: Split common.py into multiple files
This is a refactoring with no functionality change. The common.py
file is split up so we will be able to use the parts that have no
third party dependencies separately.

For now, keep common.py and re-export everything, so we do not
introduce issues in other tools.

BUG=b:267499599
TEST=presubmit

Change-Id: Idf6d45bd90f5cf448fb9dd88df540af3da0f7f88
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/4482141
Reviewed-by: Zihan Chen <zihanchen@google.com>
Commit-Queue: Dennis Kempin <denniskempin@google.com>
2023-05-02 17:04:27 +00:00

70 lines
2.3 KiB
Python

#!/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()