I am trying to make a kind of recursive call on my first Click CLI app. The main point is to have sub-commands associated to the first and, so, I was trying to separate it all in different files/modules to improve it's maintainability.
I have the current directory
:
root
|-commands
|-project
|---__init__
|---command1
|---command2
|-database
|---__init__
|---command1
|---command2
This is my main file:
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)
My projects __init__
file:
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)
My commands.project.command1
file:
import click
@click.command()
def command1():
"""
Execute all the steps required to update the project.
"""
pass
The main point here is that, every time I want to add a new subcommand, I need to:
Add
.py
file with all code to the command, in respective subcommand/submodule folder (obviously!)Add it's
import
statement on it's__init__
fileRelate this new command to it's parent (project/database, in this case)
Is there any way to do a circular/dynamic load to avoid step no.2 and 3?
EDIT
After tried Stephen Rauch way, it successfully includes all provided files, but none of the commands works with -
only with function name (eg: -> 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
commands/project/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 result main project --help
(note the install_project
instead install-project
sub command)
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
command-one
, function on command's file:command_one
(python does not let hyphened functions ->-
). – Invite-
, I will not be able toimport
those files or it's definitions. – Invite