mirror of
https://github.com/frappe/bench.git
synced 2025-01-09 16:36:25 +00:00
ran 2to3 script (#381)
* ran 2to3 script * Correct urllib.parse import * Backward compatible urllib import * removed test_setup_production_v6
This commit is contained in:
parent
a1587b783f
commit
080ca173a6
24
bench/app.py
24
bench/app.py
@ -72,7 +72,7 @@ def get_app(git_url, branch=None, bench_path='.', build_asset_files=True, verbos
|
|||||||
apps_path = os.path.join(os.path.abspath(bench_path), 'apps')
|
apps_path = os.path.join(os.path.abspath(bench_path), 'apps')
|
||||||
os.rename(os.path.join(apps_path, repo_name), os.path.join(apps_path, app_name))
|
os.rename(os.path.join(apps_path, repo_name), os.path.join(apps_path, app_name))
|
||||||
|
|
||||||
print 'installing', app_name
|
print('installing', app_name)
|
||||||
install_app(app=app_name, bench_path=bench_path, verbose=verbose)
|
install_app(app=app_name, bench_path=bench_path, verbose=verbose)
|
||||||
|
|
||||||
if build_asset_files:
|
if build_asset_files:
|
||||||
@ -109,7 +109,7 @@ def install_app(app, bench_path='.', verbose=False, no_cache=False):
|
|||||||
|
|
||||||
def remove_app(app, bench_path='.'):
|
def remove_app(app, bench_path='.'):
|
||||||
if not app in get_apps(bench_path):
|
if not app 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)
|
app_path = os.path.join(bench_path, 'apps', app)
|
||||||
@ -121,7 +121,7 @@ def remove_app(app, bench_path='.'):
|
|||||||
if os.path.exists(req_file):
|
if os.path.exists(req_file):
|
||||||
out = subprocess.check_output(["bench", "--site", site, "list-apps"], cwd=bench_path)
|
out = subprocess.check_output(["bench", "--site", site, "list-apps"], cwd=bench_path)
|
||||||
if re.search(r'\b' + app + r'\b', out):
|
if re.search(r'\b' + app + r'\b', out):
|
||||||
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} uninstall -y {1}".format(pip, app_path)])
|
exec_cmd(["{0} uninstall -y {1}".format(pip, app_path)])
|
||||||
@ -143,7 +143,7 @@ def pull_all_apps(bench_path='.', reset=False):
|
|||||||
if os.path.exists(os.path.join(app_dir, '.git')):
|
if os.path.exists(os.path.join(app_dir, '.git')):
|
||||||
out = subprocess.check_output(["git", "status"], cwd=app_dir)
|
out = subprocess.check_output(["git", "status"], cwd=app_dir)
|
||||||
if not re.search(r'nothing to commit, working (directory|tree) clean', out):
|
if not re.search(r'nothing to commit, working (directory|tree) clean', out):
|
||||||
print '''
|
print('''
|
||||||
|
|
||||||
Cannot proceed with update: You have local changes in app "{0}" that are not committed.
|
Cannot proceed with update: You have local changes in app "{0}" that are not committed.
|
||||||
|
|
||||||
@ -153,7 +153,7 @@ Here are your choices:
|
|||||||
1. Temporarily remove your changes with "git stash" or discard them completely
|
1. Temporarily remove your changes with "git stash" or discard them completely
|
||||||
with "bench update --reset" or for individual repositries "git reset --hard"
|
with "bench update --reset" or for individual repositries "git reset --hard"
|
||||||
2. If your changes are helpful for others, send in a pull request via GitHub and
|
2. If your changes are helpful for others, send in a pull request via GitHub and
|
||||||
wait for them to be merged in the core.'''.format(app)
|
wait for them to be merged in the core.'''.format(app))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
for app in get_apps(bench_path=bench_path):
|
for app in get_apps(bench_path=bench_path):
|
||||||
@ -238,7 +238,7 @@ def get_upstream_version(app, branch=None, bench_path='.'):
|
|||||||
branch = get_current_branch(app, bench_path=bench_path)
|
branch = get_current_branch(app, bench_path=bench_path)
|
||||||
try:
|
try:
|
||||||
contents = subprocess.check_output(['git', 'show', 'upstream/{branch}:{app}/__init__.py'.format(branch=branch, app=app)], cwd=repo_dir, stderr=subprocess.STDOUT)
|
contents = subprocess.check_output(['git', 'show', 'upstream/{branch}:{app}/__init__.py'.format(branch=branch, app=app)], cwd=repo_dir, stderr=subprocess.STDOUT)
|
||||||
except subprocess.CalledProcessError, e:
|
except subprocess.CalledProcessError as e:
|
||||||
if "Invalid object" in e.output:
|
if "Invalid object" in e.output:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
@ -254,7 +254,7 @@ def get_repo_dir(app, bench_path='.'):
|
|||||||
|
|
||||||
def switch_branch(branch, apps=None, bench_path='.', upgrade=False, check_upgrade=True):
|
def switch_branch(branch, apps=None, bench_path='.', upgrade=False, check_upgrade=True):
|
||||||
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
|
from . import utils
|
||||||
apps_dir = os.path.join(bench_path, 'apps')
|
apps_dir = os.path.join(bench_path, 'apps')
|
||||||
version_upgrade = (False,)
|
version_upgrade = (False,)
|
||||||
switched_apps = []
|
switched_apps = []
|
||||||
@ -273,7 +273,7 @@ def switch_branch(branch, apps=None, bench_path='.', upgrade=False, check_upgrad
|
|||||||
version_upgrade = is_version_upgrade(app=app, bench_path=bench_path, branch=branch)
|
version_upgrade = is_version_upgrade(app=app, bench_path=bench_path, branch=branch)
|
||||||
if version_upgrade[0] and not upgrade:
|
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])
|
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])
|
||||||
print "Switching for "+app
|
print("Switching for "+app)
|
||||||
unshallow = "--unshallow" if os.path.exists(os.path.join(app_dir, ".git", "shallow")) else ""
|
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 --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 config --add remote.upstream.fetch '+refs/heads/*:refs/remotes/upstream/*'", cwd=app_dir)
|
||||||
@ -282,14 +282,14 @@ def switch_branch(branch, apps=None, bench_path='.', upgrade=False, check_upgrad
|
|||||||
exec_cmd("git merge upstream/{branch}".format(branch=branch), cwd=app_dir)
|
exec_cmd("git merge upstream/{branch}".format(branch=branch), cwd=app_dir)
|
||||||
switched_apps.append(app)
|
switched_apps.append(app)
|
||||||
except CommandFailedError:
|
except CommandFailedError:
|
||||||
print "Error switching to branch {0} for {1}".format(branch, app)
|
print("Error switching to branch {0} for {1}".format(branch, app))
|
||||||
except InvalidRemoteException:
|
except InvalidRemoteException:
|
||||||
print "Remote does not exist for app "+app
|
print("Remote does not exist for app "+app)
|
||||||
except InvalidBranchException:
|
except InvalidBranchException:
|
||||||
print "Branch {0} does not exist in Upstream for {1}".format(branch, app)
|
print("Branch {0} does not exist in Upstream for {1}".format(branch, app))
|
||||||
|
|
||||||
if switched_apps:
|
if switched_apps:
|
||||||
print "Successfully switched branches for:\n" + "\n".join(switched_apps)
|
print("Successfully switched branches for:\n" + "\n".join(switched_apps))
|
||||||
|
|
||||||
if version_upgrade[0] and upgrade:
|
if version_upgrade[0] and upgrade:
|
||||||
update_requirements()
|
update_requirements()
|
||||||
|
10
bench/cli.py
10
bench/cli.py
@ -26,9 +26,9 @@ def cli():
|
|||||||
return frappe_cmd()
|
return frappe_cmd()
|
||||||
|
|
||||||
elif len(sys.argv) > 1 and sys.argv[1]=="--help":
|
elif len(sys.argv) > 1 and sys.argv[1]=="--help":
|
||||||
print click.Context(bench_command).get_help()
|
print(click.Context(bench_command).get_help())
|
||||||
print
|
print()
|
||||||
print get_frappe_help()
|
print(get_frappe_help())
|
||||||
return
|
return
|
||||||
|
|
||||||
elif len(sys.argv) > 1 and sys.argv[1] in get_apps():
|
elif len(sys.argv) > 1 and sys.argv[1] in get_apps():
|
||||||
@ -43,7 +43,7 @@ def cli():
|
|||||||
|
|
||||||
def check_uid():
|
def check_uid():
|
||||||
if cmd_requires_root() and not is_root():
|
if cmd_requires_root() and not is_root():
|
||||||
print 'superuser privileges required for this command'
|
print('superuser privileges required for this command')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
def cmd_requires_root():
|
def cmd_requires_root():
|
||||||
@ -69,7 +69,7 @@ def change_uid():
|
|||||||
drop_privileges(uid_name=frappe_user, gid_name=frappe_user)
|
drop_privileges(uid_name=frappe_user, gid_name=frappe_user)
|
||||||
os.environ['HOME'] = pwd.getpwnam(frappe_user).pw_dir
|
os.environ['HOME'] = pwd.getpwnam(frappe_user).pw_dir
|
||||||
else:
|
else:
|
||||||
print 'You should not run this command as root'
|
print('You should not run this command as root')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
def old_frappe_cli(bench_path='.'):
|
def old_frappe_cli(bench_path='.'):
|
||||||
|
@ -64,7 +64,7 @@ def config_http_timeout(seconds):
|
|||||||
|
|
||||||
|
|
||||||
@click.command('set-common-config')
|
@click.command('set-common-config')
|
||||||
@click.option('configs', '-c', '--config', multiple=True, type=(unicode, unicode))
|
@click.option('configs', '-c', '--config', multiple=True, type=(str, str))
|
||||||
def set_common_config(configs):
|
def set_common_config(configs):
|
||||||
import ast
|
import ast
|
||||||
from bench.config.common_site_config import update_config
|
from bench.config.common_site_config import update_config
|
||||||
|
@ -29,5 +29,5 @@ def remote_urls():
|
|||||||
if os.path.exists(os.path.join(repo_dir, '.git')):
|
if os.path.exists(os.path.join(repo_dir, '.git')):
|
||||||
remote = get_remote(app)
|
remote = get_remote(app)
|
||||||
remote_url = subprocess.check_output(['git', 'config', '--get', 'remote.{}.url'.format(remote)], cwd=repo_dir).strip()
|
remote_url = subprocess.check_output(['git', 'config', '--get', 'remote.{}.url'.format(remote)], cwd=repo_dir).strip()
|
||||||
print "{app} {remote_url}".format(app=app, remote_url=remote_url)
|
print("{app} {remote_url}".format(app=app, remote_url=remote_url))
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ def add_domain(domain, site=None, ssl_certificate=None, ssl_certificate_key=None
|
|||||||
from bench.config.site_config import add_domain
|
from bench.config.site_config import add_domain
|
||||||
|
|
||||||
if not site:
|
if not site:
|
||||||
print "Please specify site"
|
print("Please specify site")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
add_domain(site, domain, ssl_certificate, ssl_certificate_key, bench_path='.')
|
add_domain(site, domain, ssl_certificate, ssl_certificate_key, bench_path='.')
|
||||||
@ -148,7 +148,7 @@ def remove_domain(domain, site=None):
|
|||||||
from bench.config.site_config import remove_domain
|
from bench.config.site_config import remove_domain
|
||||||
|
|
||||||
if not site:
|
if not site:
|
||||||
print "Please specify site"
|
print("Please specify site")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
remove_domain(site, domain, bench_path='.')
|
remove_domain(site, domain, bench_path='.')
|
||||||
@ -160,12 +160,12 @@ def sync_domains(domains, site=None):
|
|||||||
from bench.config.site_config import sync_domains
|
from bench.config.site_config import sync_domains
|
||||||
|
|
||||||
if not site:
|
if not site:
|
||||||
print "Please specify site"
|
print("Please specify site")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
domains = json.loads(domains)
|
domains = json.loads(domains)
|
||||||
if not isinstance(domains, list):
|
if not isinstance(domains, list):
|
||||||
print "Domains should be a json list of strings or dictionaries"
|
print("Domains should be a json list of strings or dictionaries")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
changed = sync_domains(site, domains, bench_path='.')
|
changed = sync_domains(site, domains, bench_path='.')
|
||||||
|
@ -45,18 +45,18 @@ def update(pull=False, patch=False, build=False, bench=False, auto=False, restar
|
|||||||
})
|
})
|
||||||
|
|
||||||
if conf.get('release_bench'):
|
if conf.get('release_bench'):
|
||||||
print 'Release bench, cannot update'
|
print('Release bench, cannot update')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
version_upgrade = is_version_upgrade()
|
version_upgrade = is_version_upgrade()
|
||||||
|
|
||||||
if version_upgrade[0] and not upgrade:
|
if version_upgrade[0] and not upgrade:
|
||||||
print
|
print()
|
||||||
print
|
print()
|
||||||
print "This update will cause a major version change in Frappe/ERPNext from {0} to {1}.".format(*version_upgrade[1:])
|
print("This update will cause a major version change in Frappe/ERPNext from {0} to {1}.".format(*version_upgrade[1:]))
|
||||||
print "This would take significant time to migrate and might break custom apps. Please run `bench update --upgrade` to confirm."
|
print("This would take significant time to migrate and might break custom apps. Please run `bench update --upgrade` to confirm.")
|
||||||
print
|
print()
|
||||||
print "You can stay on the latest stable release by running `bench switch-to-master` or pin your bench to {0} by running `bench switch-to-v{0}`".format(version_upgrade[1])
|
print("You can stay on the latest stable release by running `bench switch-to-master` or pin your bench to {0} by running `bench switch-to-v{0}`".format(version_upgrade[1]))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
_update(pull, patch, build, bench, auto, restart_supervisor, requirements, no_backup, upgrade, force=force, reset=reset)
|
_update(pull, patch, build, bench, auto, restart_supervisor, requirements, no_backup, upgrade, force=force, reset=reset)
|
||||||
@ -78,22 +78,22 @@ def _update(pull=False, patch=False, build=False, update_bench=False, auto=False
|
|||||||
pull_all_apps(bench_path=bench_path, reset=reset)
|
pull_all_apps(bench_path=bench_path, reset=reset)
|
||||||
|
|
||||||
if requirements:
|
if requirements:
|
||||||
print 'Updating Python libraries...'
|
print('Updating Python libraries...')
|
||||||
update_requirements(bench_path=bench_path)
|
update_requirements(bench_path=bench_path)
|
||||||
|
|
||||||
if upgrade and (version_upgrade[0] or (not version_upgrade[0] and force)):
|
if upgrade and (version_upgrade[0] or (not version_upgrade[0] and force)):
|
||||||
pre_upgrade(version_upgrade[1], version_upgrade[2], bench_path=bench_path)
|
pre_upgrade(version_upgrade[1], version_upgrade[2], bench_path=bench_path)
|
||||||
import bench.utils, bench.app
|
import bench.utils, bench.app
|
||||||
print 'Reloading bench...'
|
print('Reloading bench...')
|
||||||
reload(bench.utils)
|
reload(bench.utils)
|
||||||
reload(bench.app)
|
reload(bench.app)
|
||||||
|
|
||||||
if patch:
|
if patch:
|
||||||
if not no_backup:
|
if not no_backup:
|
||||||
print 'Backing up sites...'
|
print('Backing up sites...')
|
||||||
backup_all_sites(bench_path=bench_path)
|
backup_all_sites(bench_path=bench_path)
|
||||||
|
|
||||||
print 'Patching sites...'
|
print('Patching sites...')
|
||||||
patch_sites(bench_path=bench_path)
|
patch_sites(bench_path=bench_path)
|
||||||
if build:
|
if build:
|
||||||
build_assets(bench_path=bench_path)
|
build_assets(bench_path=bench_path)
|
||||||
@ -102,10 +102,10 @@ def _update(pull=False, patch=False, build=False, update_bench=False, auto=False
|
|||||||
if restart_supervisor or conf.get('restart_supervisor_on_update'):
|
if restart_supervisor or conf.get('restart_supervisor_on_update'):
|
||||||
restart_supervisor_processes(bench_path=bench_path)
|
restart_supervisor_processes(bench_path=bench_path)
|
||||||
|
|
||||||
print "_"*80
|
print("_"*80)
|
||||||
print "Bench: Deployment tool for Frappe and ERPNext (https://erpnext.org)."
|
print("Bench: Deployment tool for Frappe and ERPNext (https://erpnext.org).")
|
||||||
print "Open source depends on your contributions, so please contribute bug reports, patches, fixes or cash and be a part of the community"
|
print("Open source depends on your contributions, so please contribute bug reports, patches, fixes or cash and be a part of the community")
|
||||||
print
|
print()
|
||||||
|
|
||||||
|
|
||||||
@click.command('retry-upgrade')
|
@click.command('retry-upgrade')
|
||||||
@ -118,7 +118,7 @@ def retry_upgrade(version):
|
|||||||
|
|
||||||
|
|
||||||
def restart_update(kwargs):
|
def restart_update(kwargs):
|
||||||
args = ['--'+k for k, v in kwargs.items() if v]
|
args = ['--'+k for k, v in list(kwargs.items()) if v]
|
||||||
os.execv(sys.argv[0], sys.argv[:2] + args)
|
os.execv(sys.argv[0], sys.argv[:2] + args)
|
||||||
|
|
||||||
|
|
||||||
@ -130,8 +130,8 @@ def switch_to_branch(branch, apps, upgrade=False):
|
|||||||
"Switch all apps to specified branch, or specify apps separated by space"
|
"Switch all apps to specified branch, or specify apps separated by space"
|
||||||
from bench.app import switch_to_branch
|
from bench.app import switch_to_branch
|
||||||
switch_to_branch(branch=branch, apps=list(apps), upgrade=upgrade)
|
switch_to_branch(branch=branch, apps=list(apps), upgrade=upgrade)
|
||||||
print 'Switched to ' + branch
|
print('Switched to ' + branch)
|
||||||
print 'Please run `bench update --patch` to be safe from any differences in database schema'
|
print('Please run `bench update --patch` to be safe from any differences in database schema')
|
||||||
|
|
||||||
|
|
||||||
@click.command('switch-to-master')
|
@click.command('switch-to-master')
|
||||||
@ -140,9 +140,9 @@ def switch_to_master(upgrade=False):
|
|||||||
"Switch frappe and erpnext to master branch"
|
"Switch frappe and erpnext to master branch"
|
||||||
from bench.app import switch_to_master
|
from bench.app import switch_to_master
|
||||||
switch_to_master(upgrade=upgrade, apps=['frappe', 'erpnext'])
|
switch_to_master(upgrade=upgrade, apps=['frappe', 'erpnext'])
|
||||||
print
|
print()
|
||||||
print 'Switched to master'
|
print('Switched to master')
|
||||||
print 'Please run `bench update --patch` to be safe from any differences in database schema'
|
print('Please run `bench update --patch` to be safe from any differences in database schema')
|
||||||
|
|
||||||
|
|
||||||
@click.command('switch-to-develop')
|
@click.command('switch-to-develop')
|
||||||
@ -151,9 +151,9 @@ def switch_to_develop(upgrade=False):
|
|||||||
"Switch frappe and erpnext to develop branch"
|
"Switch frappe and erpnext to develop branch"
|
||||||
from bench.app import switch_to_develop
|
from bench.app import switch_to_develop
|
||||||
switch_to_develop(upgrade=upgrade, apps=['frappe', 'erpnext'])
|
switch_to_develop(upgrade=upgrade, apps=['frappe', 'erpnext'])
|
||||||
print
|
print()
|
||||||
print 'Switched to develop'
|
print('Switched to develop')
|
||||||
print 'Please run `bench update --patch` to be safe from any differences in database schema'
|
print('Please run `bench update --patch` to be safe from any differences in database schema')
|
||||||
|
|
||||||
|
|
||||||
@click.command('switch-to-v4')
|
@click.command('switch-to-v4')
|
||||||
@ -162,9 +162,9 @@ def switch_to_v4(upgrade=False):
|
|||||||
"Switch frappe and erpnext to v4 branch"
|
"Switch frappe and erpnext to v4 branch"
|
||||||
from bench.app import switch_to_v4
|
from bench.app import switch_to_v4
|
||||||
switch_to_v4(upgrade=upgrade)
|
switch_to_v4(upgrade=upgrade)
|
||||||
print
|
print()
|
||||||
print 'Switched to v4'
|
print('Switched to v4')
|
||||||
print 'Please run `bench update --patch` to be safe from any differences in database schema'
|
print('Please run `bench update --patch` to be safe from any differences in database schema')
|
||||||
|
|
||||||
|
|
||||||
@click.command('switch-to-v5')
|
@click.command('switch-to-v5')
|
||||||
@ -173,6 +173,6 @@ def switch_to_v5(upgrade=False):
|
|||||||
"Switch frappe and erpnext to v5 branch"
|
"Switch frappe and erpnext to v5 branch"
|
||||||
from bench.app import switch_to_v5
|
from bench.app import switch_to_v5
|
||||||
switch_to_v5(upgrade=upgrade)
|
switch_to_v5(upgrade=upgrade)
|
||||||
print
|
print()
|
||||||
print 'Switched to v5'
|
print('Switched to v5')
|
||||||
print 'Please run `bench update --patch` to be safe from any differences in database schema'
|
print('Please run `bench update --patch` to be safe from any differences in database schema')
|
||||||
|
@ -86,10 +86,10 @@ def renew_lets_encrypt():
|
|||||||
@click.command()
|
@click.command()
|
||||||
def shell(bench_path='.'):
|
def shell(bench_path='.'):
|
||||||
if not os.environ.get('SHELL'):
|
if not os.environ.get('SHELL'):
|
||||||
print "Cannot get shell"
|
print("Cannot get shell")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
if not os.path.exists('sites'):
|
if not os.path.exists('sites'):
|
||||||
print "sites dir doesn't exist"
|
print("sites dir doesn't exist")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
env = copy.copy(os.environ)
|
env = copy.copy(os.environ)
|
||||||
env['PS1'] = '(' + os.path.basename(os.path.dirname(os.path.abspath(__file__))) + ')' + env.get('PS1', '')
|
env['PS1'] = '(' + os.path.basename(os.path.dirname(os.path.abspath(__file__))) + ')' + env.get('PS1', '')
|
||||||
@ -104,7 +104,7 @@ def backup_site(site):
|
|||||||
"backup site"
|
"backup site"
|
||||||
from bench.utils import get_sites, backup_site
|
from bench.utils import get_sites, backup_site
|
||||||
if not site in get_sites(bench_path='.'):
|
if not site in get_sites(bench_path='.'):
|
||||||
print 'site not found'
|
print('site not found')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
backup_site(site, bench_path='.')
|
backup_site(site, bench_path='.')
|
||||||
|
|
||||||
@ -142,4 +142,4 @@ def disable_production():
|
|||||||
def bench_src():
|
def bench_src():
|
||||||
"""Prints bench source folder path, which can be used as: cd `bench src` """
|
"""Prints bench source folder path, which can be used as: cd `bench src` """
|
||||||
import bench
|
import bench
|
||||||
print os.path.dirname(bench.__path__[0])
|
print(os.path.dirname(bench.__path__[0]))
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
import os, multiprocessing, getpass, json, urlparse
|
import os, multiprocessing, getpass, json
|
||||||
|
|
||||||
|
try:
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
except ImportError:
|
||||||
|
from urlparse import urlparse
|
||||||
|
|
||||||
default_config = {
|
default_config = {
|
||||||
'restart_supervisor_on_update': False,
|
'restart_supervisor_on_update': False,
|
||||||
@ -81,19 +86,19 @@ def make_ports(bench_path):
|
|||||||
bench_path = os.path.join(benches_path, folder)
|
bench_path = os.path.join(benches_path, folder)
|
||||||
if os.path.isdir(bench_path):
|
if os.path.isdir(bench_path):
|
||||||
bench_config = get_config(bench_path)
|
bench_config = get_config(bench_path)
|
||||||
for key in default_ports.keys():
|
for key in list(default_ports.keys()):
|
||||||
value = bench_config.get(key)
|
value = bench_config.get(key)
|
||||||
|
|
||||||
# extract port from redis url
|
# extract port from redis url
|
||||||
if value and (key in ('redis_cache', 'redis_queue', 'redis_socketio')):
|
if value and (key in ('redis_cache', 'redis_queue', 'redis_socketio')):
|
||||||
value = urlparse.urlparse(value).port
|
value = urlparse(value).port
|
||||||
|
|
||||||
if value:
|
if value:
|
||||||
existing_ports.setdefault(key, []).append(value)
|
existing_ports.setdefault(key, []).append(value)
|
||||||
|
|
||||||
# new port value = max of existing port value + 1
|
# new port value = max of existing port value + 1
|
||||||
ports = {}
|
ports = {}
|
||||||
for key, value in default_ports.items():
|
for key, value in list(default_ports.items()):
|
||||||
existing_value = existing_ports.get(key, [])
|
existing_value = existing_ports.get(key, [])
|
||||||
if existing_value:
|
if existing_value:
|
||||||
value = max(existing_value) + 1
|
value = max(existing_value) + 1
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import bench, os, click, errno, urllib
|
import bench, os, click, errno
|
||||||
from bench.utils import exec_cmd, CommandFailedError
|
from bench.utils import exec_cmd, CommandFailedError
|
||||||
from bench.config.site_config import update_site_config, remove_domain, get_domains
|
from bench.config.site_config import update_site_config, remove_domain, get_domains
|
||||||
from bench.config.nginx import make_nginx_conf
|
from bench.config.nginx import make_nginx_conf
|
||||||
@ -6,22 +6,27 @@ from bench.config.production_setup import service
|
|||||||
from bench.config.common_site_config import get_config
|
from bench.config.common_site_config import get_config
|
||||||
from crontab import CronTab
|
from crontab import CronTab
|
||||||
|
|
||||||
|
try:
|
||||||
|
from urllib.request import urlretrieve
|
||||||
|
except ImportError:
|
||||||
|
from urllib import urlretrieve
|
||||||
|
|
||||||
def setup_letsencrypt(site, custom_domain, bench_path):
|
def setup_letsencrypt(site, custom_domain, bench_path):
|
||||||
|
|
||||||
site_path = os.path.join(bench_path, "sites", site, "site_config.json")
|
site_path = os.path.join(bench_path, "sites", site, "site_config.json")
|
||||||
if not os.path.exists(os.path.dirname(site_path)):
|
if not os.path.exists(os.path.dirname(site_path)):
|
||||||
print "No site named "+site
|
print("No site named "+site)
|
||||||
return
|
return
|
||||||
|
|
||||||
if custom_domain:
|
if custom_domain:
|
||||||
domains = get_domains(site, bench_path)
|
domains = get_domains(site, bench_path)
|
||||||
for d in domains:
|
for d in domains:
|
||||||
if (isinstance(d, dict) and d['domain']==custom_domain):
|
if (isinstance(d, dict) and d['domain']==custom_domain):
|
||||||
print "SSL for Domain {0} already exists".format(custom_domain)
|
print("SSL for Domain {0} already exists".format(custom_domain))
|
||||||
return
|
return
|
||||||
|
|
||||||
if not custom_domain in domains:
|
if not custom_domain in domains:
|
||||||
print "No custom domain named {0} set for site".format(custom_domain)
|
print("No custom domain named {0} set for site".format(custom_domain))
|
||||||
return
|
return
|
||||||
|
|
||||||
click.confirm('Running this will stop the nginx service temporarily causing your sites to go offline\n'
|
click.confirm('Running this will stop the nginx service temporarily causing your sites to go offline\n'
|
||||||
@ -29,7 +34,7 @@ def setup_letsencrypt(site, custom_domain, bench_path):
|
|||||||
abort=True)
|
abort=True)
|
||||||
|
|
||||||
if not get_config(bench_path).get("dns_multitenant"):
|
if not get_config(bench_path).get("dns_multitenant"):
|
||||||
print "You cannot setup SSL without DNS Multitenancy"
|
print("You cannot setup SSL without DNS Multitenancy")
|
||||||
return
|
return
|
||||||
|
|
||||||
create_config(site, custom_domain)
|
create_config(site, custom_domain)
|
||||||
@ -54,7 +59,7 @@ def run_certbot_and_setup_ssl(site, custom_domain, bench_path):
|
|||||||
exec_cmd("{path} --config /etc/letsencrypt/configs/{site}.cfg certonly".format(path=get_certbot_path(), site=custom_domain or site))
|
exec_cmd("{path} --config /etc/letsencrypt/configs/{site}.cfg certonly".format(path=get_certbot_path(), site=custom_domain or site))
|
||||||
except CommandFailedError:
|
except CommandFailedError:
|
||||||
service('nginx', 'start')
|
service('nginx', 'start')
|
||||||
print "There was a problem trying to setup SSL for your site"
|
print("There was a problem trying to setup SSL for your site")
|
||||||
return
|
return
|
||||||
|
|
||||||
ssl_path = "/etc/letsencrypt/live/{site}/".format(site=custom_domain or site)
|
ssl_path = "/etc/letsencrypt/live/{site}/".format(site=custom_domain or site)
|
||||||
@ -94,8 +99,8 @@ def get_certbot():
|
|||||||
create_dir_if_missing(certbot_path)
|
create_dir_if_missing(certbot_path)
|
||||||
|
|
||||||
if not os.path.isfile(certbot_path):
|
if not os.path.isfile(certbot_path):
|
||||||
urllib.urlretrieve ("https://dl.eff.org/certbot-auto", certbot_path)
|
urlretrieve ("https://dl.eff.org/certbot-auto", certbot_path)
|
||||||
os.chmod(certbot_path, 0744)
|
os.chmod(certbot_path, 0o744)
|
||||||
|
|
||||||
|
|
||||||
def get_certbot_path():
|
def get_certbot_path():
|
||||||
|
@ -25,7 +25,7 @@ def make_nginx_conf(bench_path, yes=False):
|
|||||||
"error_pages": get_error_pages(),
|
"error_pages": get_error_pages(),
|
||||||
"allow_rate_limiting": allow_rate_limiting,
|
"allow_rate_limiting": allow_rate_limiting,
|
||||||
# for nginx map variable
|
# for nginx map variable
|
||||||
"random_string": "".join(random.choice(string.ascii_lowercase) for i in xrange(7))
|
"random_string": "".join(random.choice(string.ascii_lowercase) for i in range(7))
|
||||||
}
|
}
|
||||||
|
|
||||||
if allow_rate_limiting:
|
if allow_rate_limiting:
|
||||||
@ -159,7 +159,7 @@ def get_sites_with_config(bench_path):
|
|||||||
if dns_multitenant and site_config.get('domains'):
|
if dns_multitenant and site_config.get('domains'):
|
||||||
for domain in site_config.get('domains'):
|
for domain in site_config.get('domains'):
|
||||||
# domain can be a string or a dict with 'domain', 'ssl_certificate', 'ssl_certificate_key'
|
# domain can be a string or a dict with 'domain', 'ssl_certificate', 'ssl_certificate_key'
|
||||||
if isinstance(domain, basestring):
|
if isinstance(domain, str):
|
||||||
domain = { 'domain': domain }
|
domain = { 'domain': domain }
|
||||||
|
|
||||||
domain['name'] = site
|
domain['name'] = site
|
||||||
|
@ -66,7 +66,7 @@ def service(service, option):
|
|||||||
exec_cmd(service_manager_command)
|
exec_cmd(service_manager_command)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise Exception, 'No service manager found'
|
raise Exception('No service manager found')
|
||||||
|
|
||||||
def get_supervisor_confdir():
|
def get_supervisor_confdir():
|
||||||
possiblities = ('/etc/supervisor/conf.d', '/etc/supervisor.d/', '/etc/supervisord/conf.d', '/etc/supervisord.d')
|
possiblities = ('/etc/supervisor/conf.d', '/etc/supervisor.d/', '/etc/supervisord/conf.d', '/etc/supervisord.d')
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
from .common_site_config import get_config
|
from .common_site_config import get_config
|
||||||
import re, os, subprocess, urlparse, semantic_version
|
import re, os, subprocess, semantic_version
|
||||||
import bench
|
import bench
|
||||||
|
|
||||||
|
try:
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
except ImportError:
|
||||||
|
from urlparse import urlparse
|
||||||
|
|
||||||
def generate_config(bench_path):
|
def generate_config(bench_path):
|
||||||
config = get_config(bench_path)
|
config = get_config(bench_path)
|
||||||
|
|
||||||
ports = {}
|
ports = {}
|
||||||
for key in ('redis_cache', 'redis_queue', 'redis_socketio'):
|
for key in ('redis_cache', 'redis_queue', 'redis_socketio'):
|
||||||
ports[key] = urlparse.urlparse(config[key]).port
|
ports[key] = urlparse(config[key]).port
|
||||||
|
|
||||||
write_redis_config(
|
write_redis_config(
|
||||||
template_name='redis_queue.conf',
|
template_name='redis_queue.conf',
|
||||||
|
@ -43,7 +43,7 @@ def add_domain(site, domain, ssl_certificate, ssl_certificate_key, bench_path='.
|
|||||||
domains = get_domains(site, bench_path)
|
domains = get_domains(site, bench_path)
|
||||||
for d in domains:
|
for d in domains:
|
||||||
if (isinstance(d, dict) and d['domain']==domain) or d==domain:
|
if (isinstance(d, dict) and d['domain']==domain) or d==domain:
|
||||||
print "Domain {0} already exists".format(domain)
|
print("Domain {0} already exists".format(domain))
|
||||||
return
|
return
|
||||||
|
|
||||||
if ssl_certificate_key and ssl_certificate:
|
if ssl_certificate_key and ssl_certificate:
|
||||||
@ -75,7 +75,7 @@ def sync_domains(site, domains, bench_path='.'):
|
|||||||
changed = True
|
changed = True
|
||||||
|
|
||||||
else:
|
else:
|
||||||
for d in existing_domains.values():
|
for d in list(existing_domains.values()):
|
||||||
if d != new_domains.get(d['domain']):
|
if d != new_domains.get(d['domain']):
|
||||||
changed = True
|
changed = True
|
||||||
break
|
break
|
||||||
@ -92,7 +92,7 @@ def get_domains(site, bench_path='.'):
|
|||||||
def get_domains_dict(domains):
|
def get_domains_dict(domains):
|
||||||
domains_dict = defaultdict(dict)
|
domains_dict = defaultdict(dict)
|
||||||
for d in domains:
|
for d in domains:
|
||||||
if isinstance(d, basestring):
|
if isinstance(d, str):
|
||||||
domains_dict[d] = { 'domain': d }
|
domains_dict[d] = { 'domain': d }
|
||||||
|
|
||||||
elif isinstance(d, dict):
|
elif isinstance(d, dict):
|
||||||
|
@ -29,7 +29,7 @@ def release(bench_path, app, bump_type, develop='develop', master='master',
|
|||||||
def validate(bench_path):
|
def validate(bench_path):
|
||||||
config = get_config(bench_path)
|
config = get_config(bench_path)
|
||||||
if not config.get('release_bench'):
|
if not config.get('release_bench'):
|
||||||
print 'bench not configured to release'
|
print('bench not configured to release')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
global github_username, github_password
|
global github_username, github_password
|
||||||
@ -38,7 +38,7 @@ def validate(bench_path):
|
|||||||
github_password = config.get('github_password')
|
github_password = config.get('github_password')
|
||||||
|
|
||||||
if not github_username:
|
if not github_username:
|
||||||
github_username = raw_input('Username: ')
|
github_username = input('Username: ')
|
||||||
|
|
||||||
if not github_password:
|
if not github_password:
|
||||||
github_password = getpass.getpass()
|
github_password = getpass.getpass()
|
||||||
@ -54,12 +54,12 @@ def bump(bench_path, app, bump_type, develop, master, remote, owner, repo_name=N
|
|||||||
message = get_release_message(repo_path, develop=develop, master=master, remote=remote)
|
message = get_release_message(repo_path, develop=develop, master=master, remote=remote)
|
||||||
|
|
||||||
if not message:
|
if not message:
|
||||||
print 'No commits to release'
|
print('No commits to release')
|
||||||
return
|
return
|
||||||
|
|
||||||
print
|
print()
|
||||||
print message
|
print(message)
|
||||||
print
|
print()
|
||||||
|
|
||||||
click.confirm('Do you want to continue?', abort=True)
|
click.confirm('Do you want to continue?', abort=True)
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ def bump(bench_path, app, bump_type, develop, master, remote, owner, repo_name=N
|
|||||||
tag_name = create_release(repo_path, new_version, develop=develop, master=master)
|
tag_name = create_release(repo_path, new_version, develop=develop, master=master)
|
||||||
push_release(repo_path, develop=develop, master=master, remote=remote)
|
push_release(repo_path, develop=develop, master=master, remote=remote)
|
||||||
create_github_release(repo_path, tag_name, message, remote=remote, owner=owner, repo_name=repo_name)
|
create_github_release(repo_path, tag_name, message, remote=remote, owner=owner, repo_name=repo_name)
|
||||||
print 'Released {tag} for {repo_path}'.format(tag=tag_name, repo_path=repo_path)
|
print('Released {tag} for {repo_path}'.format(tag=tag_name, repo_path=repo_path))
|
||||||
|
|
||||||
def update_branches_and_check_for_changelog(repo_path, develop='develop', master='master', remote='upstream'):
|
def update_branches_and_check_for_changelog(repo_path, develop='develop', master='master', remote='upstream'):
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ def update_branches_and_check_for_changelog(repo_path, develop='develop', master
|
|||||||
check_for_unmerged_changelog(repo_path)
|
check_for_unmerged_changelog(repo_path)
|
||||||
|
|
||||||
def update_branch(repo_path, branch, remote):
|
def update_branch(repo_path, branch, remote):
|
||||||
print "updating local branch of", repo_path, 'using', remote + '/' + branch
|
print("updating local branch of", repo_path, 'using', remote + '/' + branch)
|
||||||
|
|
||||||
repo = git.Repo(repo_path)
|
repo = git.Repo(repo_path)
|
||||||
g = repo.git
|
g = repo.git
|
||||||
@ -95,7 +95,7 @@ def check_for_unmerged_changelog(repo_path):
|
|||||||
raise Exception("Unmerged change log! in " + repo_path)
|
raise Exception("Unmerged change log! in " + repo_path)
|
||||||
|
|
||||||
def get_release_message(repo_path, develop='develop', master='master', remote='upstream'):
|
def get_release_message(repo_path, develop='develop', master='master', remote='upstream'):
|
||||||
print 'getting release message for', repo_path, 'comparing', master, '...', develop
|
print('getting release message for', repo_path, 'comparing', master, '...', develop)
|
||||||
|
|
||||||
repo = git.Repo(repo_path)
|
repo = git.Repo(repo_path)
|
||||||
g = repo.git
|
g = repo.git
|
||||||
@ -109,7 +109,7 @@ def bump_repo(repo_path, bump_type, develop='develop', master='master'):
|
|||||||
current_version = get_current_version(repo_path)
|
current_version = get_current_version(repo_path)
|
||||||
new_version = get_bumped_version(current_version, bump_type)
|
new_version = get_bumped_version(current_version, bump_type)
|
||||||
|
|
||||||
print 'bumping version from', current_version, 'to', new_version
|
print('bumping version from', current_version, 'to', new_version)
|
||||||
|
|
||||||
set_version(repo_path, new_version)
|
set_version(repo_path, new_version)
|
||||||
return new_version
|
return new_version
|
||||||
@ -154,7 +154,7 @@ def get_bumped_version(version, bump_type):
|
|||||||
else:
|
else:
|
||||||
v.prerelease[1] = str(int(v.prerelease[1]) + 1)
|
v.prerelease[1] = str(int(v.prerelease[1]) + 1)
|
||||||
|
|
||||||
return unicode(v)
|
return str(v)
|
||||||
|
|
||||||
def set_version(repo_path, version):
|
def set_version(repo_path, version):
|
||||||
set_filename_version(os.path.join(repo_path, os.path.basename(repo_path),'__init__.py'), version, '__version__')
|
set_filename_version(os.path.join(repo_path, os.path.basename(repo_path),'__init__.py'), version, '__version__')
|
||||||
@ -192,7 +192,7 @@ def set_filename_version(filename, version_number, pattern):
|
|||||||
f.write(contents)
|
f.write(contents)
|
||||||
|
|
||||||
def commit_changes(repo_path, new_version):
|
def commit_changes(repo_path, new_version):
|
||||||
print 'committing version change to', repo_path
|
print('committing version change to', repo_path)
|
||||||
|
|
||||||
repo = git.Repo(repo_path)
|
repo = git.Repo(repo_path)
|
||||||
app_name = os.path.basename(repo_path)
|
app_name = os.path.basename(repo_path)
|
||||||
@ -200,13 +200,13 @@ def commit_changes(repo_path, new_version):
|
|||||||
repo.index.commit('bumped to version {}'.format(new_version))
|
repo.index.commit('bumped to version {}'.format(new_version))
|
||||||
|
|
||||||
def create_release(repo_path, new_version, develop='develop', master='master'):
|
def create_release(repo_path, new_version, develop='develop', master='master'):
|
||||||
print 'creating release for version', new_version
|
print('creating release for version', new_version)
|
||||||
repo = git.Repo(repo_path)
|
repo = git.Repo(repo_path)
|
||||||
g = repo.git
|
g = repo.git
|
||||||
g.checkout(master)
|
g.checkout(master)
|
||||||
try:
|
try:
|
||||||
g.merge(develop, '--no-ff')
|
g.merge(develop, '--no-ff')
|
||||||
except git.exc.GitCommandError, e:
|
except git.exc.GitCommandError as e:
|
||||||
handle_merge_error(e, source=develop, target=master)
|
handle_merge_error(e, source=develop, target=master)
|
||||||
|
|
||||||
tag_name = 'v' + new_version
|
tag_name = 'v' + new_version
|
||||||
@ -215,29 +215,29 @@ def create_release(repo_path, new_version, develop='develop', master='master'):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
g.merge(master)
|
g.merge(master)
|
||||||
except git.exc.GitCommandError, e:
|
except git.exc.GitCommandError as e:
|
||||||
handle_merge_error(e, source=master, target=develop)
|
handle_merge_error(e, source=master, target=develop)
|
||||||
|
|
||||||
if develop != 'develop':
|
if develop != 'develop':
|
||||||
print 'merging master into develop'
|
print('merging master into develop')
|
||||||
g.checkout('develop')
|
g.checkout('develop')
|
||||||
try:
|
try:
|
||||||
g.merge(master)
|
g.merge(master)
|
||||||
except git.exc.GitCommandError, e:
|
except git.exc.GitCommandError as e:
|
||||||
handle_merge_error(e, source=master, target='develop')
|
handle_merge_error(e, source=master, target='develop')
|
||||||
|
|
||||||
return tag_name
|
return tag_name
|
||||||
|
|
||||||
def handle_merge_error(e, source, target):
|
def handle_merge_error(e, source, target):
|
||||||
print '-'*80
|
print('-'*80)
|
||||||
print 'Error when merging {source} into {target}'.format(source=source, target=target)
|
print('Error when merging {source} into {target}'.format(source=source, target=target))
|
||||||
print e
|
print(e)
|
||||||
print 'You can open a new terminal, try to manually resolve the conflict/error and continue'
|
print('You can open a new terminal, try to manually resolve the conflict/error and continue')
|
||||||
print '-'*80
|
print('-'*80)
|
||||||
click.confirm('Have you manually resolved the error?', abort=True)
|
click.confirm('Have you manually resolved the error?', abort=True)
|
||||||
|
|
||||||
def push_release(repo_path, develop='develop', master='master', remote='upstream'):
|
def push_release(repo_path, develop='develop', master='master', remote='upstream'):
|
||||||
print 'pushing branches', master, develop, 'of', repo_path
|
print('pushing branches', master, develop, 'of', repo_path)
|
||||||
repo = git.Repo(repo_path)
|
repo = git.Repo(repo_path)
|
||||||
g = repo.git
|
g = repo.git
|
||||||
args = [
|
args = [
|
||||||
@ -246,22 +246,22 @@ def push_release(repo_path, develop='develop', master='master', remote='upstream
|
|||||||
]
|
]
|
||||||
|
|
||||||
if develop != 'develop':
|
if develop != 'develop':
|
||||||
print 'pushing develop branch of', repo_path
|
print('pushing develop branch of', repo_path)
|
||||||
args.append('develop:develop')
|
args.append('develop:develop')
|
||||||
|
|
||||||
args.append('--tags')
|
args.append('--tags')
|
||||||
|
|
||||||
print g.push(remote, *args)
|
print(g.push(remote, *args))
|
||||||
|
|
||||||
def create_github_release(repo_path, tag_name, message, remote='upstream', owner='frappe', repo_name=None,
|
def create_github_release(repo_path, tag_name, message, remote='upstream', owner='frappe', repo_name=None,
|
||||||
gh_username=None, gh_password=None):
|
gh_username=None, gh_password=None):
|
||||||
|
|
||||||
print 'creating release on github'
|
print('creating release on github')
|
||||||
|
|
||||||
global github_username, github_password
|
global github_username, github_password
|
||||||
if not (gh_username and gh_password):
|
if not (gh_username and gh_password):
|
||||||
if not (github_username and github_password):
|
if not (github_username and github_password):
|
||||||
raise Exception, "No credentials"
|
raise Exception("No credentials")
|
||||||
gh_username = github_username
|
gh_username = github_username
|
||||||
gh_password = github_password
|
gh_password = github_password
|
||||||
|
|
||||||
@ -274,7 +274,7 @@ def create_github_release(repo_path, tag_name, message, remote='upstream', owner
|
|||||||
'draft': False,
|
'draft': False,
|
||||||
'prerelease': False
|
'prerelease': False
|
||||||
}
|
}
|
||||||
for i in xrange(3):
|
for i in range(3):
|
||||||
try:
|
try:
|
||||||
r = requests.post('https://api.github.com/repos/{owner}/{repo_name}/releases'.format(
|
r = requests.post('https://api.github.com/repos/{owner}/{repo_name}/releases'.format(
|
||||||
owner=owner, repo_name=repo_name),
|
owner=owner, repo_name=repo_name),
|
||||||
@ -282,12 +282,12 @@ def create_github_release(repo_path, tag_name, message, remote='upstream', owner
|
|||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
break
|
break
|
||||||
except requests.exceptions.HTTPError:
|
except requests.exceptions.HTTPError:
|
||||||
print 'request failed, retrying....'
|
print('request failed, retrying....')
|
||||||
sleep(3*i + 1)
|
sleep(3*i + 1)
|
||||||
if i !=2:
|
if i !=2:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
print r.json()
|
print(r.json())
|
||||||
raise
|
raise
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
import unittest
|
import unittest
|
||||||
import json, os, shutil, subprocess
|
import json, os, shutil, subprocess
|
||||||
import bench
|
import bench
|
||||||
@ -178,7 +178,7 @@ class TestBenchInit(unittest.TestCase):
|
|||||||
try:
|
try:
|
||||||
subprocess.check_output(drop_site_cmd, cwd=bench_path)
|
subprocess.check_output(drop_site_cmd, cwd=bench_path)
|
||||||
except subprocess.CalledProcessError as err:
|
except subprocess.CalledProcessError as err:
|
||||||
print err.output
|
print(err.output)
|
||||||
|
|
||||||
if not archived_sites_path:
|
if not archived_sites_path:
|
||||||
archived_sites_path = os.path.join(bench_path, 'archived_sites')
|
archived_sites_path = os.path.join(bench_path, 'archived_sites')
|
||||||
@ -234,8 +234,8 @@ class TestBenchInit(unittest.TestCase):
|
|||||||
|
|
||||||
config = self.load_json(common_site_config_path)
|
config = self.load_json(common_site_config_path)
|
||||||
|
|
||||||
for key, value in expected_config.items():
|
for key, value in list(expected_config.items()):
|
||||||
self.assertEquals(config.get(key), value)
|
self.assertEqual(config.get(key), value)
|
||||||
|
|
||||||
def assert_exists(self, *args):
|
def assert_exists(self, *args):
|
||||||
self.assertTrue(os.path.exists(os.path.join(*args)))
|
self.assertTrue(os.path.exists(os.path.join(*args)))
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
from bench.tests import test_init
|
from bench.tests import test_init
|
||||||
from bench.config.production_setup import setup_production, get_supervisor_confdir, disable_production
|
from bench.config.production_setup import setup_production, get_supervisor_confdir, disable_production
|
||||||
import bench.utils
|
import bench.utils
|
||||||
@ -36,23 +36,6 @@ class TestSetupProduction(test_init.TestBenchInit):
|
|||||||
bench_path = os.path.join(os.path.abspath(self.benches_path), bench_name)
|
bench_path = os.path.join(os.path.abspath(self.benches_path), bench_name)
|
||||||
disable_production(bench_path)
|
disable_production(bench_path)
|
||||||
|
|
||||||
def test_setup_production_v6(self):
|
|
||||||
bench_name = 'test-bench-v6'
|
|
||||||
self.test_init(bench_name, frappe_branch='v6.x.x')
|
|
||||||
|
|
||||||
user = getpass.getuser()
|
|
||||||
|
|
||||||
bench_path = os.path.join(os.path.abspath(self.benches_path), bench_name)
|
|
||||||
setup_production(user, bench_path)
|
|
||||||
|
|
||||||
self.assert_nginx_config(bench_name)
|
|
||||||
self.assert_nginx_process()
|
|
||||||
|
|
||||||
self.assert_supervisor_config(bench_name, use_rq=False)
|
|
||||||
self.assert_supervisor_process(bench_name, use_rq=False)
|
|
||||||
|
|
||||||
disable_production(bench_path)
|
|
||||||
|
|
||||||
def test_disable_production(self):
|
def test_disable_production(self):
|
||||||
bench_name = 'test-disable-prod'
|
bench_name = 'test-disable-prod'
|
||||||
self.test_init(bench_name, frappe_branch='master')
|
self.test_init(bench_name, frappe_branch='master')
|
||||||
@ -76,7 +59,7 @@ class TestSetupProduction(test_init.TestBenchInit):
|
|||||||
self.assertTrue(os.path.exists(conf_dest))
|
self.assertTrue(os.path.exists(conf_dest))
|
||||||
|
|
||||||
# symlink matches
|
# symlink matches
|
||||||
self.assertEquals(os.path.realpath(conf_dest), conf_src)
|
self.assertEqual(os.path.realpath(conf_dest), conf_src)
|
||||||
|
|
||||||
# file content
|
# file content
|
||||||
with open(conf_src, "r") as f:
|
with open(conf_src, "r") as f:
|
||||||
@ -113,7 +96,7 @@ class TestSetupProduction(test_init.TestBenchInit):
|
|||||||
self.assertTrue(os.path.exists(conf_dest))
|
self.assertTrue(os.path.exists(conf_dest))
|
||||||
|
|
||||||
# symlink matches
|
# symlink matches
|
||||||
self.assertEquals(os.path.realpath(conf_dest), conf_src)
|
self.assertEqual(os.path.realpath(conf_dest), conf_src)
|
||||||
|
|
||||||
# file content
|
# file content
|
||||||
with open(conf_src, "r") as f:
|
with open(conf_src, "r") as f:
|
||||||
|
@ -16,8 +16,8 @@ folders_in_bench = ('apps', 'sites', 'config', 'logs', 'config/pids')
|
|||||||
def get_frappe(bench_path='.'):
|
def get_frappe(bench_path='.'):
|
||||||
frappe = get_env_cmd('frappe', bench_path=bench_path)
|
frappe = get_env_cmd('frappe', bench_path=bench_path)
|
||||||
if not os.path.exists(frappe):
|
if not os.path.exists(frappe):
|
||||||
print 'frappe app is not installed. Run the following command to install frappe'
|
print('frappe app is not installed. Run the following command to install frappe')
|
||||||
print 'bench get-app https://github.com/frappe/frappe.git'
|
print('bench get-app https://github.com/frappe/frappe.git')
|
||||||
return frappe
|
return frappe
|
||||||
|
|
||||||
def get_env_cmd(cmd, bench_path='.'):
|
def get_env_cmd(cmd, bench_path='.'):
|
||||||
@ -33,7 +33,7 @@ def init(path, apps_path=None, no_procfile=False, no_backups=False,
|
|||||||
from bench.patches import set_all_patches_executed
|
from bench.patches import set_all_patches_executed
|
||||||
|
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
print 'Directory {} already exists!'.format(path)
|
print('Directory {} already exists!'.format(path))
|
||||||
raise Exception("Site directory already exists")
|
raise Exception("Site directory already exists")
|
||||||
# sys.exit(1)
|
# sys.exit(1)
|
||||||
|
|
||||||
@ -76,17 +76,17 @@ def init(path, apps_path=None, no_procfile=False, no_backups=False,
|
|||||||
|
|
||||||
def clone_apps_from(bench_path, clone_from):
|
def clone_apps_from(bench_path, clone_from):
|
||||||
from .app import install_app
|
from .app import install_app
|
||||||
print 'Copying apps from {0}...'.format(clone_from)
|
print('Copying apps from {0}...'.format(clone_from))
|
||||||
subprocess.check_output(['cp', '-R', os.path.join(clone_from, 'apps'), bench_path])
|
subprocess.check_output(['cp', '-R', os.path.join(clone_from, 'apps'), bench_path])
|
||||||
|
|
||||||
print 'Copying node_modules from {0}...'.format(clone_from)
|
print('Copying node_modules from {0}...'.format(clone_from))
|
||||||
subprocess.check_output(['cp', '-R', os.path.join(clone_from, 'node_modules'), bench_path])
|
subprocess.check_output(['cp', '-R', os.path.join(clone_from, 'node_modules'), bench_path])
|
||||||
|
|
||||||
def setup_app(app):
|
def setup_app(app):
|
||||||
# run git reset --hard in each branch, pull latest updates and install_app
|
# run git reset --hard in each branch, pull latest updates and install_app
|
||||||
app_path = os.path.join(bench_path, 'apps', app)
|
app_path = os.path.join(bench_path, 'apps', app)
|
||||||
if os.path.exists(os.path.join(app_path, '.git')):
|
if os.path.exists(os.path.join(app_path, '.git')):
|
||||||
print 'Cleaning up {0}'.format(app)
|
print('Cleaning up {0}'.format(app))
|
||||||
|
|
||||||
# remove .egg-ino
|
# remove .egg-ino
|
||||||
subprocess.check_output(['rm', '-rf', app + '.egg-info'], cwd=app_path)
|
subprocess.check_output(['rm', '-rf', app + '.egg-info'], cwd=app_path)
|
||||||
@ -240,7 +240,7 @@ def setup_sudoers(user):
|
|||||||
f.write('\n#includedir /etc/sudoers.d\n')
|
f.write('\n#includedir /etc/sudoers.d\n')
|
||||||
|
|
||||||
if set_permissions:
|
if set_permissions:
|
||||||
os.chmod('/etc/sudoers', 0440)
|
os.chmod('/etc/sudoers', 0o440)
|
||||||
|
|
||||||
sudoers_file = '/etc/sudoers.d/frappe'
|
sudoers_file = '/etc/sudoers.d/frappe'
|
||||||
|
|
||||||
@ -257,7 +257,7 @@ def setup_sudoers(user):
|
|||||||
with open(sudoers_file, 'w') as f:
|
with open(sudoers_file, 'w') as f:
|
||||||
f.write(frappe_sudoers.encode('utf-8'))
|
f.write(frappe_sudoers.encode('utf-8'))
|
||||||
|
|
||||||
os.chmod(sudoers_file, 0440)
|
os.chmod(sudoers_file, 0o440)
|
||||||
|
|
||||||
def setup_logging(bench_path='.'):
|
def setup_logging(bench_path='.'):
|
||||||
if os.path.exists(os.path.join(bench_path, 'logs')):
|
if os.path.exists(os.path.join(bench_path, 'logs')):
|
||||||
@ -326,9 +326,9 @@ def check_git_for_shallow_clone():
|
|||||||
def get_cmd_output(cmd, cwd='.'):
|
def get_cmd_output(cmd, cwd='.'):
|
||||||
try:
|
try:
|
||||||
return subprocess.check_output(cmd, cwd=cwd, shell=True, stderr=open(os.devnull, 'wb')).strip()
|
return subprocess.check_output(cmd, cwd=cwd, shell=True, stderr=open(os.devnull, 'wb')).strip()
|
||||||
except subprocess.CalledProcessError, e:
|
except subprocess.CalledProcessError as e:
|
||||||
if e.output:
|
if e.output:
|
||||||
print e.output
|
print(e.output)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def restart_supervisor_processes(bench_path='.', web_workers=False):
|
def restart_supervisor_processes(bench_path='.', web_workers=False):
|
||||||
@ -439,7 +439,7 @@ def drop_privileges(uid_name='nobody', gid_name='nogroup'):
|
|||||||
os.setuid(running_uid)
|
os.setuid(running_uid)
|
||||||
|
|
||||||
# Ensure a very conservative umask
|
# Ensure a very conservative umask
|
||||||
os.umask(022)
|
os.umask(0o22)
|
||||||
|
|
||||||
def fix_prod_setup_perms(bench_path='.', frappe_user=None):
|
def fix_prod_setup_perms(bench_path='.', frappe_user=None):
|
||||||
from .config.common_site_config import get_config
|
from .config.common_site_config import get_config
|
||||||
@ -458,7 +458,7 @@ def fix_prod_setup_perms(bench_path='.', frappe_user=None):
|
|||||||
frappe_user = get_config(bench_path).get('frappe_user')
|
frappe_user = get_config(bench_path).get('frappe_user')
|
||||||
|
|
||||||
if not frappe_user:
|
if not frappe_user:
|
||||||
print "frappe user not set"
|
print("frappe user not set")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
for path in files:
|
for path in files:
|
||||||
@ -470,14 +470,14 @@ def fix_prod_setup_perms(bench_path='.', frappe_user=None):
|
|||||||
def fix_file_perms():
|
def fix_file_perms():
|
||||||
for dir_path, dirs, files in os.walk('.'):
|
for dir_path, dirs, files in os.walk('.'):
|
||||||
for _dir in dirs:
|
for _dir in dirs:
|
||||||
os.chmod(os.path.join(dir_path, _dir), 0755)
|
os.chmod(os.path.join(dir_path, _dir), 0o755)
|
||||||
for _file in files:
|
for _file in files:
|
||||||
os.chmod(os.path.join(dir_path, _file), 0644)
|
os.chmod(os.path.join(dir_path, _file), 0o644)
|
||||||
bin_dir = './env/bin'
|
bin_dir = './env/bin'
|
||||||
if os.path.exists(bin_dir):
|
if os.path.exists(bin_dir):
|
||||||
for _file in os.listdir(bin_dir):
|
for _file in os.listdir(bin_dir):
|
||||||
if not _file.startswith('activate'):
|
if not _file.startswith('activate'):
|
||||||
os.chmod(os.path.join(bin_dir, _file), 0755)
|
os.chmod(os.path.join(bin_dir, _file), 0o755)
|
||||||
|
|
||||||
def get_current_frappe_version(bench_path='.'):
|
def get_current_frappe_version(bench_path='.'):
|
||||||
from .app import get_current_frappe_version as fv
|
from .app import get_current_frappe_version as fv
|
||||||
@ -539,8 +539,8 @@ def post_upgrade(from_ver, to_ver, bench_path='.'):
|
|||||||
from .config.supervisor import generate_supervisor_config
|
from .config.supervisor import generate_supervisor_config
|
||||||
from .config.nginx import make_nginx_conf
|
from .config.nginx import make_nginx_conf
|
||||||
conf = get_config(bench_path=bench_path)
|
conf = get_config(bench_path=bench_path)
|
||||||
print "-"*80
|
print("-"*80)
|
||||||
print "Your bench was upgraded to version {0}".format(to_ver)
|
print("Your bench was upgraded to version {0}".format(to_ver))
|
||||||
|
|
||||||
if conf.get('restart_supervisor_on_update'):
|
if conf.get('restart_supervisor_on_update'):
|
||||||
redis.generate_config(bench_path=bench_path)
|
redis.generate_config(bench_path=bench_path)
|
||||||
@ -553,17 +553,17 @@ def post_upgrade(from_ver, to_ver, bench_path='.'):
|
|||||||
if from_ver <= 5 and to_ver == 6:
|
if from_ver <= 5 and to_ver == 6:
|
||||||
setup_socketio(bench_path=bench_path)
|
setup_socketio(bench_path=bench_path)
|
||||||
|
|
||||||
print "As you have setup your bench for production, you will have to reload configuration for nginx and supervisor"
|
print("As you have setup your bench for production, you will have to reload configuration for nginx and supervisor")
|
||||||
print "To complete the migration, please run the following commands"
|
print("To complete the migration, please run the following commands")
|
||||||
print
|
print()
|
||||||
print "sudo service nginx restart"
|
print("sudo service nginx restart")
|
||||||
print "sudo supervisorctl reload"
|
print("sudo supervisorctl reload")
|
||||||
|
|
||||||
def update_translations_p(args):
|
def update_translations_p(args):
|
||||||
try:
|
try:
|
||||||
update_translations(*args)
|
update_translations(*args)
|
||||||
except requests.exceptions.HTTPError:
|
except requests.exceptions.HTTPError:
|
||||||
print 'Download failed for', args[0], args[1]
|
print('Download failed for', args[0], args[1])
|
||||||
|
|
||||||
def download_translations_p():
|
def download_translations_p():
|
||||||
pool = multiprocessing.Pool(4)
|
pool = multiprocessing.Pool(4)
|
||||||
@ -600,7 +600,7 @@ def update_translations(app, lang):
|
|||||||
f.write(chunk)
|
f.write(chunk)
|
||||||
f.flush()
|
f.flush()
|
||||||
|
|
||||||
print 'downloaded for', app, lang
|
print('downloaded for', app, lang)
|
||||||
|
|
||||||
def print_output(p):
|
def print_output(p):
|
||||||
while p.poll() is None:
|
while p.poll() is None:
|
||||||
@ -650,18 +650,18 @@ def validate_pillow_dependencies(bench_path, requirements):
|
|||||||
distro = platform.linux_distribution()
|
distro = platform.linux_distribution()
|
||||||
distro_name = distro[0].lower()
|
distro_name = distro[0].lower()
|
||||||
if "centos" in distro_name or "fedora" in distro_name:
|
if "centos" in distro_name or "fedora" in distro_name:
|
||||||
print "Please install these dependencies using the command:"
|
print("Please install these dependencies using the command:")
|
||||||
print "sudo yum install libtiff-devel libjpeg-devel libzip-devel freetype-devel lcms2-devel libwebp-devel tcl-devel tk-devel"
|
print("sudo yum install libtiff-devel libjpeg-devel libzip-devel freetype-devel lcms2-devel libwebp-devel tcl-devel tk-devel")
|
||||||
|
|
||||||
raise
|
raise
|
||||||
|
|
||||||
elif "ubuntu" in distro_name or "elementary os" in distro_name or "debian" in distro_name:
|
elif "ubuntu" in distro_name or "elementary os" in distro_name or "debian" in distro_name:
|
||||||
print "Please install these dependencies using the command:"
|
print("Please install these dependencies using the command:")
|
||||||
|
|
||||||
if "ubuntu" in distro_name and distro[1]=="12.04":
|
if "ubuntu" in distro_name and distro[1]=="12.04":
|
||||||
print "sudo apt-get install -y libtiff4-dev libjpeg8-dev zlib1g-dev libfreetype6-dev liblcms2-dev libwebp-dev tcl8.5-dev tk8.5-dev python-tk"
|
print("sudo apt-get install -y libtiff4-dev libjpeg8-dev zlib1g-dev libfreetype6-dev liblcms2-dev libwebp-dev tcl8.5-dev tk8.5-dev python-tk")
|
||||||
else:
|
else:
|
||||||
print "sudo apt-get install -y libtiff5-dev libjpeg8-dev zlib1g-dev libfreetype6-dev liblcms2-dev libwebp-dev tcl8.6-dev tk8.6-dev python-tk"
|
print("sudo apt-get install -y libtiff5-dev libjpeg8-dev zlib1g-dev libfreetype6-dev liblcms2-dev libwebp-dev tcl8.6-dev tk8.6-dev python-tk")
|
||||||
|
|
||||||
raise
|
raise
|
||||||
|
|
||||||
@ -687,7 +687,7 @@ def set_git_remote_url(git_url, bench_path='.'):
|
|||||||
app = git_url.rsplit('/', 1)[1].rsplit('.', 1)[0]
|
app = git_url.rsplit('/', 1)[1].rsplit('.', 1)[0]
|
||||||
|
|
||||||
if app not in bench.app.get_apps(bench_path):
|
if app not in bench.app.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_dir = bench.app.get_repo_dir(app, bench_path=bench_path)
|
app_dir = bench.app.get_repo_dir(app, bench_path=bench_path)
|
||||||
@ -696,7 +696,7 @@ def set_git_remote_url(git_url, bench_path='.'):
|
|||||||
|
|
||||||
def run_playbook(playbook_name, extra_vars=None):
|
def run_playbook(playbook_name, extra_vars=None):
|
||||||
if not find_executable('ansible'):
|
if not find_executable('ansible'):
|
||||||
print "Ansible is needed to run this command, please install it using 'pip install ansible'"
|
print("Ansible is needed to run this command, please install it using 'pip install ansible'")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
args = ['ansible-playbook', '-c', 'local', playbook_name]
|
args = ['ansible-playbook', '-c', 'local', playbook_name]
|
||||||
if extra_vars:
|
if extra_vars:
|
||||||
|
@ -30,7 +30,7 @@ def install_bench(args):
|
|||||||
})
|
})
|
||||||
|
|
||||||
if not success:
|
if not success:
|
||||||
print 'Could not install pre-requisites. Please check for errors or install them manually.'
|
print('Could not install pre-requisites. Please check for errors or install them manually.')
|
||||||
return
|
return
|
||||||
|
|
||||||
# secure pip installation
|
# secure pip installation
|
||||||
@ -75,7 +75,7 @@ def install_bench(args):
|
|||||||
if args.production:
|
if args.production:
|
||||||
args.user = 'frappe'
|
args.user = 'frappe'
|
||||||
|
|
||||||
elif os.environ.has_key('SUDO_USER'):
|
elif 'SUDO_USER' in os.environ:
|
||||||
args.user = os.environ['SUDO_USER']
|
args.user = os.environ['SUDO_USER']
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@ -122,9 +122,9 @@ def check_distribution_compatibility():
|
|||||||
if float(dist_version) in supported_dists[dist_name]:
|
if float(dist_version) in supported_dists[dist_name]:
|
||||||
return
|
return
|
||||||
|
|
||||||
print "Sorry, the installer doesn't support {0} {1}. Aborting installation!".format(dist_name, dist_version)
|
print("Sorry, the installer doesn't support {0} {1}. Aborting installation!".format(dist_name, dist_version))
|
||||||
if dist_name in supported_dists:
|
if dist_name in supported_dists:
|
||||||
print "Install on {0} {1} instead".format(dist_name, supported_dists[dist_name][-1])
|
print("Install on {0} {1} instead".format(dist_name, supported_dists[dist_name][-1]))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
def get_distribution_info():
|
def get_distribution_info():
|
||||||
@ -142,7 +142,7 @@ def install_python27():
|
|||||||
if version == (2, 7):
|
if version == (2, 7):
|
||||||
return
|
return
|
||||||
|
|
||||||
print 'Installing Python 2.7'
|
print('Installing Python 2.7')
|
||||||
|
|
||||||
# install python 2.7
|
# install python 2.7
|
||||||
success = run_os_command({
|
success = run_os_command({
|
||||||
@ -210,9 +210,9 @@ def clone_bench_repo(args):
|
|||||||
def run_os_command(command_map):
|
def run_os_command(command_map):
|
||||||
'''command_map is a dictionary of {'executable': command}. For ex. {'apt-get': 'sudo apt-get install -y python2.7'} '''
|
'''command_map is a dictionary of {'executable': command}. For ex. {'apt-get': 'sudo apt-get install -y python2.7'} '''
|
||||||
success = True
|
success = True
|
||||||
for executable, commands in command_map.items():
|
for executable, commands in list(command_map.items()):
|
||||||
if find_executable(executable):
|
if find_executable(executable):
|
||||||
if isinstance(commands, basestring):
|
if isinstance(commands, str):
|
||||||
commands = [commands]
|
commands = [commands]
|
||||||
|
|
||||||
for command in commands:
|
for command in commands:
|
||||||
@ -266,7 +266,7 @@ def get_passwords(ignore_prompt=False):
|
|||||||
with open(passwords_file_path, 'w') as f:
|
with open(passwords_file_path, 'w') as f:
|
||||||
json.dump(passwords, f, indent=1)
|
json.dump(passwords, f, indent=1)
|
||||||
|
|
||||||
print 'Passwords saved at ~/passwords.txt'
|
print('Passwords saved at ~/passwords.txt')
|
||||||
|
|
||||||
return passwords
|
return passwords
|
||||||
|
|
||||||
@ -274,7 +274,7 @@ def get_extra_vars_json(extra_args):
|
|||||||
# We need to pass production as extra_vars to the playbook to execute conditionals in the
|
# We need to pass production as extra_vars to the playbook to execute conditionals in the
|
||||||
# playbook. Extra variables can passed as json or key=value pair. Here, we will use JSON.
|
# playbook. Extra variables can passed as json or key=value pair. Here, we will use JSON.
|
||||||
json_path = os.path.join('/tmp', 'extra_vars.json')
|
json_path = os.path.join('/tmp', 'extra_vars.json')
|
||||||
extra_vars = dict(extra_args.items())
|
extra_vars = dict(list(extra_args.items()))
|
||||||
with open(json_path, mode='w') as j:
|
with open(json_path, mode='w') as j:
|
||||||
json.dump(extra_vars, j, indent=1, sort_keys=True)
|
json.dump(extra_vars, j, indent=1, sort_keys=True)
|
||||||
|
|
||||||
@ -350,4 +350,4 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
install_bench(args)
|
install_bench(args)
|
||||||
|
|
||||||
print '''Frappe/ERPNext has been successfully installed!'''
|
print('''Frappe/ERPNext has been successfully installed!''')
|
||||||
|
Loading…
Reference in New Issue
Block a user