seitime-frappe/frappe/utils/bench_helper.py
Gavin D'souza 8d19a815b3 refactor: bench_helper
* Walrus operators ftw
* Pathlib to reduce verbose path joins crie
* Added typing for sanity
2022-08-11 23:53:21 +05:30

104 lines
2.7 KiB
Python

import importlib
import json
import os
import traceback
import warnings
from pathlib import Path
import click
import frappe
import frappe.utils
click.disable_unicode_literals_warning = True
def main():
commands = get_app_groups()
commands.update({"get-frappe-commands": get_frappe_commands, "get-frappe-help": get_frappe_help})
click.Group(commands=commands)(prog_name="bench")
def get_app_groups() -> dict[str, click.Group]:
"""Get all app groups, put them in main group "frappe" since bench is
designed to only handle that"""
commands = {}
for app in get_apps():
if app_commands := get_app_commands(app):
commands |= app_commands
return dict(frappe=click.group(name="frappe", commands=commands)(app_group))
def get_app_group(app: str) -> click.Group:
if app_commands := get_app_commands(app):
return click.group(name=app, commands=app_commands)(app_group)
@click.option("--site")
@click.option("--profile", is_flag=True, default=False, help="Profile")
@click.option("--verbose", is_flag=True, default=False, help="Verbose")
@click.option("--force", is_flag=True, default=False, help="Force")
@click.pass_context
def app_group(ctx, site=False, force=False, verbose=False, profile=False):
ctx.obj = {"sites": get_sites(site), "force": force, "verbose": verbose, "profile": profile}
if ctx.info_name == "frappe":
ctx.info_name = ""
def get_sites(site_arg: str) -> list[str]:
if site_arg == "all":
return frappe.utils.get_sites()
elif site_arg:
return [site_arg]
elif os.environ.get("FRAPPE_SITE"):
return [os.environ.get("FRAPPE_SITE")]
elif os.path.exists("currentsite.txt"):
with open("currentsite.txt") as f:
if site := f.read().strip():
return [site]
return []
def get_app_commands(app: str) -> dict:
ret = {}
app_path = Path("..", "apps", app, app)
if not ((app_path / "commands.py").exists() or (app_path / "commands" / "__init__.py").exists()):
return ret
try:
app_command_module = importlib.import_module(f"{app}.commands")
except Exception:
traceback.print_exc()
return ret
for command in getattr(app_command_module, "commands", []):
ret[command.name] = command
return ret
@click.command("get-frappe-commands")
def get_frappe_commands():
commands = list(get_app_commands("frappe"))
for app in get_apps():
app_commands = get_app_commands(app)
if app_commands:
commands.extend(list(app_commands))
print(json.dumps(commands))
@click.command("get-frappe-help")
def get_frappe_help():
print(click.Context(get_app_groups()["frappe"]).get_help())
def get_apps():
return frappe.get_all_apps(with_internal_apps=False, sites_path=".")
if __name__ == "__main__":
if not frappe._dev_server:
warnings.simplefilter("ignore")
main()