我正在尝试在我的第一个Click CLI应用程序上进行某种递归调用。重点是要有与第一个命令相关的子命令,因此,我试图将其全部分离到不同的文件/模块中,以提高其可维护性。
我有当前directory
:
root
|-commands
|-project
|---__init__
|---command1
|---command2
|-database
|---__init__
|---command1
|---command2
这是我的主文件:
import click
from commands.project import project
from commands.database import database
@click.group(help="Main command")
def main():
pass
main.add_command(project)
main.add_command(database)
我的项目__init__
文件:
from commands.project.command1 import *
from commands.project.command2 import *
import click
@click.group(help="Projects")
def project():
pass
project.add_command(command1)
project.add_command(command2)
我的commands.project.command1
档案:
import click
@click.command()
def command1():
"""
Execute all the steps required to update the project.
"""
pass
这里的要点是,每次我想添加一个新的子命令时,我都需要:
将.py
包含所有代码的文件添加到命令中相应的subcommand / submodule文件夹中(显然!)。
import
在__init__
文件上添加语句
将此新命令与其父级(在这种情况下为项目/数据库)相关联
有什么方法可以进行圆形/动态载荷以避免步骤2和3?
编辑
在尝试了Stephen Rauch的方法之后,它成功地包含了所有提供的文件,但是没有一个命令-
仅适用于函数名(例如: -> )。 update-project
update_project
root
|-commands
|-project
|---update
|---install_project
|-database
|---command_one
|---command_two
main.py
# main command ----------------------------------------------------------- ###
@click.group(help="CLI tool!", context_settings=dict(max_content_width=120))
def main():
pass
# PROJECT command group -------------------------------------------------------- ###
@main.group(cls=group_from_folder("commands/project"),
short_help="Project installation and upgrade utils.",
help="Project installation and upgrade.")
def project():
pass
命令/项目/ install_project.py
import click
@click.command(name="install-project",
help="This options allows you to easily install project",
short_help="Install a brand new project")
@click.pass_context
def install_project(ctx):
CLI结果main project --help
(注意install_project
相反的install-project
sub命令)
Usage: main project [OPTIONS] COMMAND [ARGS]...
Project installation and upgrade.
Options:
--help Show this message and exit.
Commands:
install_project Install a brand new project one
我建议您只从特定的Python包中读取命令,然后将其添加到您的输入组中。
假设我们有这样的结构:
|--app
|--commands
|--__init__.py
|--group1
|--__init__.py
|--command1.py
|--group2
|--__init__.py
|--command2.py
|--__init__.py
|--cli.py
然后您的命令文件需要包含一键单击。具有指定名称的命令和具有名称``命令''的函数:
import click
@click.command(name="your-first-command")
def command():
pass
每个组中的初始化文件都需要包含doc字符串,以使click.Group具有正确的“帮助”值。
最有趣的cli.py:
import click
import importlib
import pkgutil
import os.path
def get_commands_from_pkg(pkg) -> dict:
pkg_obj = importlib.import_module(pkg)
pkg_path = os.path.dirname(pkg_obj.__file__)
commands = {}
for module in pkgutil.iter_modules([pkg_path]):
module_obj = importlib.import_module(f"{pkg}.{module.name}")
if not module.ispkg:
commands[module_obj.command.name] = module_obj.command
else:
commands[module.name.replace('_', '-')] = click.Group(
context_settings={'help_option_names': ['-h', '--help']},
help=module_obj.__doc__,
commands=get_commands_from_pkg(f"{pkg}.{module.name}")
)
return commands
@click.group(context_settings={'help_option_names': ['-h', '--help']}, help="Your CLI",
commands=get_commands_from_pkg('app.commands'))
def cli():
pass
如您所见,我们以递归方式创建点击组并将点击命令添加到特定的组。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句