2
0
mirror of https://github.com/frappe/bench.git synced 2024-09-29 07:19:05 +00:00

chore: move 'find_parent_bench' to utils

style: consistent spaces and formatting, code cleanup
This commit is contained in:
Gavin D'souza 2020-02-13 04:15:30 +05:30
parent 90d2313947
commit b4f4e71719
4 changed files with 75 additions and 30 deletions

View File

@ -1,6 +1,6 @@
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_bench_directory
from bench.utils import is_root, PatchError, drop_privileges, get_env_cmd, get_cmd_output, get_frappe, log, is_bench_directory, find_parent_bench
from bench.app import get_apps
from bench.config.common_site_config import get_config
from bench.commands import bench_command
@ -29,7 +29,6 @@ def cli():
elif len(sys.argv) > 1 and sys.argv[1]=="--help":
print(click.Context(bench_command).get_help())
print()
print(get_frappe_help())
return
@ -99,7 +98,6 @@ def get_frappe_commands(bench_path='.'):
return []
try:
output = get_cmd_output("{python} -m frappe.utils.bench_helper get-frappe-commands".format(python=python), cwd=sites_path)
# output = output.decode('utf-8')
return json.loads(output)
except subprocess.CalledProcessError as e:
if hasattr(e, "stderr"):
@ -109,27 +107,12 @@ def get_frappe_commands(bench_path='.'):
def get_frappe_help(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):
return []
try:
out = get_cmd_output("{python} -m frappe.utils.bench_helper get-frappe-help".format(python=python), cwd=sites_path)
return "Framework commands:\n" + out.split('Commands:')[1]
except subprocess.CalledProcessError:
return "\n\nFramework commands:\n" + out.split('Commands:')[1]
except:
return ""
def find_parent_bench(path):
"""Checks if parent directories are benches"""
if is_bench_directory(directory=path):
return path
home_path = os.path.expanduser("~")
root_path = os.path.abspath(os.sep)
if path not in {home_path, root_path}:
# NOTE: the os.path.split assumes that given path is absolute
parent_dir = os.path.split(path)[0]
return find_parent_bench(parent_dir)
def change_working_directory():
"""Allows bench commands to be run from anywhere inside a bench directory"""
cur_dir = os.path.abspath(".")

View File

@ -19,9 +19,7 @@ def prepare_staging(bench_path, app, remote='upstream'):
print('No commits to release')
return
print()
print(message)
print()
click.confirm('Do you want to continue?', abort=True)
@ -52,13 +50,13 @@ def create_staging(repo_path, from_branch='develop'):
g.merge(from_branch, '--no-ff')
except git.exc.GitCommandError as e:
handle_merge_error(e, source=from_branch, target='staging')
g.checkout(from_branch)
try:
g.merge('staging')
except git.exc.GitCommandError as e:
handle_merge_error(e, source='staging', target=from_branch)
def push_commits(repo_path, remote='upstream'):
print('pushing staging branch of', repo_path)

View File

