mirror of
https://github.com/devine-dl/devine.git
synced 2025-04-29 17:49:44 +00:00
44 lines
1.2 KiB
Python
44 lines
1.2 KiB
Python
from typing import Optional
|
|
|
|
import click
|
|
|
|
from devine.core.config import config
|
|
from devine.core.utilities import import_module_by_path
|
|
|
|
_COMMANDS = sorted(
|
|
(
|
|
path
|
|
for path in config.directories.commands.glob("*.py")
|
|
if path.stem.lower() != "__init__"
|
|
),
|
|
key=lambda x: x.stem
|
|
)
|
|
|
|
_MODULES = {
|
|
path.stem: getattr(import_module_by_path(path), path.stem)
|
|
for path in _COMMANDS
|
|
}
|
|
|
|
|
|
class Commands(click.MultiCommand):
|
|
"""Lazy-loaded command group of project commands."""
|
|
|
|
def list_commands(self, ctx: click.Context) -> list[str]:
|
|
"""Returns a list of command names from the command filenames."""
|
|
return [x.stem for x in _COMMANDS]
|
|
|
|
def get_command(self, ctx: click.Context, name: str) -> Optional[click.Command]:
|
|
"""Load the command code and return the main click command function."""
|
|
module = _MODULES.get(name)
|
|
if not module:
|
|
raise click.ClickException(f"Unable to find command by the name '{name}'")
|
|
|
|
if hasattr(module, "cli"):
|
|
return module.cli
|
|
|
|
return module
|
|
|
|
|
|
# Hide direct access to commands from quick import form, they shouldn't be accessed directly
|
|
__all__ = ("Commands",)
|