Added crossplatform ANSI art to icmtoolchain command

This commit is contained in:
MaXFeeD
2025-06-24 16:30:24 +03:00
parent bafd887335
commit f2bd4b41da
2 changed files with 41 additions and 7 deletions
+28 -5
View File
@@ -3,19 +3,22 @@ from itertools import tee
from typing import TYPE_CHECKING, MutableSequence, MutableSet, Optional from typing import TYPE_CHECKING, MutableSequence, MutableSet, Optional
from .project_graph import ProjectEdge, ProjectGraph from .project_graph import ProjectEdge, ProjectGraph
from .shell import (abort, attention, failure, pretty_error, pretty_print, from .shell import (abort, attention, failure, pretty_ansi_layers,
pretty_warn, success) pretty_error, pretty_print, pretty_warn, success)
if TYPE_CHECKING: if TYPE_CHECKING:
from .parser import NamedCallable from .parser import NamedCallable
def show_help(): def show_help(requires_art: bool = False):
if requires_art:
show_ansi_toolchain()
pretty_print()
pretty_print("Usage: icmtoolchain [options] ... <task1> [arguments1] ...") pretty_print("Usage: icmtoolchain [options] ... <task1> [arguments1] ...")
pretty_print(" " * 2 + "--help: Display this message.") pretty_print(" " * 2 + "--help: Display this message.")
pretty_print(" " * 2 + "--list: See available tasks.") pretty_print(" " * 2 + "--list: See available tasks.")
pretty_print("Perform commands marked with a special decorator @task.") pretty_print("Perform commands marked with a special decorator @task.")
pretty_print("Example: icmtoolchain selectProject --path mod1 pushEverything selectProject --path mod2 pushEverything launchApplication") pretty_print("Example: icmtoolchain pushEverything launchApplication")
def show_available_tasks(): def show_available_tasks():
from .task import TASKS from .task import TASKS
@@ -26,6 +29,26 @@ def show_available_tasks():
pretty_print(": " + task.description, end="") pretty_print(": " + task.description, end="")
pretty_print() pretty_print()
def show_ansi_toolchain():
pretty_ansi_layers(
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 196, 160, 196, 196, 196, 196, 0, 0, 0, 0, 0, 0, 196, 160, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 196, 196, 196, 196, 160, 0, 0, 0, 0, 196, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 196, 196, 196, 196, 0, 0, 0, 196, 196, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 196, 196, 160, 196, 160, 160, 0, 160, 0, 0, 196, 196, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 160, 196, 196, 196, 196, 0, 0, 160, 196, 196, 196, 0, 220, 0, 160, 196, 0, 196, 196, 0, 0, 0, 0, 0],
[0, 0, 0, 160, 196, 196, 196, 196, 196, 0, 0, 0, 226, 220, 196, 196, 196, 214, 220, 0, 196, 160, 196, 196, 196, 0, 0, 0, 0],
[0, 0, 196, 196, 196, 160, 0, 196, 196, 196, 202, 208, 220, 226, 226, 202, 202, 196, 226, 226, 196, 196, 196, 196, 196, 0, 0, 0, 160],
[0, 196, 196, 0, 0, 160, 196, 196, 196, 196, 196, 208, 214, 214, 214, 220, 2, 214, 220, 226, 196, 196, 0, 160, 196, 0, 0, 0, 196],
[160, 160, 0, 0, 160, 196, 160, 172, 202, 214, 214, 2, 2, 7, 7, 7, 2, 7, 2, 214, 196, 196, 0, 0, 196, 0, 0, 0, 196],
[0, 0, 0, 0, 0, 0, 0, 0, 226, 226, 2, 7, 7, 7, 7, 7, 7, 7, 7, 2, 214, 196, 0, 0, 0, 160, 0, 160, 196],
[0, 0, 0, 160, 196, 0, 0, 166, 208, 226, 2, 7, 7, 7, 7, 7, 7, 7, 7, 2, 220, 208, 226, 0, 196, 196, 0, 196, 196],
[0, 0, 0, 196, 196, 0, 196, 196, 214, 226, 7, 7, " I", "nn", "er", " C", "or", "e ", 7, 7, 214, 226, 226, 124, 196, 196, 0, 196, 160],
[0, 0, 196, 196, 196, 160, 196, 196, 214, 2, 7, 7, " M", "od", 7, 7, 7, 7, 7, 7, 2, 226, 208, 196, 196, 0, 196, 196, 0],
[0, 0, 196, 196, 0, 196, 196, 214, 220, 2, 7, 7, " T", "oo", "lc", "ha", "in", 7, 7, 7, 2, 214, 196, 196, 196, 196, 196, 196, 0],
[0, 160, 196, 0, 196, 196, 124, 226, 220, 2, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 214, 196, 202, 0, 196, 196, 0, 0]
)
def show_unresolved_dependencies(dependencies: MutableSet[ProjectEdge]) -> None: def show_unresolved_dependencies(dependencies: MutableSet[ProjectEdge]) -> None:
if not any(dependencies): if not any(dependencies):
return return
@@ -66,7 +89,7 @@ def run(argv: Optional[MutableSequence[str]] = None):
if not argv or len(argv) == 0: if not argv or len(argv) == 0:
argv = sys.argv argv = sys.argv
if "--help" in argv or len(argv) <= 1: if "--help" in argv or len(argv) <= 1:
show_help() show_help(requires_art=len(argv) <= 1)
exit(0) exit(0)
if "--list" in argv: if "--list" in argv:
show_available_tasks() show_available_tasks()
+13 -2
View File
@@ -2,8 +2,8 @@ import os
import platform import platform
from datetime import datetime, timedelta from datetime import datetime, timedelta
from io import StringIO from io import StringIO
from typing import (Any, Callable, Dict, List, Literal, NoReturn, Optional, from typing import (Any, Callable, Dict, Iterable, List, Literal, NoReturn,
TypeVar, Union, overload) Optional, TypeVar, Union, overload)
from prompt_toolkit import Application, print_formatted_text from prompt_toolkit import Application, print_formatted_text
from prompt_toolkit.buffer import (Buffer, BufferAcceptHandler, from prompt_toolkit.buffer import (Buffer, BufferAcceptHandler,
@@ -861,6 +861,17 @@ def pretty_answer(prompt: AnyFormattedText, *values: object, sep: str=", ", end:
success(prompt, end=prompt_end, file=file, flush=flush, include_default_pygments_style=include_default_pygments_style) success(prompt, end=prompt_end, file=file, flush=flush, include_default_pygments_style=include_default_pygments_style)
pretty_print(*values, style="class:print.answer", sep=sep, end=end, file=file, flush=flush, include_default_pygments_style=include_default_pygments_style) pretty_print(*values, style="class:print.answer", sep=sep, end=end, file=file, flush=flush, include_default_pygments_style=include_default_pygments_style)
def pretty_ansi_layers(*layers: Iterable[Union[int, str]], end: Optional[str] = "", file: Optional[Any] = None, flush: bool = False, include_default_pygments_style: bool = False) -> None:
from prompt_toolkit import ANSI
for layer in layers:
for symbol in layer:
prefix = "" if symbol == 0 or symbol == 7 else "7m" if not isinstance(symbol, int) else "7m\x1b[" if symbol == 2 else "48;5;"
postfix = "m " if isinstance(symbol, int) else ""
pretty_print(ANSI(f"\x1b[{prefix}{symbol}{postfix}"), end="", file=file, flush=flush, include_default_pygments_style=include_default_pygments_style) # "\x1b[0m"
pretty_print(file=file, flush=flush, include_default_pygments_style=include_default_pygments_style)
if end:
pretty_print(end, end="", file=file, flush=flush, include_default_pygments_style=include_default_pygments_style)
def success(*values: object, sep: str = " ", end: Optional[str] = "\n", file: Optional[Any] = None, flush: bool = False, include_default_pygments_style: bool = False): def success(*values: object, sep: str = " ", end: Optional[str] = "\n", file: Optional[Any] = None, flush: bool = False, include_default_pygments_style: bool = False):
pretty_print(UNICODE_CHECK_MARK, style="class:print.success", end=" ") pretty_print(UNICODE_CHECK_MARK, style="class:print.success", end=" ")
pretty_print(*values, style="class:print.success", sep=sep, end=end, file=file, flush=flush, include_default_pygments_style=include_default_pygments_style) pretty_print(*values, style="class:print.success", sep=sep, end=end, file=file, flush=flush, include_default_pygments_style=include_default_pygments_style)