2
0
mirror of https://github.com/frappe/bench.git synced 2024-09-23 12:39:01 +00:00

Add reference feature

This commit is contained in:
Pratik Vyas 2015-06-07 17:02:30 +05:30
parent 39fbb25782
commit 220405103c
3 changed files with 57 additions and 26 deletions

View File

@ -11,12 +11,14 @@ import subprocess
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class MajorVersionUpgradeException(Exception): class MajorVersionUpgradeException(Exception):
def __init__(self, message, upstream_version, local_version): def __init__(self, message, upstream_version, local_version):
super(MajorVersionUpgradeException, self).__init__(message) super(MajorVersionUpgradeException, self).__init__(message)
self.upstream_version = upstream_version self.upstream_version = upstream_version
self.local_version = local_version self.local_version = local_version
def get_apps(bench='.'): def get_apps(bench='.'):
try: try:
with open(os.path.join(bench, 'sites', 'apps.txt')) as f: with open(os.path.join(bench, 'sites', 'apps.txt')) as f:
@ -24,32 +26,39 @@ def get_apps(bench='.'):
except IOError: except IOError:
return [] return []
def add_to_appstxt(app, bench='.'): def add_to_appstxt(app, bench='.'):
apps = get_apps(bench=bench) apps = get_apps(bench=bench)
if app not in apps: if app not in apps:
apps.append(app) apps.append(app)
return write_appstxt(apps, bench=bench) return write_appstxt(apps, bench=bench)
def remove_from_appstxt(app, bench='.'): def remove_from_appstxt(app, bench='.'):
apps = get_apps(bench=bench) apps = get_apps(bench=bench)
if app in apps: if app in apps:
apps.remove(app) apps.remove(app)
return write_appstxt(apps, bench=bench) return write_appstxt(apps, bench=bench)
def write_appstxt(apps, bench='.'): def write_appstxt(apps, bench='.'):
with open(os.path.join(bench, 'sites', 'apps.txt'), 'w') as f: with open(os.path.join(bench, 'sites', 'apps.txt'), 'w') as f:
return f.write('\n'.join(apps)) return f.write('\n'.join(apps))
def get_app(app, git_url, branch=None, bench='.', build_asset_files=True):
def get_app(app, git_url, branch=None, bench='.', build_asset_files=True, reference_bench=''):
logger.info('getting app {}'.format(app)) logger.info('getting app {}'.format(app))
shallow_clone = '--depth 1' if check_git_for_shallow_clone() and get_config().get('shallow_clone') else '' shallow_clone = '--depth 1' if check_git_for_shallow_clone() and get_config().get('shallow_clone') else ''
reference = os.path.abspath(os.path.join(reference_bench, 'apps', app))
reference = '--reference {}'.format(reference) if os.path.exists(reference) else ''
branch = '--branch {branch}'.format(branch=branch) if branch else '' branch = '--branch {branch}'.format(branch=branch) if branch else ''
exec_cmd("git clone {git_url} {branch} {shallow_clone} --origin upstream {app}".format( exec_cmd("git clone {reference} {git_url} {branch} {shallow_clone} --origin upstream {app}".format(
git_url=git_url, git_url=git_url,
app=app, app=app,
shallow_clone=shallow_clone, shallow_clone=shallow_clone,
branch=branch), reference=reference,
cwd=os.path.join(bench, 'apps')) branch=branch),
cwd=os.path.join(bench, 'apps'))
print 'installing', app print 'installing', app
install_app(app, bench=bench) install_app(app, bench=bench)
if build_asset_files: if build_asset_files:
@ -58,31 +67,34 @@ def get_app(app, git_url, branch=None, bench='.', build_asset_files=True):
if conf.get('restart_supervisor_on_update'): if conf.get('restart_supervisor_on_update'):
restart_supervisor_processes(bench=bench) restart_supervisor_processes(bench=bench)
def new_app(app, bench='.'): def new_app(app, bench='.'):
logger.info('creating new app {}'.format(app)) logger.info('creating new app {}'.format(app))
apps = os.path.abspath(os.path.join(bench, 'apps')) apps = os.path.abspath(os.path.join(bench, 'apps'))
if FRAPPE_VERSION == 4: if FRAPPE_VERSION == 4:
exec_cmd("{frappe} --make_app {apps} {app}".format(frappe=get_frappe(bench=bench), exec_cmd("{frappe} --make_app {apps} {app}".format(
frappe=get_frappe(bench=bench),
apps=apps, app=app)) apps=apps, app=app))
else: else:
run_frappe_cmd('make-app', apps, app, bench=bench) run_frappe_cmd('make-app', apps, app, bench=bench)
install_app(app, bench=bench) install_app(app, bench=bench)
def install_app(app, bench='.'): def install_app(app, bench='.'):
logger.info('installing {}'.format(app)) logger.info('installing {}'.format(app))
conf = get_config() conf = get_config()
find_links = '--find-links={}'.format(conf.get('wheel_cache_dir')) if conf.get('wheel_cache_dir') else '' find_links = '--find-links={}'.format(conf.get('wheel_cache_dir')) if conf.get('wheel_cache_dir') else ''
exec_cmd("{pip} install -q {find_links} -e {app}".format( exec_cmd("{pip} install {find_links} -e {app}".format(
pip=os.path.join(bench, 'env', 'bin', 'pip'), pip=os.path.join(bench, 'env', 'bin', 'pip'),
app=os.path.join(bench, 'apps', app), app=os.path.join(bench, 'apps', app),
find_links=find_links)) find_links=find_links))
add_to_appstxt(app, bench=bench) add_to_appstxt(app, bench=bench)
def pull_all_apps(bench='.'): def pull_all_apps(bench='.'):
apps_dir = os.path.join(bench, 'apps') apps_dir = os.path.join(bench, 'apps')
apps = [app for app in os.listdir(apps_dir) if os.path.isdir(os.path.join(apps_dir, app))] apps = [app for app in os.listdir(apps_dir) if os.path.isdir(os.path.join(apps_dir, app))]
rebase = '--rebase' if get_config().get('rebase_on_pull') else '' rebase = '--rebase' if get_config().get('rebase_on_pull') else ''
frappe_dir = os.path.join(apps_dir, 'frappe')
for app in apps: for app in apps:
app_dir = os.path.join(apps_dir, app) app_dir = os.path.join(apps_dir, app)
@ -90,6 +102,7 @@ def pull_all_apps(bench='.'):
logger.info('pulling {0}'.format(app)) logger.info('pulling {0}'.format(app))
exec_cmd("git pull {rebase} upstream {branch}".format(rebase=rebase, branch=get_current_branch(app_dir)), cwd=app_dir) exec_cmd("git pull {rebase} upstream {branch}".format(rebase=rebase, branch=get_current_branch(app_dir)), cwd=app_dir)
def is_version_upgrade(bench='.', branch=None): def is_version_upgrade(bench='.', branch=None):
apps_dir = os.path.join(bench, 'apps') apps_dir = os.path.join(bench, 'apps')
frappe_dir = os.path.join(apps_dir, 'frappe') frappe_dir = os.path.join(apps_dir, 'frappe')
@ -103,10 +116,11 @@ def is_version_upgrade(bench='.', branch=None):
local_version = get_major_version(get_current_version(frappe_dir)) local_version = get_major_version(get_current_version(frappe_dir))
upstream_version = get_major_version(upstream_version) upstream_version = get_major_version(upstream_version)
if upstream_version - local_version > 0: if upstream_version - local_version > 0:
return (local_version, upstream_version) return (local_version, upstream_version)
return False return False
def get_current_frappe_version(bench='.'): def get_current_frappe_version(bench='.'):
apps_dir = os.path.join(bench, 'apps') apps_dir = os.path.join(bench, 'apps')
frappe_dir = os.path.join(apps_dir, 'frappe') frappe_dir = os.path.join(apps_dir, 'frappe')
@ -116,16 +130,20 @@ def get_current_frappe_version(bench='.'):
except IOError: except IOError:
return '' return ''
def get_current_branch(repo_dir): def get_current_branch(repo_dir):
return get_cmd_output("basename $(git symbolic-ref -q HEAD)", cwd=repo_dir) return get_cmd_output("basename $(git symbolic-ref -q HEAD)", cwd=repo_dir)
def fetch_upstream(repo_dir): def fetch_upstream(repo_dir):
return exec_cmd("git fetch upstream", cwd=repo_dir) return exec_cmd("git fetch upstream", cwd=repo_dir)
def get_current_version(repo_dir): def get_current_version(repo_dir):
with open(os.path.join(repo_dir, 'setup.py')) as f: with open(os.path.join(repo_dir, 'setup.py')) as f:
return get_version_from_string(f.read()) return get_version_from_string(f.read())
def get_upstream_version(repo_dir, branch=None): def get_upstream_version(repo_dir, branch=None):
if not branch: if not branch:
branch = get_current_branch(repo_dir) branch = get_current_branch(repo_dir)
@ -138,6 +156,7 @@ def get_upstream_version(repo_dir, branch=None):
raise raise
return get_version_from_string(contents) return get_version_from_string(contents)
def switch_branch(branch, apps=None, bench='.', upgrade=False): 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 from .utils import update_requirements, backup_all_sites, patch_sites, build_assets, pre_upgrade, post_upgrade
import utils import utils
@ -147,7 +166,7 @@ def switch_branch(branch, apps=None, bench='.', upgrade=False):
raise MajorVersionUpgradeException("Switching to {0} will cause upgrade from {1} to {2}. Pass --upgrade to confirm".format(branch, version_upgrade[0], version_upgrade[1]), version_upgrade[0], version_upgrade[1]) raise MajorVersionUpgradeException("Switching to {0} will cause upgrade from {1} to {2}. Pass --upgrade to confirm".format(branch, version_upgrade[0], version_upgrade[1]), version_upgrade[0], version_upgrade[1])
if not apps: if not apps:
apps = ('frappe', 'erpnext', 'shopping_cart') apps = ('frappe', 'erpnext', 'shopping_cart')
for app in apps: for app in apps:
app_dir = os.path.join(apps_dir, app) app_dir = os.path.join(apps_dir, app)
if os.path.exists(app_dir): if os.path.exists(app_dir):
@ -167,27 +186,35 @@ def switch_branch(branch, apps=None, bench='.', upgrade=False):
build_assets() build_assets()
post_upgrade(version_upgrade[0], version_upgrade[1]) post_upgrade(version_upgrade[0], version_upgrade[1])
def switch_to_master(apps=None, bench='.', upgrade=False): def switch_to_master(apps=None, bench='.', upgrade=False):
switch_branch('master', apps=apps, bench=bench, upgrade=upgrade) switch_branch('master', apps=apps, bench=bench, upgrade=upgrade)
def switch_to_develop(apps=None, bench='.', upgrade=False): def switch_to_develop(apps=None, bench='.', upgrade=False):
switch_branch('develop', apps=apps, bench=bench, upgrade=upgrade) switch_branch('develop', apps=apps, bench=bench, upgrade=upgrade)
def switch_to_v4(apps=None, bench='.', upgrade=False): def switch_to_v4(apps=None, bench='.', upgrade=False):
switch_branch('v4.x.x', apps=apps, bench=bench, upgrade=upgrade) switch_branch('v4.x.x', apps=apps, bench=bench, upgrade=upgrade)
def get_version_from_string(contents): def get_version_from_string(contents):
match = re.search(r"^(\s*%s\s*=\s*['\\\"])(.+?)(['\"])(?sm)" % 'version', match = re.search(
contents) r"^(\s*%s\s*=\s*['\\\"])(.+?)(['\"])(?sm)" % 'version',
contents)
return match.group(2) return match.group(2)
def get_major_version(version): def get_major_version(version):
return semantic_version.Version(version).major return semantic_version.Version(version).major
def install_apps_from_path(path, bench='.'):
def install_apps_from_path(path, bench='.', reference_bench=''):
apps = get_apps_json(path) apps = get_apps_json(path)
for app in apps: for app in apps:
get_app(app['name'], app['url'], branch=app.get('branch'), bench=bench, build_asset_files=False) get_app(app['name'], app['url'], branch=app.get('branch'), bench=bench, build_asset_files=False, reference_bench=reference_bench)
def get_apps_json(path): def get_apps_json(path):
if path.startswith('http'): if path.startswith('http'):

