diff --git a/bench/cli.py b/bench/cli.py index c1c75bc5..723c596e 100755 --- a/bench/cli.py +++ b/bench/cli.py @@ -1,16 +1,27 @@ +# imports - standard imports import atexit +import json +import logging +import os +import pwd +import subprocess +import sys + +# imports - third party imports import click -import os, sys, logging, json, pwd, subprocess -from bench.utils import is_root, PatchError, drop_privileges, get_env_cmd, get_cmd_output, get_frappe, log, is_dist_editable, find_parent_bench, check_latest_version + +# imports - module imports from bench.app import get_apps -from bench.config.common_site_config import get_config from bench.commands import bench_command +from bench.config.common_site_config import get_config +from bench.utils import PatchError, bench_cache_file, check_latest_version, drop_privileges, find_parent_bench, generate_command_cache, get_cmd_output, get_env_cmd, get_frappe, is_bench_directory, is_dist_editable, is_root, log logger = logging.getLogger('bench') from_command_line = False change_uid_msg = "You should not run this command as root" + def cli(): global from_command_line from_command_line = True @@ -20,46 +31,50 @@ def cli(): change_dir() change_uid() - if is_dist_editable("bench"): + if is_dist_editable("bench") and len(sys.argv) > 1 and sys.argv[1] != "src": log("bench is installed in editable mode!\n\nThis is not the recommended mode of installation for production. Instead, install the package from PyPI with: `pip install frappe-bench`\n", level=3) + if not is_bench_directory() and not cmd_requires_root() and len(sys.argv) > 1 and sys.argv[1] not in ("init", "find", "src"): + log("Command not being executed in bench directory", level=3) + if len(sys.argv) > 2 and sys.argv[1] == "frappe": return old_frappe_cli() - elif len(sys.argv) > 1 and sys.argv[1] in get_frappe_commands(): - return frappe_cmd() + elif len(sys.argv) > 1: + if sys.argv[1] in get_frappe_commands() + ["--site", "--verbose", "--force", "--profile"]: + return frappe_cmd() - elif len(sys.argv) > 1 and sys.argv[1] in ("--site", "--verbose", "--force", "--profile"): - return frappe_cmd() + elif sys.argv[1] == "--help": + print(click.Context(bench_command).get_help()) + print(get_frappe_help()) + return - elif len(sys.argv) > 1 and sys.argv[1]=="--help": - print(click.Context(bench_command).get_help()) - print(get_frappe_help()) - return + elif sys.argv[1] in get_apps(): + return app_cmd() - elif len(sys.argv) > 1 and sys.argv[1] in get_apps(): - return app_cmd() + if not (len(sys.argv) > 1 and sys.argv[1] == "src"): + atexit.register(check_latest_version) + + try: + bench_command() + except PatchError: + sys.exit(1) - else: - try: - atexit.register(check_latest_version) - bench_command() - except PatchError: - sys.exit(1) def check_uid(): if cmd_requires_root() and not is_root(): log('superuser privileges required for this command', level=3) sys.exit(1) + def cmd_requires_root(): if len(sys.argv) > 2 and sys.argv[2] in ('production', 'sudoers', 'supervisor', 'lets-encrypt', 'fonts', - 'print', 'firewall', 'ssh-port', 'role', 'fail2ban', 'wildcard-ssl'): + 'print', 'firewall', 'ssh-port', 'role', 'fail2ban', 'wildcard-ssl', 'install'): return True - if len(sys.argv) >= 2 and sys.argv[1] in ('patch', 'renew-lets-encrypt', 'disable-production', - 'install'): + if len(sys.argv) >= 2 and sys.argv[1] in ('patch', 'renew-lets-encrypt', 'disable-production'): return True + def change_dir(): if os.path.exists('config.json') or "init" in sys.argv: return @@ -70,6 +85,7 @@ def change_dir(): if os.path.exists(dir_path): os.chdir(dir_path) + def change_uid(): if is_root() and not cmd_requires_root(): frappe_user = get_config(".").get('frappe_user') @@ -80,35 +96,37 @@ def change_uid(): log(change_uid_msg, level=3) sys.exit(1) + def old_frappe_cli(bench_path='.'): f = get_frappe(bench_path=bench_path) os.chdir(os.path.join(bench_path, 'sites')) os.execv(f, [f] + sys.argv[2:]) + def app_cmd(bench_path='.'): f = get_env_cmd('python', bench_path=bench_path) os.chdir(os.path.join(bench_path, 'sites')) os.execv(f, [f] + ['-m', 'frappe.utils.bench_helper'] + sys.argv[1:]) + def frappe_cmd(bench_path='.'): f = get_env_cmd('python', bench_path=bench_path) os.chdir(os.path.join(bench_path, 'sites')) os.execv(f, [f] + ['-m', 'frappe.utils.bench_helper', 'frappe'] + sys.argv[1:]) -def get_frappe_commands(bench_path='.'): - python = get_env_cmd('python', bench_path=bench_path) - sites_path = os.path.join(bench_path, 'sites') - if not os.path.exists(sites_path): - log("Command not being executed in bench directory", level=3) - return [] - try: - output = get_cmd_output("{python} -m frappe.utils.bench_helper get-frappe-commands".format(python=python), cwd=sites_path) - return json.loads(output) - except subprocess.CalledProcessError as e: - if hasattr(e, "stderr"): - print(e.stderr.decode('utf-8')) + +def get_frappe_commands(): + if not is_bench_directory(): return [] + if os.path.exists(bench_cache_file): + command_dump = open(bench_cache_file, 'r').read() or '[]' + return json.loads(command_dump) + + else: + return generate_command_cache() + + def get_frappe_help(bench_path='.'): python = get_env_cmd('python', bench_path=bench_path) sites_path = os.path.join(bench_path, 'sites') @@ -118,6 +136,7 @@ def get_frappe_help(bench_path='.'): except: return "" + def change_working_directory(): """Allows bench commands to be run from anywhere inside a bench directory""" cur_dir = os.path.abspath(".")