click.group
을 customize하여, django
의 manage.py
출력화면과 비슷한 help page를 만들었다.click.group에서 help page를 살펴보니.. 다음과 같은 점들을 추가하고 싶어졌다.
command output에 color를 적용하고 싶다.
django manage command와 같이 subcommand를 기능별로 묶을 수 있으면 좋겠다.
click.group
의 help page
django manage.py
의 help page
→ subcommand들이 명령어 종류별로 그룹화되어있다.
colorize output
click.echo(click.style(text, fg=color, bold=bold))
fg
option을 주어, output을 colorize할 수 있다.make subcommand in group
class ColoredGroup(Group):
subcommand_sections = [
{"name": "package",
"ends_with": "pkgs"},
{"name": "layer",
"ends_with": "layer"},
{"name": "allinone",
"ends_with": "allinone"}
]
def format_commands(self, ctx: Context, formatter: HelpFormatter) -> None:
...
# reverse self.list_commands(ctx) to show the commands in the order of method definition
reversed_commands = reversed(self.list_commands(ctx))
for subcommand in reversed_commands:
...
commands.append((subcommand, cmd))
if len(commands):
...
rows = []
for subcommand_section in self.subcommand_sections:
name = subcommand_section["name"]
rows.append(("", ""))
rows.append((click.style(f"[{name}]", bold=True, fg="red"), ""))
for subcommand, cmd in commands:
help = cmd.get_short_help_str(limit)
for subcommand_section in self.subcommand_sections:
if subcommand.endswith(subcommand_section["ends_with"]):
# insert next to the section
rows.insert(
rows.index((click.style(f"[{subcommand_section['name']}]", bold=True, fg="red"), "")) + 1,
(click.style(" "+subcommand,bold=True), click.style(help,fg="bright_black"))
)
break
if rows:
with formatter.section(_(click.style("Available subcommands", bold=True))):
formatter.write_dl(rows)
command를 code로 작성한 순서가 task 순서와 일치하기 때문에, definition 된 순서대로 정렬하는 게 깔끔하다.
→ self.list_commands(ctx)
를 reverse하여 사용해, code definition 순서에 맞게 command들이 출력되도록 바꾸었다.
sucommand_section
을 정의 후 출력할 row에 포함하였다. 색상을 red로 설정했다.subcommand
가 subcommand_section
에 지정된 단어로 끝나면, 매칭되는 subcommand section
항목 뒤에 subcommand
를 insert하도록 하였다.django manage.py
와 유사한 (djangotic) CLI help page를 만들었다.