View File

@ -151,14 +151,16 @@ def bench(bench='.'):
@click.option('--apps_path', default=None, help="path to json files with apps to install after init") @click.option('--apps_path', default=None, help="path to json files with apps to install after init")
@click.option('--frappe-path', default=None, help="path to frappe repo") @click.option('--frappe-path', default=None, help="path to frappe repo")
@click.option('--frappe-branch', default=None, help="path to frappe repo") @click.option('--frappe-branch', default=None, help="path to frappe repo")
@click.option('--reference', default=None, help="Reuse git objects from a reference bench")
@click.option('--no-procfile', flag_value=True, type=bool, help="Pull changes in all the apps in bench") @click.option('--no-procfile', flag_value=True, type=bool, help="Pull changes in all the apps in bench")
@click.option('--no-backups',flag_value=True, type=bool, help="Run migrations for all sites in the bench") @click.option('--no-backups',flag_value=True, type=bool, help="Run migrations for all sites in the bench")
@click.option('--no-auto-update',flag_value=True, type=bool, help="Build JS and CSS artifacts for the bench") @click.option('--no-auto-update',flag_value=True, type=bool, help="Build JS and CSS artifacts for the bench")
def init(path, apps_path, frappe_path, frappe_branch, no_procfile, no_backups, def init(path, apps_path, frappe_path, frappe_branch, reference, no_procfile, no_backups,
no_auto_update): no_auto_update):
"Create a new bench" "Create a new bench"
_init(path, apps_path=apps_path, no_procfile=no_procfile, no_backups=no_backups, _init(path, apps_path=apps_path, no_procfile=no_procfile, no_backups=no_backups,
no_auto_update=no_auto_update, frappe_path=frappe_path, frappe_branch=frappe_branch) no_auto_update=no_auto_update, frappe_path=frappe_path,
frappe_branch=frappe_branch, reference_bench=reference)
click.echo('Bench {} initialized'.format(path)) click.echo('Bench {} initialized'.format(path))
@click.command('get-app') @click.command('get-app')

