我将如何使用 python-click 构建类似 kubectl 的 CLI?
How would I structure a kubectl-like CLI with python-click?
我想创建一个 CLI,以 kubectl
的方式接收操作和资源参数以工作。例如
myctl init config
myctl create issue|pr|branch
myctl delete issue|pr|branch|config
myctl 命令应始终接收 2 个参数,这样用户就不会尝试类似:myctl init config delete issue
的操作。也不应该能够执行不可能的组合,例如 myctl create config
.
我想到了一些代码,例如:
import click
@click.command()
@click.group()
@click.option(
"init,create,delete",
type=str,
help="Action name.",
)
@click.option(
"config,issue,pr,branch",
type=str,
help="Resource name.",
)
def main(action: str, resource: str) -> None:
pass
if __name__ == "__main__":
main(prog_name="myctl")
我不太确定我应该使用哪些点击元素来构造它(参数、选项、组等)以及如何将它们组合在一起。
我过去通过创建多个嵌套组实现了这一点。
import click
@click.group('cli')
def cli():
pass
@click.group('init')
def init():
pass
@click.group('create')
def create():
pass
@click.group('delete')
def delete():
pass
@init.command('config')
def config():
print('Configuration complete')
@create.command('issue')
@click.argument('name')
def issue(name):
print(f'Created {name}')
@create.command('pr')
@click.argument('base_branch', required=False, default='master')
def pr(base_branch):
print(f'Created PR against {base_branch}')
@create.command('branch')
@click.argument('name')
def branch(name):
print(f'Create branch {name}')
@delete.command('issue')
@click.argument('issue_number')
def delete_issue(issue_number):
print(f'Deleting issue {issue_number}')
@delete.command('pr')
@click.argument('pr_number')
def delete_pr(pr_number):
print(f'Deleting PR {pr_number}')
@delete.command('branch')
@click.argument('branch_name')
def delete_branch(branch_name):
print(f'Deleting branch {branch_name}')
@delete.command('config')
@click.argument('config_name')
def delete_config(config_name):
print(f'Deleting config {config_name}')
cli.add_command(init)
cli.add_command(create)
cli.add_command(delete)
def run_cli():
cli()
if __name__ == "__main__":
run_cli()
然后您可以根据需要扩展它,调用如下所示。我调用了我的 CLI play
.
❯ play
Usage: play [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
create
delete
init
❯ play init
Usage: play init [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
config
❯ play init config
Configuration complete
❯ play create
Usage: play create [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
branch
issue
pr
❯ play create branch feature/the-coolest
Create branch feature/the-coolest
然后您可以继续添加简短的帮助消息并根据您的应用程序对其进行自定义。
我想创建一个 CLI,以 kubectl
的方式接收操作和资源参数以工作。例如
myctl init config
myctl create issue|pr|branch
myctl delete issue|pr|branch|config
myctl 命令应始终接收 2 个参数,这样用户就不会尝试类似:myctl init config delete issue
的操作。也不应该能够执行不可能的组合,例如 myctl create config
.
我想到了一些代码,例如:
import click
@click.command()
@click.group()
@click.option(
"init,create,delete",
type=str,
help="Action name.",
)
@click.option(
"config,issue,pr,branch",
type=str,
help="Resource name.",
)
def main(action: str, resource: str) -> None:
pass
if __name__ == "__main__":
main(prog_name="myctl")
我不太确定我应该使用哪些点击元素来构造它(参数、选项、组等)以及如何将它们组合在一起。
我过去通过创建多个嵌套组实现了这一点。
import click
@click.group('cli')
def cli():
pass
@click.group('init')
def init():
pass
@click.group('create')
def create():
pass
@click.group('delete')
def delete():
pass
@init.command('config')
def config():
print('Configuration complete')
@create.command('issue')
@click.argument('name')
def issue(name):
print(f'Created {name}')
@create.command('pr')
@click.argument('base_branch', required=False, default='master')
def pr(base_branch):
print(f'Created PR against {base_branch}')
@create.command('branch')
@click.argument('name')
def branch(name):
print(f'Create branch {name}')
@delete.command('issue')
@click.argument('issue_number')
def delete_issue(issue_number):
print(f'Deleting issue {issue_number}')
@delete.command('pr')
@click.argument('pr_number')
def delete_pr(pr_number):
print(f'Deleting PR {pr_number}')
@delete.command('branch')
@click.argument('branch_name')
def delete_branch(branch_name):
print(f'Deleting branch {branch_name}')
@delete.command('config')
@click.argument('config_name')
def delete_config(config_name):
print(f'Deleting config {config_name}')
cli.add_command(init)
cli.add_command(create)
cli.add_command(delete)
def run_cli():
cli()
if __name__ == "__main__":
run_cli()
然后您可以根据需要扩展它,调用如下所示。我调用了我的 CLI play
.
❯ play
Usage: play [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
create
delete
init
❯ play init
Usage: play init [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
config
❯ play init config
Configuration complete
❯ play create
Usage: play create [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
branch
issue
pr
❯ play create branch feature/the-coolest
Create branch feature/the-coolest
然后您可以继续添加简短的帮助消息并根据您的应用程序对其进行自定义。