2
0
mirror of https://github.com/frappe/bench.git synced 2024-11-17 02:25:16 +00:00
bench/bench/app.py

221 lines
7.8 KiB
Python
Raw Normal View History

2014-07-10 17:21:34 +00:00
import os
2016-04-27 13:51:46 +00:00
from .utils import (exec_cmd, get_frappe, check_git_for_shallow_clone, build_assets,
2016-03-15 11:27:48 +00:00
restart_supervisor_processes, get_cmd_output, run_frappe_cmd)
from .config.common_site_config import get_config
2014-07-10 17:21:34 +00:00
2014-07-11 09:33:07 +00:00
import logging
2014-07-21 06:10:03 +00:00
import requests
import semantic_version
2014-07-21 06:10:03 +00:00
import json
import re
import subprocess
2016-01-11 06:58:02 +00:00
logging.basicConfig(level="DEBUG")
2014-07-11 09:33:07 +00:00
logger = logging.getLogger(__name__)
2014-07-10 17:21:34 +00:00
class MajorVersionUpgradeException(Exception):
def __init__(self, message, upstream_version, local_version):
super(MajorVersionUpgradeException, self).__init__(message)
self.upstream_version = upstream_version
self.local_version = local_version
2014-07-10 17:21:34 +00:00
def get_apps(bench='.'):
try:
with open(os.path.join(bench, 'sites', 'apps.txt')) as f:
return f.read().strip().split('\n')
except IOError:
return []
def add_to_appstxt(app, bench='.'):
apps = get_apps(bench=bench)
if app not in apps:
apps.append(app)
2014-11-20 07:30:57 +00:00
return write_appstxt(apps, bench=bench)
def remove_from_appstxt(app, bench='.'):
apps = get_apps(bench=bench)
if app in apps:
apps.remove(app)
return write_appstxt(apps, bench=bench)
def write_appstxt(apps, bench='.'):
with open(os.path.join(bench, 'sites', 'apps.txt'), 'w') as f:
return f.write('\n'.join(apps))
2014-07-10 17:21:34 +00:00
2015-12-08 18:52:16 +00:00
def get_app(app, git_url, branch=None, bench='.', build_asset_files=True, verbose=False):
2014-07-11 09:33:07 +00:00
logger.info('getting app {}'.format(app))
2016-03-16 07:33:09 +00:00
shallow_clone = '--depth 1' if check_git_for_shallow_clone() else ''
2014-09-12 09:30:18 +00:00
branch = '--branch {branch}'.format(branch=branch) if branch else ''
2016-04-27 13:51:46 +00:00
exec_cmd("git clone {git_url} {branch} {shallow_clone} --origin upstream {app}".format(
git_url=git_url,
app=app,
shallow_clone=shallow_clone,
branch=branch),
cwd=os.path.join(bench, 'apps'))
2014-09-30 18:45:09 +00:00
print 'installing', app
2015-12-08 18:52:16 +00:00
install_app(app, bench=bench, verbose=verbose)
2014-12-03 05:35:12 +00:00
if build_asset_files:
build_assets(bench=bench)
conf = get_config(bench=bench)
if conf.get('restart_supervisor_on_update'):
2014-10-31 10:27:31 +00:00
restart_supervisor_processes(bench=bench)
2014-07-10 17:21:34 +00:00
def new_app(app, bench='.'):
2016-04-29 10:06:46 +00:00
# For backwards compatibility
app = app.lower().replace(" ", "_").replace("-", "_")
2014-07-11 09:33:07 +00:00
logger.info('creating new app {}'.format(app))
2015-03-06 12:48:11 +00:00
apps = os.path.abspath(os.path.join(bench, 'apps'))
2015-03-03 11:25:03 +00:00
if FRAPPE_VERSION == 4:
exec_cmd("{frappe} --make_app {apps} {app}".format(frappe=get_frappe(bench=bench),
apps=apps, app=app))
2015-03-03 11:04:35 +00:00
else:
run_frappe_cmd('make-app', apps, app, bench=bench)
2014-07-10 17:21:34 +00:00
install_app(app, bench=bench)
2015-12-08 18:52:16 +00:00
def install_app(app, bench='.', verbose=False):
2014-07-11 09:33:07 +00:00
logger.info('installing {}'.format(app))
# find_links = '--find-links={}'.format(conf.get('wheel_cache_dir')) if conf.get('wheel_cache_dir') else ''
find_links = ''
2015-12-08 18:52:16 +00:00
exec_cmd("{pip} install {quiet} {find_links} -e {app}".format(
pip=os.path.join(bench, 'env', 'bin', 'pip'),
2015-12-08 18:52:16 +00:00
quiet="-q" if not verbose else "",
app=os.path.join(bench, 'apps', app),
find_links=find_links))
2014-07-10 17:21:34 +00:00
add_to_appstxt(app, bench=bench)
2015-03-05 09:38:39 +00:00
def pull_all_apps(bench='.'):
2016-02-26 06:58:01 +00:00
rebase = '--rebase' if get_config(bench).get('rebase_on_pull') else ''
2015-07-04 08:36:53 +00:00
for app in get_apps(bench=bench):
app_dir = get_repo_dir(app, bench=bench)
2014-07-10 17:21:34 +00:00
if os.path.exists(os.path.join(app_dir, '.git')):
2014-09-05 03:58:55 +00:00
logger.info('pulling {0}'.format(app))
2015-07-04 08:36:53 +00:00
exec_cmd("git pull {rebase} upstream {branch}".format(rebase=rebase, branch=get_current_branch(app, bench=bench)), cwd=app_dir)
2014-10-30 07:08:02 +00:00
2015-05-04 04:12:25 +00:00
def is_version_upgrade(bench='.', branch=None):
2015-07-04 08:36:53 +00:00
fetch_upstream('frappe', bench=bench)
upstream_version = get_upstream_version('frappe', bench=bench, branch=branch)
if not upstream_version:
raise Exception("Current branch of 'frappe' not in upstream")
2015-07-04 08:36:53 +00:00
local_version = get_major_version(get_current_version('frappe', bench=bench))
upstream_version = get_major_version(upstream_version)
2015-07-04 08:36:53 +00:00
if upstream_version - local_version > 0:
return (True, local_version, upstream_version)
return (False, local_version, upstream_version)
2015-02-24 09:40:30 +00:00
def get_current_frappe_version(bench='.'):
2015-03-03 11:09:07 +00:00
try:
2015-07-04 08:36:53 +00:00
return get_major_version(get_current_version('frappe', bench=bench))
2015-03-03 11:09:07 +00:00
except IOError:
2016-04-27 13:51:46 +00:00
return 0
2015-02-24 09:40:30 +00:00
2015-07-04 08:36:53 +00:00
def get_current_branch(app, bench='.'):
repo_dir = get_repo_dir(app, bench=bench)
2014-10-30 07:08:02 +00:00
return get_cmd_output("basename $(git symbolic-ref -q HEAD)", cwd=repo_dir)
2014-07-21 06:10:03 +00:00
2016-05-05 10:53:00 +00:00
def use_rq(bench_path):
bench_path = os.path.abspath(bench_path)
celery_app = os.path.join(bench_path, 'apps', 'frappe', 'frappe', 'celery_app.py')
return not os.path.exists(celery_app)
2015-07-04 08:36:53 +00:00
def fetch_upstream(app, bench='.'):
repo_dir = get_repo_dir(app, bench=bench)
return exec_cmd("git fetch upstream", cwd=repo_dir)
2015-07-04 08:36:53 +00:00
def get_current_version(app, bench='.'):
repo_dir = get_repo_dir(app, bench=bench)
with open(os.path.join(repo_dir, 'setup.py')) as f:
return get_version_from_string(f.read())
2015-07-04 08:36:53 +00:00
def get_upstream_version(app, branch=None, bench='.'):
repo_dir = get_repo_dir(app, bench=bench)
2015-05-04 04:12:25 +00:00
if not branch:
2015-09-27 22:37:22 +00:00
branch = get_current_branch(app, bench=bench)
try:
2015-05-04 04:12:25 +00:00
contents = subprocess.check_output(['git', 'show', 'upstream/{branch}:setup.py'.format(branch=branch)], cwd=repo_dir, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError, e:
if "Invalid object" in e.output:
return None
else:
raise
return get_version_from_string(contents)
2015-07-04 08:36:53 +00:00
def get_upstream_url(app, bench='.'):
repo_dir = get_repo_dir(app, bench=bench)
return subprocess.check_output(['git', 'config', '--get', 'remote.upstream.url'], cwd=repo_dir).strip()
def get_repo_dir(app, bench='.'):
return os.path.join(bench, 'apps', app)
2015-05-04 04:12:25 +00:00
def switch_branch(branch, apps=None, bench='.', upgrade=False):
from .utils import update_requirements, backup_all_sites, patch_sites, build_assets, pre_upgrade, post_upgrade
import utils
apps_dir = os.path.join(bench, 'apps')
2015-05-04 04:12:25 +00:00
version_upgrade = is_version_upgrade(bench=bench, branch=branch)
if version_upgrade[0] and not upgrade:
raise MajorVersionUpgradeException("Switching to {0} will cause upgrade from {1} to {2}. Pass --upgrade to confirm".format(branch, version_upgrade[1], version_upgrade[2]), version_upgrade[1], version_upgrade[2])
2015-05-04 04:12:25 +00:00
if not apps:
2015-09-03 06:39:16 +00:00
apps = ['frappe', 'erpnext']
if branch=="v4.x.x":
apps.append('shopping_cart')
for app in apps:
app_dir = os.path.join(apps_dir, app)
if os.path.exists(app_dir):
unshallow = "--unshallow" if os.path.exists(os.path.join(app_dir, ".git", "shallow")) else ""
exec_cmd("git config --unset-all remote.upstream.fetch", cwd=app_dir)
exec_cmd("git config --add remote.upstream.fetch '+refs/heads/*:refs/remotes/upstream/*'", cwd=app_dir)
exec_cmd("git fetch upstream {unshallow}".format(unshallow=unshallow), cwd=app_dir)
exec_cmd("git checkout {branch}".format(branch=branch), cwd=app_dir)
exec_cmd("git merge upstream/{branch}".format(branch=branch), cwd=app_dir)
if version_upgrade[0] and upgrade:
2015-05-04 04:12:25 +00:00
update_requirements()
pre_upgrade(version_upgrade[1], version_upgrade[2])
2015-05-04 04:12:25 +00:00
reload(utils)
backup_all_sites()
patch_sites()
build_assets()
post_upgrade(version_upgrade[1], version_upgrade[2])
2015-05-04 04:12:25 +00:00
def switch_to_master(apps=None, bench='.', upgrade=False):
switch_branch('master', apps=apps, bench=bench, upgrade=upgrade)
2015-05-04 04:12:25 +00:00
def switch_to_develop(apps=None, bench='.', upgrade=False):
switch_branch('develop', apps=apps, bench=bench, upgrade=upgrade)
2015-05-04 04:12:25 +00:00
def switch_to_v4(apps=None, bench='.', upgrade=False):
switch_branch('v4.x.x', apps=apps, bench=bench, upgrade=upgrade)
2015-08-22 23:56:29 +00:00
def switch_to_v5(apps=None, bench='.', upgrade=False):
switch_branch('v5.x.x', apps=apps, bench=bench, upgrade=upgrade)
def get_version_from_string(contents):
match = re.search(r"^(\s*%s\s*=\s*['\\\"])(.+?)(['\"])(?sm)" % 'version',
contents)
return match.group(2)
def get_major_version(version):
return semantic_version.Version(version).major
def install_apps_from_path(path, bench='.'):
2014-08-01 11:11:05 +00:00
apps = get_apps_json(path)
for app in apps:
get_app(app['name'], app['url'], branch=app.get('branch'), bench=bench, build_asset_files=False)
2014-07-21 06:10:03 +00:00
2014-08-01 11:11:05 +00:00
def get_apps_json(path):
2014-07-21 06:10:03 +00:00
if path.startswith('http'):
r = requests.get(path)
return r.json()
else:
with open(path) as f:
return json.load(f)
2015-03-03 11:04:35 +00:00
FRAPPE_VERSION = get_current_frappe_version()