From 2fa25d8791e23385eec60614abfd190f3d39a617 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Tue, 28 Dec 2021 13:36:01 +0530 Subject: [PATCH] fix: Command picking & execution Parse sys.argv appropriately and use them to match commands "better". Using hacks to match with flags and options appear to be faulty, so dropped that. Only matching with command names remains. Fixes https://github.com/frappe/bench/issues/1223 --- bench/cli.py | 26 +++++++++++++------------- bench/utils/__init__.py | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/bench/cli.py b/bench/cli.py index 96ac2365..9cf946cc 100755 --- a/bench/cli.py +++ b/bench/cli.py @@ -25,6 +25,7 @@ from bench.utils import ( is_root, log, setup_logging, + parse_sys_argv, ) from bench.utils.bench import get_env_cmd @@ -34,21 +35,23 @@ verbose = False is_envvar_warn_set = None from_command_line = False # set when commands are executed via the CLI bench.LOG_BUFFER = [] +sys_argv = None change_uid_msg = "You should not run this command as root" src = os.path.dirname(__file__) def cli(): - global from_command_line, bench_config, is_envvar_warn_set, verbose + global from_command_line, bench_config, is_envvar_warn_set, verbose, sys_argv from_command_line = True command = " ".join(sys.argv) argv = set(sys.argv) 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"}) + sys_argv = parse_sys_argv() - if "--verbose" in sys.argv: + if "--verbose" in sys_argv.options: verbose = True change_working_directory() @@ -92,13 +95,10 @@ def cli(): print(get_frappe_help()) return - if sys.argv[1] in ["--site", "--force", "--profile"]: - frappe_cmd() - - if sys.argv[1] in get_cached_frappe_commands(): - frappe_cmd() - - if sys.argv[1] in get_frappe_commands(): + if ( + sys_argv.commands.intersection(get_cached_frappe_commands()) + or sys_argv.commands.intersection(get_frappe_commands()) + ): frappe_cmd() if sys.argv[1] in Bench(".").apps: @@ -188,15 +188,15 @@ def frappe_cmd(bench_path="."): def get_cached_frappe_commands(): if os.path.exists(bench_cache_file): command_dump = open(bench_cache_file, "r").read() or "[]" - return json.loads(command_dump) - return [] + return set(json.loads(command_dump)) + return set() def get_frappe_commands(): if not is_bench_directory(): - return [] + return set() - return generate_command_cache() + return set(generate_command_cache()) def get_frappe_help(bench_path="."): diff --git a/bench/utils/__init__.py b/bench/utils/__init__.py index adfbf6c0..f75fe263 100644 --- a/bench/utils/__init__.py +++ b/bench/utils/__init__.py @@ -471,3 +471,38 @@ def get_traceback() -> str: trace_list = format_exception(exc_type, exc_value, exc_tb) return "".join(trace_list) + + +class _dict(dict): + """dict like object that exposes keys as attributes""" + # bench port of frappe._dict + def __getattr__(self, key): + ret = self.get(key) + # "__deepcopy__" exception added to fix frappe#14833 via DFP + if not ret and key.startswith("__") and key != "__deepcopy__": + raise AttributeError() + return ret + def __setattr__(self, key, value): + self[key] = value + def __getstate__(self): + return self + def __setstate__(self, d): + self.update(d) + def update(self, d): + """update and return self -- the missing dict feature in python""" + super(_dict, self).update(d) + return self + def copy(self): + return _dict(dict(self).copy()) + + +def parse_sys_argv(): + sys_argv = _dict(options=set(), commands=set()) + + for c in sys.argv[1:]: + if c.startswith("-"): + sys_argv.options.add(c) + else: + sys_argv.commands.add(c) + + return sys_argv