Skip to content

Commit acb207d

Browse files
🚨 Make linter happy, more syntax forms for category color
1 parent 3717a09 commit acb207d

8 files changed

Lines changed: 33 additions & 41 deletions

File tree

β€ŽCHANGELOG.mdβ€Ž

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
### Changed
1616

1717
- Require Python 3.13 or greater.
18+
- Categories now support all syntax for colors supported by the `adorable2`
19+
package.
1820
- Deprecate `powercli.utils.static` in favor of `powercli.static.Static`.
1921
- Better support for inspecting subcommand arguments (via
2022
`powercli.parser.ParsedCommand.subcommand()`).

β€Žexamples/compiler.pyβ€Ž

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import sys
22
from typing import Any
33

4+
from adorable.common import YELLOW, AQUA, GREEN
45
from loguru import logger
56
from rich import print
67

@@ -10,15 +11,15 @@
1011
logger.enable("powercli.command")
1112
logger.add(sys.stdout, level="TRACE")
1213

13-
category_pm = Category("package management")
14-
category_build = Category("build")
15-
category_output = Category("output")
14+
category_pm = Category("package management", color=AQUA)
15+
category_build = Category("build", color=GREEN)
16+
category_output = Category("output", color=YELLOW)
1617

1718
cmd: Command[Any, Any] = Command(
1819
name="nullc",
1920
description="The C compiler that does not actually do anything at all",
2021
examples=[
21-
Example(["run main.c"], "Compile and run a C program"),
22+
Example(["run", "main.c"], "Compile and run a C program"),
2223
Example(["compile", "main.c", "-o", "main"], "Compile a C program"),
2324
],
2425
)

β€Žexamples/deprecation.pyβ€Ž

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import sys
22

33
from loguru import logger
4-
from rich import print
54

65
from powercli import Command, Static
76
from powercli.deprecation import Deprecation

β€Žpowercli/_help_utils.pyβ€Ž

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
]
1919

2020
import builtins
21+
import shlex
2122
import shutil
2223
from collections.abc import Collection
2324
from functools import partial
@@ -27,6 +28,7 @@
2728

2829
import wraptext
2930
from adorable import ansi, color
31+
from adorable.color import Color, RGB
3032
from adorable.common import BLACK, BOLD, MAROON, NAVY
3133

3234
from .static import Static
@@ -40,6 +42,17 @@
4042
PROMPT_PREFIX = "$"
4143

4244