@ -83,9 +83,7 @@ def bump(bench_path, app, bump_type, from_branch, to_branch, remote, owner, repo
print('No commits to release')
return
print()
print(message)
print()
click.confirm('Do you want to continue?', abort=True)

View File

@ -80,6 +80,7 @@ def safe_decode(string, encoding = 'utf-8'):
pass
return string
def get_frappe(bench_path='.'):
frappe = get_env_cmd('frappe', bench_path=bench_path)
if not os.path.exists(frappe):
@ -87,9 +88,11 @@ def get_frappe(bench_path='.'):
print('bench get-app https://github.com/frappe/frappe.git')
return frappe
def get_env_cmd(cmd, bench_path='.'):
return os.path.abspath(os.path.join(bench_path, 'env', 'bin', cmd))
def init(path, apps_path=None, no_procfile=False, no_backups=False,
frappe_path=None, frappe_branch=None, verbose=False, clone_from=None,
skip_redis_config_generation=False, clone_without_update=False, ignore_exist=False, skip_assets=False,
@ -152,10 +155,12 @@ def init(path, apps_path=None, no_procfile=False, no_backups=False,
copy_patches_txt(path)
def restart_update(kwargs):
args = ['--'+k for k, v in list(kwargs.items()) if v]
os.execv(sys.argv[0], sys.argv[:2] + args)
def update(pull=False, patch=False, build=False, bench=False, restart_supervisor=False,
restart_systemd=False, requirements=False, backup=True, force=False, reset=False):
"""command: bench update"""
@ -242,10 +247,12 @@ def update(pull=False, patch=False, build=False, bench=False, restart_supervisor
print("_" * 80 + "\nBench: Deployment tool for Frappe and Frappe Applications (https://frappe.io/bench).\nOpen source depends on your contributions, so please contribute bug reports, patches, fixes or cash and be a part of the community")
def copy_patches_txt(bench_path):
shutil.copy(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'patches', 'patches.txt'),
os.path.join(bench_path, 'patches.txt'))
def clone_apps_from(bench_path, clone_from, update_app=True):
from .app import install_app
print('Copying apps from {0}...'.format(clone_from))
@ -282,6 +289,7 @@ def clone_apps_from(bench_path, clone_from, update_app=True):
for app in apps:
setup_app(app)
def exec_cmd(cmd, cwd='.'):
from .cli import from_command_line
@ -304,6 +312,7 @@ def exec_cmd(cmd, cwd='.'):
if return_code > 0:
raise CommandFailedError(cmd)
def which(executable, raise_err = False):
from distutils.spawn import find_executable
exec_ = find_executable(executable)
@ -315,6 +324,7 @@ def which(executable, raise_err = False):
return exec_
def setup_env(bench_path='.', python = 'python3'):
python = which(python, raise_err = True)
pip = os.path.join('env', 'bin', 'pip')
@ -323,10 +333,12 @@ def setup_env(bench_path='.', python = 'python3'):
exec_cmd('{} -q install -U pip wheel six'.format(pip), cwd=bench_path)
exec_cmd('{} -q install -e git+https://github.com/frappe/python-pdfkit.git#egg=pdfkit'.format(pip), cwd=bench_path)
def setup_socketio(bench_path='.'):
exec_cmd("npm install socket.io redis express superagent cookie babel-core less chokidar \
babel-cli babel-preset-es2015 babel-preset-es2016 babel-preset-es2017 babel-preset-babili", cwd=bench_path)
def patch_sites(bench_path='.'):
bench.set_frappe_version(bench_path=bench_path)
@ -338,6 +350,7 @@ def patch_sites(bench_path='.'):
except subprocess.CalledProcessError:
raise PatchError
def build_assets(bench_path='.', app=None):
bench.set_frappe_version(bench_path=bench_path)
@ -349,14 +362,17 @@ def build_assets(bench_path='.', app=None):
command += ' --app {}'.format(app)
exec_cmd(command, cwd=bench_path)
def get_sites(bench_path='.'):
sites_path = os.path.join(bench_path, 'sites')
sites = (site for site in os.listdir(sites_path) if os.path.exists(os.path.join(sites_path, site, 'site_config.json')))
return sites
def get_bench_dir(bench_path='.'):
return os.path.abspath(bench_path)
def setup_backups(bench_path='.'):
logger.info('setting up backups')
bench_dir = get_bench_dir(bench_path=bench_path)
@ -370,6 +386,7 @@ def setup_backups(bench_path='.'):
add_to_crontab('0 */6 * * * {backup_command} >> {logfile} 2>&1'.format(backup_command=backup_command,
logfile=os.path.join(get_bench_dir(bench_path=bench_path), 'logs', 'backup.log')))
def add_to_crontab(line):
current_crontab = read_crontab()
line = str.encode(line)
@ -382,12 +399,14 @@ def add_to_crontab(line):
s.stdin.write(line + b'\n')
s.stdin.close()
def read_crontab():
s = subprocess.Popen(["crontab", "-l"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
out = s.stdout.read()
s.stdout.close()
return out
def update_bench(bench_repo=True, requirements=True):
logger.info("Updating bench")
@ -406,6 +425,7 @@ def update_bench(bench_repo=True, requirements=True):
logger.info("Bench Updated!")
def setup_sudoers(user):
from bench import env
@ -440,6 +460,7 @@ def setup_sudoers(user):
os.chmod(sudoers_file, 0o440)
def setup_logging(bench_path='.'):
if os.path.exists(os.path.join(bench_path, 'logs')):
logger = logging.getLogger('bench')
@ -450,6 +471,7 @@ def setup_logging(bench_path='.'):
logger.addHandler(hdlr)
logger.setLevel(logging.DEBUG)
def get_program(programs):
program = None
for p in programs:
@ -458,9 +480,11 @@ def get_program(programs):
break
return program
def get_process_manager():
return get_program(['foreman', 'forego', 'honcho'])
def start(no_dev=False, concurrency=None, procfile=None):
program = get_process_manager()
if not program:
@ -478,6 +502,7 @@ def start(no_dev=False, concurrency=None, procfile=None):
os.execv(program, command)
def check_cmd(cmd, cwd='.'):
try:
subprocess.check_call(cmd, cwd=cwd, shell=True)
@ -485,6 +510,7 @@ def check_cmd(cmd, cwd='.'):
except subprocess.CalledProcessError:
return False
def get_git_version():
'''returns git version from `git --version`
extracts version number from string `get version 1.9.1` etc'''
@ -494,6 +520,7 @@ def get_git_version():
version = '.'.join(version.split('.')[0:2])
return float(version)
def check_git_for_shallow_clone():
from .config.common_site_config import get_config
config = get_config('.')
@ -509,6 +536,7 @@ def check_git_for_shallow_clone():
if git_version > 1.9:
return True
def get_cmd_output(cmd, cwd='.'):
try:
output = subprocess.check_output(cmd, cwd=cwd, shell=True, stderr=subprocess.PIPE).strip()
@ -519,6 +547,7 @@ def get_cmd_output(cmd, cwd='.'):
print(e.output)
raise
def safe_encode(what, encoding = 'utf-8'):
try:
what = what.encode(encoding)
@ -527,6 +556,7 @@ def safe_encode(what, encoding = 'utf-8'):
return what
def restart_supervisor_processes(bench_path='.', web_workers=False):
from .config.common_site_config import get_config
conf = get_config(bench_path=bench_path)
@ -556,26 +586,31 @@ def restart_supervisor_processes(bench_path='.', web_workers=False):
exec_cmd('sudo supervisorctl restart {group}'.format(group=group), cwd=bench_path)
def restart_systemd_processes(bench_path='.', web_workers=False):
from .config.common_site_config import get_config
bench_name = get_bench_name(bench_path)
exec_cmd('sudo systemctl stop -- $(systemctl show -p Requires {bench_name}.target | cut -d= -f2)'.format(bench_name=bench_name))
exec_cmd('sudo systemctl start -- $(systemctl show -p Requires {bench_name}.target | cut -d= -f2)'.format(bench_name=bench_name))
def set_default_site(site, bench_path='.'):
if site not in get_sites(bench_path=bench_path):
raise Exception("Site not in bench")
exec_cmd("{frappe} --use {site}".format(frappe=get_frappe(bench_path=bench_path), site=site),
cwd=os.path.join(bench_path, 'sites'))
def update_bench_requirements():
bench_req_file = os.path.join(os.path.dirname(bench.__path__[0]), 'requirements.txt')
install_requirements(bench_req_file, user=True)
def update_env_pip(bench_path):
env_pip = os.path.join(bench_path, 'env', 'bin', 'pip')
exec_cmd("{pip} install -q -U pip".format(pip=env_pip))
def update_requirements(bench_path='.'):
from bench.app import get_apps, install_app
print('Updating Python libraries...')
@ -589,13 +624,13 @@ def update_requirements(bench_path='.'):
for app in get_apps():
install_app(app, bench_path=bench_path)
def update_node_packages(bench_path='.'):
print('Updating node packages...')
from bench.app import get_develop_version
from distutils.version import LooseVersion
v = LooseVersion(get_develop_version('frappe', bench_path = bench_path))
# After rollup was merged, frappe_version = 10.1
# if develop_verion is 11 and up, only then install yarn
if v < LooseVersion('11.x.x-develop'):
@ -603,6 +638,7 @@ def update_node_packages(bench_path='.'):
else:
update_yarn_packages(bench_path)
def update_yarn_packages(bench_path='.'):
apps_dir = os.path.join(bench_path, 'apps')
@ -663,6 +699,7 @@ def install_requirements(req_file, user=False):
exec_cmd("{python} -m pip install {user_flag} -q -U -r {req_file}".format(python=python, user_flag=user_flag, req_file=req_file))
def backup_site(site, bench_path='.'):
bench.set_frappe_version(bench_path=bench_path)
@ -672,30 +709,38 @@ def backup_site(site, bench_path='.'):
else:
run_frappe_cmd('--site', site, 'backup', bench_path=bench_path)
def backup_all_sites(bench_path='.'):
for site in get_sites(bench_path=bench_path):
backup_site(site, bench_path=bench_path)
def is_root():
if os.getuid() == 0:
return True
return False
def set_mariadb_host(host, bench_path='.'):
update_common_site_config({'db_host': host}, bench_path=bench_path)
def set_redis_cache_host(host, bench_path='.'):
update_common_site_config({'redis_cache': "redis://{}".format(host)}, bench_path=bench_path)
def set_redis_queue_host(host, bench_path='.'):
update_common_site_config({'redis_queue': "redis://{}".format(host)}, bench_path=bench_path)
def set_redis_socketio_host(host, bench_path='.'):
update_common_site_config({'redis_socketio': "redis://{}".format(host)}, bench_path=bench_path)
def update_common_site_config(ddict, bench_path='.'):
update_json_file(os.path.join(bench_path, 'sites', 'common_site_config.json'), ddict)
def update_json_file(filename, ddict):
if os.path.exists(filename):
with open(filename, 'r') as f:
@ -708,6 +753,7 @@ def update_json_file(filename, ddict):
with open(filename, 'w') as f:
json.dump(content, f, indent=1, sort_keys=True)
def drop_privileges(uid_name='nobody', gid_name='nogroup'):
# from http://stackoverflow.com/a/2699996
if os.getuid() != 0:
@ -728,6 +774,7 @@ def drop_privileges(uid_name='nobody', gid_name='nogroup'):
# Ensure a very conservative umask
os.umask(0o22)
def fix_prod_setup_perms(bench_path='.', frappe_user=None):
from .config.common_site_config import get_config
@ -745,6 +792,7 @@ def fix_prod_setup_perms(bench_path='.', frappe_user=None):
gid = grp.getgrnam(frappe_user).gr_gid
os.chown(path, uid, gid)
def fix_file_perms():
for dir_path, dirs, files in os.walk('.'):
for _dir in dirs:
@ -757,10 +805,12 @@ def fix_file_perms():
if not _file.startswith('activate'):
os.chmod(os.path.join(bin_dir, _file), 0o755)
def get_current_frappe_version(bench_path='.'):
from .app import get_current_frappe_version as fv
return fv(bench_path=bench_path)
def run_frappe_cmd(*args, **kwargs):
from .cli import from_command_line
@ -784,7 +834,7 @@ def run_frappe_cmd(*args, **kwargs):
if return_code > 0:
sys.exit(return_code)
#raise CommandFailedError(args)
def get_frappe_cmd_output(*args, **kwargs):
bench_path = kwargs.get('bench_path', '.')
@ -792,19 +842,20 @@ def get_frappe_cmd_output(*args, **kwargs):
sites_dir = os.path.join(bench_path, 'sites')
return subprocess.check_output((f, '-m', 'frappe.utils.bench_helper', 'frappe') + args, cwd=sites_dir)
def validate_upgrade(from_ver, to_ver, bench_path='.'):
if to_ver >= 6:
if not find_executable('npm') and not (find_executable('node') or find_executable('nodejs')):
raise Exception("Please install nodejs and npm")
def post_upgrade(from_ver, to_ver, bench_path='.'):
from .config.common_site_config import get_config
from .config import redis
from .config.supervisor import generate_supervisor_config
from .config.nginx import make_nginx_conf
conf = get_config(bench_path=bench_path)
print("-"*80)
print("Your bench was upgraded to version {0}".format(to_ver))
print("-" * 80 + "Your bench was upgraded to version {0}".format(to_ver))
if conf.get('restart_supervisor_on_update'):
redis.generate_config(bench_path=bench_path)
@ -1080,6 +1131,7 @@ def in_virtual_env():
return False
def migrate_env(python, backup=False):
from bench.config.common_site_config import get_config
from bench.app import get_apps
@ -1136,3 +1188,17 @@ def migrate_env(python, backup=False):
except:
log.debug('Migration Error')
raise
def find_parent_bench(path):
"""Checks if parent directories are benches"""
if is_bench_directory(directory=path):
return path
home_path = os.path.expanduser("~")
root_path = os.path.abspath(os.sep)
if path not in {home_path, root_path}:
# NOTE: the os.path.split assumes that given path is absolute
parent_dir = os.path.split(path)[0]
return find_parent_bench(parent_dir)