View File

@ -38,8 +38,10 @@ def get_frappe(bench='.'):
def get_env_cmd(cmd, bench='.'): def get_env_cmd(cmd, bench='.'):
return os.path.abspath(os.path.join(bench, 'env', 'bin', cmd)) return os.path.abspath(os.path.join(bench, 'env', 'bin', cmd))
def init(path, apps_path=None, no_procfile=False, no_backups=False, def init(path, apps_path=None, no_procfile=False, no_backups=False,
no_auto_update=False, frappe_path=None, frappe_branch=None, wheel_cache_dir=None): no_auto_update=False, frappe_path=None, frappe_branch=None,
wheel_cache_dir=None, reference_bench=''):
from .app import get_app, install_apps_from_path from .app import get_app, install_apps_from_path
from .config import generate_redis_config from .config import generate_redis_config
global FRAPPE_VERSION global FRAPPE_VERSION
@ -56,12 +58,12 @@ def init(path, apps_path=None, no_procfile=False, no_backups=False,
setup_env(bench=path) setup_env(bench=path)
put_config(default_config, bench=path) put_config(default_config, bench=path)
if wheel_cache_dir: if wheel_cache_dir:
update_config({"wheel_cache_dir":wheel_cache_dir}, bench=path) update_config({"wheel_cache_dir": wheel_cache_dir}, bench=path)
prime_wheel_cache(bench=path) prime_wheel_cache(bench=path)
if not frappe_path: if not frappe_path:
frappe_path = 'https://github.com/frappe/frappe.git' frappe_path = 'https://github.com/frappe/frappe.git'
get_app('frappe', frappe_path, branch=frappe_branch, bench=path, build_asset_files=False) get_app('frappe', frappe_path, branch=frappe_branch, bench=path, build_asset_files=False, reference_bench=reference_bench)
if not no_procfile: if not no_procfile:
setup_procfile(bench=path) setup_procfile(bench=path)
if not no_backups: if not no_backups:
@ -69,7 +71,7 @@ def init(path, apps_path=None, no_procfile=False, no_backups=False,
if not no_auto_update: if not no_auto_update:
setup_auto_update(bench=path) setup_auto_update(bench=path)
if apps_path: if apps_path:
install_apps_from_path(apps_path, bench=path) install_apps_from_path(apps_path, bench=path, reference_bench=reference_bench)
FRAPPE_VERSION = get_current_frappe_version(bench=path) FRAPPE_VERSION = get_current_frappe_version(bench=path)
build_assets(bench=path) build_assets(bench=path)
generate_redis_config(bench=path) generate_redis_config(bench=path)