45+
def _color_for_category(category: Category | None) -> Color[Any]:
46+
if category is None:
47+
return color.Colorless.from_rgb(0)
48+
elif isinstance(category.color, Color):
49+
return category.color
50+
else:
51+
return color.from_rgb(
52+
category.color or blake2s(category.title.encode()).digest()[0]
53+
)
54+
55+
4356
# See also: https://phoenixr-codes.github.io/adorable/caution-ansi-strings.html#getting-the-visible-length-of-a-string
4457
def len(x: Any, /) -> int:
4558
"""Returns the length of an object.
@@ -196,9 +209,8 @@ def examples(cmd: Command[Any, Any]) -> str:
196209
lines.append(
197210
f"{BOLD:{_indent_text(example.description, indent=' ', indent_initial=True)}}"
198211
)
199-
# TODO: shlex escape args
200212
command_line = (
201-
f"{PROMPT_PREFIX} {cmd._subcommand_path()} {' '.join(example.args)}"
213+
f"{PROMPT_PREFIX} {cmd._subcommand_path()} {' '.join(shlex.quote(arg) for arg in example.args)}"
202214
)
203215
# TODO: syntax highlighting
204216
lines.append(_indent_text(command_line, indent=" ", indent_initial=True))
@@ -210,13 +222,7 @@ def pretty_flag(cmd: Command[Any, Any], flag: Flag[Any, Any, Any]) -> str:
210222
"""Returns a descriptive information for a flag."""
211223
parts = []
212224
category = flag.category
213-
clr = (
214-
ansi.empty()
215-
if category is None
216-
else color.from_rgb(
217-
category.color or blake2s(category.title.encode()).digest()[0]
218-
)
219-
)
225+
clr = _color_for_category(category)
220226
if flag.short is not None and cmd.prefix_short is not None:
221227
parts.extend(
222228
[f"{clr:{cmd.prefix_short + name}}" for name in flag.visible_short_names()]
@@ -264,13 +270,7 @@ def commands(cmd: Command[Any, Any]) -> str:
264270
cmds = categories.setdefault(command.category, [])
265271
cmds.append(command)
266272
for category, commands in categories.items():
267-
clr = (
268-
ansi.empty()
269-
if category is None
270-
else color.from_rgb(
271-
category.color or blake2s(category.title.encode()).digest()[0]
272-
)
273-
)
273+
clr = _color_for_category(category)
274274
for command in commands:
275275
lines.extend(
276276
_add_description(

β€Žpowercli/category.pyβ€Ž

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,11 @@
33
from __future__ import annotations
44

55
__all__ = ["Color", "Category"]
6-
from typing import TypeAlias
6+
from typing import Any
77

8+
from adorable.color import RGB, Color
89
from attrs import define, field
910

10-
Color: TypeAlias = int
11-
"""A RGB color."""
12-
1311

1412
@define(hash=True, eq=True)
1513
class Category:
@@ -18,5 +16,5 @@ class Category:
1816
title: str
1917
"""The title of the category."""
2018

21-
color: Color | None = field(default=None, kw_only=True)
19+
color: RGB | Color[Any] | None = field(default=None, kw_only=True)
2220
"""An optional color for the category."""

β€Žpowercli/common.pyβ€Ž

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import sys
1818
from typing import Any, Never, cast
1919

20-
from . import parser
2120
from ._help_utils import _add_description, help_message
2221
from .args import Flag
2322
from .command import Command
@@ -71,9 +70,7 @@ def _subcommand_of_parent(self, name: str) -> Command[Never, Never]:
7170
return cmd
7271
raise RuntimeError(f"no command name {name!r}")
7372

74-
def parse_args(
75-
self, args: list[str] | None = None
76-
) -> Never:
73+
def parse_args(self, args: list[str] | None = None) -> Never:
7774
"""Parses arguments like {py:meth}`powercli.command.Command.parse_args`.
7875
7976
This function will print a help message and exit.
@@ -154,9 +151,7 @@ def __init__(
154151
super().__init__(name=name, description=description, **kwargs)
155152
self.version = version
156153

157-
def parse_args(
158-
self, args: list[str] | None = None
159-
) -> Never:
154+
def parse_args(self, args: list[str] | None = None) -> Never:
160155
"""Parses arguments like {py:meth}`powercli.command.Command.parse_args`.
161156
162157
This function will print the version and exit.
@@ -231,9 +226,7 @@ def __init__(
231226
"""Initializes the list command."""
232227
super().__init__(name=name, description=description, **kwargs)
233228

234-
def parse_args(
235-
self, args: list[str] | None = None
236-
) -> Never:
229+
def parse_args(self, args: list[str] | None = None) -> Never:
237230
"""Parses arguments like {py:meth}`powercli.command.Command.parse_args`.
238231
239232
This function will print a list of subcommands and exit.

β€Žpowercli/utils.pyβ€Ž

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
from __future__ import annotations
44

5-
__all__ = ["static", "one_of", "ArgIterator"]
5+
__all__ = ["static", "member_of", "one_of", "ArgIterator"]
66
import difflib
77
from collections import deque
8-
from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence
8+
from collections.abc import Iterable, Iterator, Sequence
99
from enum import StrEnum
10-
from typing import TYPE_CHECKING, Any
11-
from warnings import deprecated, warn
10+
from typing import TYPE_CHECKING
11+
from warnings import deprecated
1212

1313
from attrs import define
1414

β€Žpowerdoc/cli.pyβ€Ž

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from copy import deepcopy
21
from pathlib import Path
32
from typing import Any
43

0 commit comments

Comments
Β (0)