mirror of
https://github.com/frappe/bench.git
synced 2025-01-08 00:04:38 +00:00
Merge pull request #1334 from gavindsouza/better-cli-resolution
refactor(cli): Commands Resolution
This commit is contained in:
commit
a481934d53
76
bench/cli.py
76
bench/cli.py
@ -1,6 +1,8 @@
|
|||||||
# imports - standard imports
|
# imports - standard imports
|
||||||
import atexit
|
import atexit
|
||||||
|
from contextlib import contextmanager
|
||||||
import json
|
import json
|
||||||
|
from logging import Logger
|
||||||
import os
|
import os
|
||||||
import pwd
|
import pwd
|
||||||
import sys
|
import sys
|
||||||
@ -25,7 +27,7 @@ from bench.utils import (
|
|||||||
is_root,
|
is_root,
|
||||||
log,
|
log,
|
||||||
setup_logging,
|
setup_logging,
|
||||||
parse_sys_argv,
|
get_cmd_from_sysargv,
|
||||||
)
|
)
|
||||||
from bench.utils.bench import get_env_cmd
|
from bench.utils.bench import get_env_cmd
|
||||||
|
|
||||||
@ -35,23 +37,41 @@ verbose = False
|
|||||||
is_envvar_warn_set = None
|
is_envvar_warn_set = None
|
||||||
from_command_line = False # set when commands are executed via the CLI
|
from_command_line = False # set when commands are executed via the CLI
|
||||||
bench.LOG_BUFFER = []
|
bench.LOG_BUFFER = []
|
||||||
sys_argv = None
|
|
||||||
|
|
||||||
change_uid_msg = "You should not run this command as root"
|
change_uid_msg = "You should not run this command as root"
|
||||||
src = os.path.dirname(__file__)
|
src = os.path.dirname(__file__)
|
||||||
|
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def execute_cmd(check_for_update=True, command: str = None, logger: Logger = None):
|
||||||
|
if check_for_update:
|
||||||
|
atexit.register(check_latest_version)
|
||||||
|
|
||||||
|
try:
|
||||||
|
yield
|
||||||
|
except BaseException as e:
|
||||||
|
return_code = getattr(e, "code", 1)
|
||||||
|
|
||||||
|
if isinstance(e, Exception):
|
||||||
|
click.secho(f"ERROR: {e}", fg="red")
|
||||||
|
|
||||||
|
if return_code:
|
||||||
|
logger.warning(f"{command} executed with exit code {return_code}")
|
||||||
|
|
||||||
|
raise e
|
||||||
|
|
||||||
|
|
||||||
def cli():
|
def cli():
|
||||||
global from_command_line, bench_config, is_envvar_warn_set, verbose, sys_argv
|
global from_command_line, bench_config, is_envvar_warn_set, verbose
|
||||||
|
|
||||||
from_command_line = True
|
from_command_line = True
|
||||||
command = " ".join(sys.argv)
|
command = " ".join(sys.argv)
|
||||||
argv = set(sys.argv)
|
argv = set(sys.argv)
|
||||||
is_envvar_warn_set = not (os.environ.get("BENCH_DEVELOPER") or os.environ.get("CI"))
|
is_envvar_warn_set = not (os.environ.get("BENCH_DEVELOPER") or os.environ.get("CI"))
|
||||||
is_cli_command = len(sys.argv) > 1 and not argv.intersection({"src", "--version"})
|
is_cli_command = len(sys.argv) > 1 and not argv.intersection({"src", "--version"})
|
||||||
sys_argv = parse_sys_argv()
|
cmd_from_sys = get_cmd_from_sysargv()
|
||||||
|
|
||||||
if "--verbose" in sys_argv.options:
|
if "--verbose" in argv:
|
||||||
verbose = True
|
verbose = True
|
||||||
|
|
||||||
change_working_directory()
|
change_working_directory()
|
||||||
@ -69,8 +89,8 @@ def cli():
|
|||||||
if (
|
if (
|
||||||
is_envvar_warn_set
|
is_envvar_warn_set
|
||||||
and is_cli_command
|
and is_cli_command
|
||||||
and is_dist_editable(bench.PROJECT_NAME)
|
|
||||||
and not bench_config.get("developer_mode")
|
and not bench_config.get("developer_mode")
|
||||||
|
and is_dist_editable(bench.PROJECT_NAME)
|
||||||
):
|
):
|
||||||
log(
|
log(
|
||||||
"bench is installed in editable mode!\n\nThis is not the recommended mode"
|
"bench is installed in editable mode!\n\nThis is not the recommended mode"
|
||||||
@ -89,36 +109,30 @@ def cli():
|
|||||||
):
|
):
|
||||||
log("Command not being executed in bench directory", level=3)
|
log("Command not being executed in bench directory", level=3)
|
||||||
|
|
||||||
if in_bench and len(sys.argv) > 1:
|
if len(sys.argv) == 1 or sys.argv[1] == "--help":
|
||||||
if sys.argv[1] == "--help":
|
print(click.Context(bench_command).get_help())
|
||||||
print(click.Context(bench_command).get_help())
|
if in_bench:
|
||||||
print(get_frappe_help())
|
print(get_frappe_help())
|
||||||
return
|
return
|
||||||
|
|
||||||
if (
|
_opts = [x.opts + x.secondary_opts for x in bench_command.params]
|
||||||
sys_argv.commands.intersection(get_cached_frappe_commands())
|
opts = {item for sublist in _opts for item in sublist}
|
||||||
or sys_argv.commands.intersection(get_frappe_commands())
|
|
||||||
):
|
# handle usages like `--use-feature='feat-x'` and `--use-feature 'feat-x'`
|
||||||
|
if cmd_from_sys and cmd_from_sys.split("=", 1)[0].strip() in opts:
|
||||||
|
bench_command()
|
||||||
|
|
||||||
|
if cmd_from_sys in bench_command.commands:
|
||||||
|
with execute_cmd(check_for_update=not is_cli_command, command=command, logger=logger):
|
||||||
|
bench_command()
|
||||||
|
|
||||||
|
if in_bench:
|
||||||
|
if cmd_from_sys in get_frappe_commands():
|
||||||
frappe_cmd()
|
frappe_cmd()
|
||||||
|
else:
|
||||||
if sys.argv[1] in Bench(".").apps:
|
|
||||||
app_cmd()
|
app_cmd()
|
||||||
|
|
||||||
if not is_cli_command:
|
bench_command()
|
||||||
atexit.register(check_latest_version)
|
|
||||||
|
|
||||||
try:
|
|
||||||
bench_command()
|
|
||||||
except BaseException as e:
|
|
||||||
return_code = getattr(e, "code", 1)
|
|
||||||
|
|
||||||
if isinstance(e, Exception):
|
|
||||||
click.secho(f"ERROR: {e}", fg="red")
|
|
||||||
|
|
||||||
if return_code:
|
|
||||||
logger.warning(f"{command} executed with exit code {return_code}")
|
|
||||||
|
|
||||||
raise e
|
|
||||||
|
|
||||||
|
|
||||||
def check_uid():
|
def check_uid():
|
||||||
|
@ -165,7 +165,7 @@ def which(executable: str, raise_err: bool = False) -> str:
|
|||||||
return exec_
|
return exec_
|
||||||
|
|
||||||
|
|
||||||
def setup_logging(bench_path=".") -> "logger":
|
def setup_logging(bench_path=".") -> logging.Logger:
|
||||||
LOG_LEVEL = 15
|
LOG_LEVEL = 15
|
||||||
logging.addLevelName(LOG_LEVEL, "LOG")
|
logging.addLevelName(LOG_LEVEL, "LOG")
|
||||||
|
|
||||||
@ -529,13 +529,41 @@ class _dict(dict):
|
|||||||
return _dict(dict(self).copy())
|
return _dict(dict(self).copy())
|
||||||
|
|
||||||
|
|
||||||
def parse_sys_argv():
|
def get_cmd_from_sysargv():
|
||||||
sys_argv = _dict(options=set(), commands=set())
|
"""Identify and segregate tokens to options and command
|
||||||
|
|
||||||
for c in sys.argv[1:]:
|
For Command: `bench --profile --site frappeframework.com migrate --no-backup`
|
||||||
if c.startswith("-"):
|
sys.argv: ["/home/frappe/.local/bin/bench", "--profile", "--site", "frappeframework.com", "migrate", "--no-backup"]
|
||||||
sys_argv.options.add(c)
|
Actual command run: migrate
|
||||||
else:
|
|
||||||
sys_argv.commands.add(c)
|
|
||||||
|
|
||||||
return sys_argv
|
"""
|
||||||
|
# context is passed as options to frappe's bench_helper
|
||||||
|
from bench.bench import Bench
|
||||||
|
frappe_context = _dict(
|
||||||
|
params={"--site"},
|
||||||
|
flags={"--verbose", "--profile", "--force"}
|
||||||
|
)
|
||||||
|
cmd_from_ctx = None
|
||||||
|
sys_argv = sys.argv[1:]
|
||||||
|
skip_next = False
|
||||||
|
|
||||||
|
for arg in sys_argv:
|
||||||
|
if skip_next:
|
||||||
|
skip_next = False
|
||||||
|
continue
|
||||||
|
|
||||||
|
if arg in frappe_context.flags:
|
||||||
|
continue
|
||||||
|
|
||||||
|
elif arg in frappe_context.params:
|
||||||
|
skip_next = True
|
||||||
|
continue
|
||||||
|
|
||||||
|
if sys_argv.index(arg) == 0 and arg in Bench(".").apps:
|
||||||
|
continue
|
||||||
|
|
||||||
|
cmd_from_ctx = arg
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
|
return cmd_from_ctx
|
||||||
|
Loading…
Reference in New Issue
Block a user