Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 140 additions & 65 deletions src/winml/modelkit/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,31 +41,31 @@
logger = logging.getLogger(__name__)

_COMMANDS_DIR = Path(__file__).parent / "commands"

# 5-row block-letter art for "WinML CLI". '#' = filled pixel, ' ' = empty.
# All letters use the same █ character so identical shapes (i vs I) look
# consistent regardless of horizontal position.
_LETTER_ART: dict[str, list[str]] = {
"W": ["# #", "# #", "# # #", "## ##", "# #"],
"i": ["###", " # ", " # ", " # ", "###"],
"n": ["# #", "## #", "# # #", "# ##", "# #"],
"M": ["# #", "## ##", "# # #", "# #", "# #"],
"L": ["# ", "# ", "# ", "# ", "#####"],
"C": ["####", "# ", "# ", "# ", "####"],
"I": ["###", " # ", " # ", " # ", "###"],
_COMPACT_LETTER_ART = {
"W": ("# #", "# #", "# # #", "## ##", "# #"),
"I": ("###", " # ", " # ", " # ", "###"),
"N": ("# #", "## #", "# # #", "# ##", "# #"),
"M": ("# #", "## ##", "# # #", "# #", "# #"),
"L": ("# ", "# ", "# ", "# ", "#####"),
}
# Two word segments; rendered with a wider gap between them.
_SEGMENTS: list[list[str]] = [list("WinML"), list("CLI")]
_LETTER_GAP = " " # between letters within a word
_WORD_GAP = " " # between words
_WORDMARK = "WINML"
_LETTER_GAP = " "
# Four 4-column gradient tiles arranged as a Microsoft-style 2x2 mark.
_MARK_ART = (
"#### ####",
"#### ####",
"#### ####",
" ",
"#### ####",
"#### ####",
"#### ####",
)

# Gradient stops (left → right across the full banner width).
_GRADIENT: list[tuple[float, tuple[int, int, int]]] = [
(0.00, (0, 230, 255)), # cyan
(0.25, (0, 100, 255)), # blue
(0.50, (130, 0, 255)), # purple
(0.75, (255, 0, 180)), # pink
(1.00, (255, 80, 80)), # red
(0.00, (45, 145, 255)),
(0.55, (0, 205, 255)),
(1.00, (130, 70, 255)),
]


Expand All @@ -83,53 +83,123 @@ def _gradient_color(t: float) -> tuple[int, int, int]:
return _GRADIENT[-1][1]


def _print_banner(version: str, *, _console: Console | None = None) -> None:
"""Print the WinML CLI gradient banner to stderr using Rich."""
from rich.console import Console # lazy import - keeps startup fast
def _print_banner(
version: str,
*,
_console: Console | None = None,
) -> None:
"""Print the capsule WinML CLI banner to stderr using Rich."""
from rich.console import Console, Group # lazy import - keeps startup fast
from rich.text import Text

# Compute total art width across both word segments.
art_w = len(_WORD_GAP) * (len(_SEGMENTS) - 1)
for seg in _SEGMENTS:
art_w += len(_LETTER_GAP) * (len(seg) - 1)
art_w += sum(len(_LETTER_ART[ch][0]) for ch in seg)
bar_w = art_w + 4
margin = " "

con = _console or Console(stderr=True, highlight=False)
con.print()

for row_idx in range(5):
line = Text(margin)
col = 0
for seg_idx, seg in enumerate(_SEGMENTS):
if seg_idx > 0:
line.append(_WORD_GAP)
col += len(_WORD_GAP)
for letter_idx, letter in enumerate(seg):
if letter_idx > 0:
line.append(_LETTER_GAP)
col += len(_LETTER_GAP)
for ch in _LETTER_ART[letter][row_idx]:
if ch == "#":
r, g, b = _gradient_color(col / max(art_w - 1, 1))
line.append("█", style=f"bold rgb({r},{g},{b})")
else:
line.append(" ")
col += 1
con.print(line)

con.print()
bar = Text(margin)
for i in range(bar_w):
r, g, b = _gradient_color(i / max(bar_w - 1, 1))
bar.append("─", style=f"rgb({r},{g},{b})")
con.print(bar)

con.print()
con.print(f"{margin}[bold rgb(160,100,255)]Windows ML · Model Conversion & Optimization[/]")
con.print(f"{margin}[dim]v{version} · CPU · GPU · NPU[/]")
con.print()
compact_rows = tuple(
_LETTER_GAP.join(_COMPACT_LETTER_ART[letter][row] for letter in _WORDMARK)
for row in range(5)
)
compact_width = len(compact_rows[0]) * 2
mark_width = len(_MARK_ART[0]) * 2
show_mark = con.width >= compact_width + mark_width + 11

def gradient_line(value: str) -> Text:
line = Text()
for col, char in enumerate(value):
r, g, b = _gradient_color(col / max(len(value) - 1, 1))
line.append(char, style=f"bold rgb({r},{g},{b})")
return line

def footer(tagline: str, *, include_version: bool = True) -> list[Text]:
lines = [
Text(),
Text.from_markup(f"{margin}[bold rgb(160,100,255)]Windows ML[/] · {tagline}"),
]
if include_version:
lines.append(Text.from_markup(f"{margin}v{version} · CPU · GPU · NPU"))
lines.append(Text())
return lines

def wordmark() -> list[Text]:
lines = []
patterns = compact_rows
width = compact_width
shadow_rows = (*patterns, " " * len(patterns[0]))
for row, pattern in enumerate(shadow_rows):
line = Text()
previous = shadow_rows[row - 1] if row else ""
for pixel_col, char in enumerate(pattern):
col = pixel_col * 2
if char == "#":
r, g, b = _gradient_color(col / max(width - 1, 1))
line.append("██", style=f"bold rgb({r},{g},{b})")
elif row and pixel_col and previous[pixel_col - 1] == "#":
line.append("▓▓", style="bold rgb(130,80,210)")
else:
line.append(" ")
lines.append(line)
return lines

def mark() -> list[Text]:
pane_cols = len(_MARK_ART[0])
lines = []
for pattern in _MARK_ART:
line = Text()
for col, char in enumerate(pattern):
if char == "#":
r, g, b = _gradient_color(col / max(pane_cols - 1, 1))
line.append("██", style=f"bold rgb({r},{g},{b})")
else:
line.append(" ")
lines.append(line)
return lines

def capsule() -> Group:
logo_lines = wordmark()
version_text = Text.from_markup(f"v{version} · CPU · GPU · NPU")
version_line = Text(" " * ((compact_width - len(version_text)) // 2))
version_line.append_text(version_text)
version_line.append(" " * (compact_width - len(version_line)))
logo_lines.extend([Text(" " * compact_width), version_line])
mark_lines = mark() if show_mark else []
content_width = compact_width + (mark_width + 3 if show_mark else 0)
frame_margin = margin if show_mark else ""

def framed_line(content: Text | None = None) -> Text:
line = gradient_line(f"{frame_margin}┃ ")
if content is None:
line.append(" " * content_width)
else:
line.append_text(content)
line.append(" " * (content_width - len(content)))
line.append(" ┃", style="bold rgb(130,70,255)")
return line

lines = [
Text(),
Text.from_markup(f"{margin}Windows ML CLI"),
gradient_line(f"{frame_margin}┏{'━' * (content_width + 4)}┓"),
framed_line(),
]
for row in range(max(len(logo_lines), len(mark_lines))):
content = Text()
if show_mark:
mark_line = mark_lines[row] if row < len(mark_lines) else Text(" " * mark_width)
content.append_text(mark_line)
content.append(" ")
logo_line = logo_lines[row] if row < len(logo_lines) else Text(" " * compact_width)
content.append_text(logo_line)
lines.append(framed_line(content))

lines.extend(
[
framed_line(),
gradient_line(f"{frame_margin}┗{'━' * (content_width + 4)}┛"),
*footer("Model conversion & optimization", include_version=False),
]
)
return Group(*lines)

con.print(capsule())


# Commands that are temporarily disabled from the CLI surface.
Expand Down Expand Up @@ -321,7 +391,12 @@ def format_commands(self, ctx: click.Context, formatter: click.HelpFormatter) ->
hidden=True,
)
@click.pass_context
def main(ctx: click.Context, verbose: int, quiet: bool, debug: bool) -> None:
def main(
ctx: click.Context,
verbose: int,
quiet: bool,
debug: bool,
) -> None:
"""WinML CLI - Accelerate Model Deployment on WinML.

Universal ONNX export with various WinML execution providers support.
Expand Down
58 changes: 57 additions & 1 deletion tests/cli/test_help_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"""CLI surface tests for ``winml`` (no args) and ``winml --help``.

Both invocations follow the same contract: exit 0 and render the full
help page, which consists of the gradient banner on stderr and the Click
help page, which consists of the selected banner on stderr and the Click
help text (Usage / Options / Commands) on stdout. The tests here pin the
*observable output contract* of these two entry points — no mocks, no
subcommand execution.
Expand Down Expand Up @@ -35,16 +35,20 @@
from __future__ import annotations

import textwrap
from io import StringIO
from typing import TYPE_CHECKING
from unittest.mock import patch

import pytest
from click.testing import CliRunner, Result
from rich.console import Console

from winml.modelkit import __version__
from winml.modelkit.cli import (
_COMMANDS_DIR,
_DISABLED_COMMANDS,
_parse_click_help,
_print_banner,
main,
)

Expand Down Expand Up @@ -146,6 +150,58 @@ def test_subcommand_help_has_no_banner(self) -> None:
assert result.exit_code == 0
assert "Windows ML" not in result.stderr

def test_banner_animation_is_skipped_outside_interactive_terminals(self) -> None:
with patch("time.sleep") as mock_sleep:
_print_banner(
"1.2.3",
_console=Console(
file=StringIO(),
force_terminal=False,
color_system=None,
),
)
mock_sleep.assert_not_called()

@pytest.mark.parametrize("width", [80, 81, 82, 100])
def test_interactive_banner_is_static(self, width: int) -> None:
with patch("time.sleep") as mock_sleep:
_print_banner(
"1.2.3",
_console=Console(
file=StringIO(),
force_terminal=True,
color_system="truecolor",
width=width,
),
)
mock_sleep.assert_not_called()

def test_removed_banner_style_is_rejected(self) -> None:
result = _invoke("--banner-style", "unknown", "--help")
assert result.exit_code != 0
assert "No such option" in result.output

# Each row contains two four-column gradient tiles separated by a gap.
_MARK_SIGNATURE = "████████ ████████"

def test_capsule_shows_left_mark_on_wide_terminals(self) -> None:
console = Console(file=StringIO(), force_terminal=False, color_system=None, width=90)
_print_banner("1.2.3", _console=console)
assert self._MARK_SIGNATURE in console.file.getvalue()

def test_capsule_hides_left_mark_on_narrow_terminals(self) -> None:
console = Console(file=StringIO(), force_terminal=False, color_system=None, width=80)
_print_banner("1.2.3", _console=console)
assert self._MARK_SIGNATURE not in console.file.getvalue()

def test_capsule_places_version_inside_frame(self) -> None:
console = Console(file=StringIO(), force_terminal=False, color_system=None, width=110)
_print_banner("1.2.3", _console=console)
output = console.file.getvalue()
version_line = next(line for line in output.splitlines() if "v1.2.3" in line)
assert version_line.strip().startswith("┃")
assert version_line.strip().endswith("┃")


# ===========================================================================
# Commands section
Expand Down