2
0
mirror of https://github.com/frappe/bench.git synced 2024-11-16 10:05:21 +00:00

perf: Faster bench remove-app

Biggest bottleneck is in the validation stage which checks if the app is
installed on any existing sites on the bench. instead of triggering
multiple list-apps for each sites, do one for all.
This commit is contained in:
Gavin D'souza 2021-04-02 01:12:19 +05:30
parent 70c9c17f63
commit ebc3cebd19

View File

@ -3,6 +3,7 @@ from __future__ import print_function
# imports - standard imports # imports - standard imports
import json import json
from json.decoder import JSONDecodeError
import logging import logging
import os import os
import re import re
@ -202,13 +203,56 @@ def remove_app(app, bench_path='.'):
import shutil import shutil
from bench.config.common_site_config import get_config from bench.config.common_site_config import get_config
app_path = os.path.join(bench_path, 'apps', app)
py = os.path.join(bench_path, 'env', 'bin', 'python')
# validate app removal
if app not in get_apps(bench_path): if app not in get_apps(bench_path):
print("No app named {0}".format(app)) print("No app named {0}".format(app))
sys.exit(1) sys.exit(1)
app_path = os.path.join(bench_path, 'apps', app) validate_app_installed_on_sites(app, bench_path=bench_path)
# remove app from bench
exec_cmd("{0} -m pip uninstall -y {1}".format(py, app), cwd=bench_path)
remove_from_appstxt(app, bench_path)
shutil.rmtree(app_path)
# re-build assets and restart processes
run_frappe_cmd("build", bench_path=bench_path)
if get_config(bench_path).get('restart_supervisor_on_update'):
restart_supervisor_processes(bench_path=bench_path)
if get_config(bench_path).get('restart_systemd_on_update'):
restart_systemd_processes(bench_path=bench_path)
def validate_app_installed_on_sites(app, bench_path="."):
print("Checking if app installed on active sites...")
ret = check_app_installed(app, bench_path=bench_path)
if ret is None:
check_app_installed_legacy(app, bench_path=bench_path)
else:
return ret
def check_app_installed(app, bench_path="."):
out = subprocess.check_output(["bench", "--site", "all", "list-apps", "--format", "json"], cwd=bench_path).decode('utf-8')
try:
import json
apps_sites_dict = json.loads(out)
except JSONDecodeError:
return None
for site, apps in apps_sites_dict.items():
if app in apps:
print("Cannot remove, app is installed on site: {0}".format(site))
sys.exit(1)
def check_app_installed_legacy(app, bench_path="."):
site_path = os.path.join(bench_path, 'sites') site_path = os.path.join(bench_path, 'sites')
py = os.path.join(bench_path, 'env', 'bin', 'python')
for site in os.listdir(site_path): for site in os.listdir(site_path):
req_file = os.path.join(site_path, site, 'site_config.json') req_file = os.path.join(site_path, site, 'site_config.json')
@ -218,14 +262,6 @@ def remove_app(app, bench_path='.'):
print("Cannot remove, app is installed on site: {0}".format(site)) print("Cannot remove, app is installed on site: {0}".format(site))
sys.exit(1) sys.exit(1)
exec_cmd("{0} -m pip uninstall -y {1}".format(py, app), cwd=bench_path)
remove_from_appstxt(app, bench_path)
shutil.rmtree(app_path)
run_frappe_cmd("build", bench_path=bench_path)
if get_config(bench_path).get('restart_supervisor_on_update'):
restart_supervisor_processes(bench_path=bench_path)
if get_config(bench_path).get('restart_systemd_on_update'):
restart_systemd_processes(bench_path=bench_path)
def pull_apps(apps=None, bench_path='.', reset=False): def pull_apps(apps=None, bench_path='.', reset=False):
'''Check all apps if there no local changes, pull''' '''Check all apps if there no local changes, pull'''