[Click] 2. click.group customizing 하기 (django manage.py 따라하기)

LULLU·2022년 9월 5일
0

TL;DR

  • click.group을 customize하여, djangomanage.py 출력화면과 비슷한 help page를 만들었다.

click.group이 맘에 안든다

  • click.group에서 help page를 살펴보니.. 다음과 같은 점들을 추가하고 싶어졌다.

    • command output에 color를 적용하고 싶다.

    • django manage command와 같이 subcommand를 기능별로 묶을 수 있으면 좋겠다.

      click.group의 help page

      django manage.py의 help page

      → subcommand들이 명령어 종류별로 그룹화되어있다.

Customize click.group

  1. colorize output

    click.echo(click.style(text, fg=color, bold=bold))
    • click.style에서 fg option을 주어, output을 colorize할 수 있다.
  2. 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 list가 code definition의 역순으로 출력되는 점이 맘에 안들었다.
      • command를 code로 작성한 순서가 task 순서와 일치하기 때문에, definition 된 순서대로 정렬하는 게 깔끔하다.

        self.list_commands(ctx)를 reverse하여 사용해, code definition 순서에 맞게 command들이 출력되도록 바꾸었다.

    • sucommand_section을 정의 후 출력할 row에 포함하였다. 색상을 red로 설정했다.
    • subcommandsubcommand_section에 지정된 단어로 끝나면, 매칭되는 subcommand section 항목 뒤에 subcommand를 insert하도록 하였다.

Customize 결과

  • django manage.py와 유사한 (djangotic) CLI help page를 만들었다.

더보기

0개의 댓글