From b51f0ed2b2c3c26b29e8d038bec134275dbff808 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 13 Sep 2021 20:55:21 +0530 Subject: [PATCH] feat: `bench setup requirements --dev` (#1196) * chore: typo * chore: update project description * feat: command to install dev-requirements.txt Often applications have development or test specific requirements which are not required in production. - Add new command `bench setup dev-requirements` - installs all `dev-requirements.txt` in app's root folder. * refactor: remove duplicate function * refactor: use `log` instead of print * refactor: merge dev-requirement command * feat: install dev-dependencies in get-app if dev When developer mode is enabled install all dev dependencies too while doing `get-app` * fix: warn about --dev not supporting node --- bench/app.py | 8 ++++++-- bench/commands/setup.py | 10 +++++++++- bench/utils.py | 24 ++++++++++++++++++++++-- docs/bench_custom_cmd.md | 2 +- setup.py | 2 +- 5 files changed, 39 insertions(+), 7 deletions(-) diff --git a/bench/app.py b/bench/app.py index 352f858d..97cbe6a8 100755 --- a/bench/app.py +++ b/bench/app.py @@ -181,12 +181,16 @@ def install_app(app, bench_path=".", verbose=False, no_cache=False, restart_benc add_to_appstxt(app, bench_path=bench_path) + conf = get_config(bench_path=bench_path) + + if conf.get("developer_mode"): + from bench.utils import install_python_dev_dependencies + install_python_dev_dependencies(apps=app) + if not skip_assets: build_assets(bench_path=bench_path, app=app) if restart_bench: - conf = get_config(bench_path=bench_path) - if conf.get('restart_supervisor_on_update'): restart_supervisor_processes(bench_path=bench_path) if conf.get('restart_systemd_on_update'): diff --git a/bench/commands/setup.py b/bench/commands/setup.py index 51f87030..73b3eb3a 100755 --- a/bench/commands/setup.py +++ b/bench/commands/setup.py @@ -135,7 +135,8 @@ def setup_socketio(): @click.command("requirements", help="Setup Python and Node dependencies") @click.option("--node", help="Update only Node packages", default=False, is_flag=True) @click.option("--python", help="Update only Python packages", default=False, is_flag=True) -def setup_requirements(node=False, python=False): +@click.option("--dev", help="Install optional python development dependencies", default=False, is_flag=True) +def setup_requirements(node=False, python=False, dev=False): if not (node or python): from bench.utils import update_requirements update_requirements() @@ -148,6 +149,13 @@ def setup_requirements(node=False, python=False): from bench.utils import update_node_packages update_node_packages() + if dev: + from bench.utils import install_python_dev_dependencies + install_python_dev_dependencies() + + if node: + click.secho("--dev flag only supports python dependencies. All node development dependencies are installed by default.", fg="yellow") + @click.command("manager", help="Setup bench-manager.local site with the bench_manager app installed on it") @click.option("--yes", help="Yes to regeneration of nginx config file", default=False, is_flag=True) diff --git a/bench/utils.py b/bench/utils.py index bfe6469c..99f7870b 100755 --- a/bench/utils.py +++ b/bench/utils.py @@ -577,7 +577,7 @@ def set_default_site(site, bench_path='.'): def update_env_pip(bench_path): - env_py = os.path.join(bench_path, 'env', 'bin', 'python') + env_py = get_env_cmd("python") exec_cmd(f"{env_py} -m pip install -q -U pip") @@ -593,7 +593,7 @@ def update_requirements(bench_path='.'): def update_python_packages(bench_path='.'): from bench.app import get_apps - env_py = os.path.join(bench_path, "env", "bin", "python") + env_py = get_env_cmd("python") print('Updating Python libraries...') update_env_pip(bench_path) @@ -617,6 +617,26 @@ def update_node_packages(bench_path='.'): update_yarn_packages(bench_path) +def install_python_dev_dependencies(bench_path='.', apps=None): + from bench.app import get_apps + + if isinstance(apps, str): + apps = [apps] + elif apps is None: + apps = get_apps() + + env_py = get_env_cmd("python") + for app in apps: + app_path = os.path.join(bench_path, "apps", app) + dev_requirements_path = os.path.join(app_path, "dev-requirements.txt") + + if os.path.exists(dev_requirements_path): + log(f'Installing python development dependencies for {app}') + exec_cmd(f"{env_py} -m pip install -q -r {dev_requirements_path}", cwd=bench_path) + else: + log(f'dev-requirements.txt not found in {app}', level=3) + + def update_yarn_packages(bench_path='.'): apps_dir = os.path.join(bench_path, 'apps') diff --git a/docs/bench_custom_cmd.md b/docs/bench_custom_cmd.md index 693739ba..72ef1559 100644 --- a/docs/bench_custom_cmd.md +++ b/docs/bench_custom_cmd.md @@ -7,7 +7,7 @@ bench utilizes `frappe.utils.bench_manager` to get the framework's as well as th Along with the framework commands, Frappe's `bench_manager` module also searches for any commands in your custom applications. Thereby, bench communicates with the respective bench's Frappe which in turn checks for available commands in all of the applications. -To make your custom command available to bench, just create a `commands` module under your parent module and write the command with a click wrapper and a variable commands which contains a list of click functions, which are your own commands. The directory strcuture may be visualized as: +To make your custom command available to bench, just create a `commands` module under your parent module and write the command with a click wrapper and a variable commands which contains a list of click functions, which are your own commands. The directory structure may be visualized as: ``` frappe-bench diff --git a/setup.py b/setup.py index be99d6c2..36835aa6 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ with open('requirements.txt') as f: setup( name=PROJECT_NAME, - description='Metadata driven, full-stack web framework', + description='CLI to manage Multi-tenant deployments for Frappe apps', author='Frappe Technologies', author_email='info@frappe.io', version=VERSION,