cli #199
@@ -5,6 +5,7 @@ from pathlib import Path
|
||||
import click
|
||||
|
||||
from cpl.cli.cli import cli
|
||||
from cpl.cli.model.project import Project
|
||||
from cpl.cli.utils.structure import get_project_by_name_or_path
|
||||
from cpl.cli.utils.venv import ensure_venv, get_venv_python
|
||||
from cpl.core.configuration import Configuration
|
||||
@@ -42,23 +43,33 @@ def build(project: str, dist: str = None, skip_py_build: bool = None, verbose: b
|
||||
create_pyproject_toml(project, dist_path / project.name)
|
||||
python = str(get_venv_python(venv))
|
||||
|
||||
Console.spinner(
|
||||
result = Console.spinner(
|
||||
"Building python package...",
|
||||
lambda: (
|
||||
subprocess.run(
|
||||
[
|
||||
python,
|
||||
"-m",
|
||||
"build",
|
||||
"--outdir",
|
||||
str(dist_path / project.name),
|
||||
str(dist_path / project.name),
|
||||
],
|
||||
check=True,
|
||||
stdin=subprocess.DEVNULL if not verbose else None,
|
||||
stdout=subprocess.DEVNULL if not verbose else None,
|
||||
stderr=subprocess.DEVNULL if not verbose else None,
|
||||
)
|
||||
lambda: subprocess.run(
|
||||
[
|
||||
python,
|
||||
"-m",
|
||||
"build",
|
||||
"--outdir",
|
||||
str(dist_path / project.name),
|
||||
str(dist_path / project.name),
|
||||
],
|
||||
check=True,
|
||||
stdin=subprocess.DEVNULL if not verbose else None,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
),
|
||||
)
|
||||
|
||||
if result is None:
|
||||
raise RuntimeError("Build process did not run")
|
||||
|
||||
if verbose and result.stdout is not None:
|
||||
Console.write_line(result.stdout.decode())
|
||||
|
||||
if result.returncode != 0 and result.stderr is not None:
|
||||
if result.stderr is not None:
|
||||
Console.error(str(result.stderr.decode()))
|
||||
raise RuntimeError(f"Build process failed with exit code {result.returncode}")
|
||||
|
||||
Console.write_line(" Done!")
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import multiprocessing
|
||||
import time
|
||||
from multiprocessing import Process
|
||||
|
||||
@@ -21,18 +19,28 @@ class Spinner(Process):
|
||||
Foreground color of the spinner
|
||||
background_color: :class:`cpl.core.console.background_color.BackgroundColorEnum`
|
||||
Background color of the spinner
|
||||
done_char: :class:`str`
|
||||
"""
|
||||
|
||||
def __init__(self, msg_len: int, foreground_color: ForegroundColorEnum, background_color: BackgroundColorEnum):
|
||||
def __init__(
|
||||
self,
|
||||
foreground_color: ForegroundColorEnum,
|
||||
background_color: BackgroundColorEnum,
|
||||
done_char: str = None,
|
||||
msg_len: int = None,
|
||||
):
|
||||
Process.__init__(self)
|
||||
|
||||
self._msg_len = msg_len
|
||||
self._foreground_color = foreground_color
|
||||
self._background_color = background_color
|
||||
|
||||
self._is_spinning = True
|
||||
self._exit = False
|
||||
|
||||
assert done_char is None or len(done_char) == 1, "done_char must be a single character"
|
||||
self._done_char = done_char or "✓"
|
||||
self._msg_len = msg_len
|
||||
|
||||
@staticmethod
|
||||
def _spinner():
|
||||
r"""Selects active spinner char"""
|
||||
@@ -53,43 +61,33 @@ class Spinner(Process):
|
||||
|
||||
def run(self) -> None:
|
||||
r"""Entry point of process, shows the spinner"""
|
||||
columns = 0
|
||||
if sys.platform == "win32":
|
||||
columns = os.get_terminal_size().columns
|
||||
else:
|
||||
size = shutil.get_terminal_size(fallback=(80, 24))
|
||||
columns = max(1, size.columns)
|
||||
|
||||
end_msg = "done"
|
||||
|
||||
padding = columns - self._msg_len - len(end_msg)
|
||||
if padding > 0:
|
||||
print(f'{"" : >{padding}}', end="")
|
||||
else:
|
||||
print("", end="")
|
||||
size = shutil.get_terminal_size(fallback=(80, 24))
|
||||
columns = max(1, size.columns)
|
||||
|
||||
spinner = self._spinner()
|
||||
color_args = self._get_color_args()
|
||||
|
||||
if self._msg_len is not None:
|
||||
columns = min(columns, self._msg_len + 2)
|
||||
|
||||
while self._is_spinning:
|
||||
print(colored(f"{next(spinner): >{len(end_msg)}}", *self._get_color_args()), end="")
|
||||
frame = next(spinner)
|
||||
sys.stdout.write(f"\033[{columns}G")
|
||||
print(colored(frame, *color_args), end="", flush=True)
|
||||
time.sleep(0.1)
|
||||
back = ""
|
||||
for i in range(0, len(end_msg)):
|
||||
back += "\b"
|
||||
|
||||
print(back, end="")
|
||||
sys.stdout.write(f"\033[{columns}G")
|
||||
sys.stdout.flush()
|
||||
|
||||
if not self._exit:
|
||||
print(colored(end_msg, *self._get_color_args()), end="")
|
||||
|
||||
def stop(self):
|
||||
r"""Stops the spinner"""
|
||||
self._is_spinning = False
|
||||
super().terminate()
|
||||
time.sleep(0.1)
|
||||
print("\b" + colored(self._done_char, *self._get_color_args()), end="", flush=True)
|
||||
super().terminate()
|
||||
|
||||
def exit(self):
|
||||
r"""Stops the spinner"""
|
||||
self._is_spinning = False
|
||||
self._exit = True
|
||||
time.sleep(0.1)
|
||||
super().terminate()
|
||||
|
||||
@@ -435,6 +435,8 @@ class Console:
|
||||
message: str,
|
||||
call: Callable,
|
||||
*args,
|
||||
done_char: str = None,
|
||||
full_width: bool = False,
|
||||
text_foreground_color: Union[str, ForegroundColorEnum] = None,
|
||||
spinner_foreground_color: Union[str, ForegroundColorEnum] = None,
|
||||
text_background_color: Union[str, BackgroundColorEnum] = None,
|
||||
@@ -484,7 +486,8 @@ class Console:
|
||||
cls.set_hold_back(True)
|
||||
spinner = None
|
||||
if not cls._disabled:
|
||||
spinner = Spinner(len(message), spinner_foreground_color, spinner_background_color)
|
||||
msg_len = None if full_width else len(message) + 1
|
||||
spinner = Spinner(spinner_foreground_color, spinner_background_color, done_char=done_char, msg_len=msg_len)
|
||||
spinner.start()
|
||||
|
||||
return_value = None
|
||||
|
||||
Reference in New Issue
Block a user