2
0
mirror of https://github.com/frappe/bench.git synced 2024-11-12 08:16:28 +00:00

Merge pull request #1170 from gavindsouza/f-strings

chore: Drop support for < Py3.6
This commit is contained in:
gavin 2021-05-13 14:00:50 +05:30 committed by GitHub
commit 656eeca343
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 226 additions and 330 deletions

View File

@ -1,32 +0,0 @@
version: 2
jobs:
build:
machine: true
working_directory: ~/repo
steps:
- checkout
- run:
name: Setup
command: |
sudo pip install --ignore-installed setuptools
sudo pip install urllib3 pyOpenSSL ndg-httpsclient pyasn1
sudo cp -r ~/.ssh/* /root/.ssh
mkdir -p ~/.bench
mkdir -p /tmp/.bench
cp -r ~/repo/* ~/.bench
cp -r ~/repo/* /tmp/.bench
- run:
name: Install Bench (Production)
command: sudo python ~/repo/playbooks/install.py --user travis --run-travis --production
- run:
name: Setup Tests
command: |
cd ~
sudo pip install --upgrade pip
sudo pip install -e ~/.bench
- run:
name: Run Tests
command: sudo -E python -m unittest -v bench.tests.test_setup_production

View File

@ -1,6 +1,3 @@
# imports - compatibility imports
from __future__ import print_function
# imports - standard imports # imports - standard imports
import json import json
import logging import logging
@ -69,7 +66,7 @@ def add_to_excluded_apps_txt(app, bench_path='.'):
if app == 'frappe': if app == 'frappe':
raise ValueError('Frappe app cannot be excludeed from update') raise ValueError('Frappe app cannot be excludeed from update')
if app not in os.listdir('apps'): if app not in os.listdir('apps'):
raise ValueError('The app {} does not exist'.format(app)) raise ValueError(f'The app {app} does not exist')
apps = get_excluded_apps(bench_path=bench_path) apps = get_excluded_apps(bench_path=bench_path)
if app not in apps: if app not in apps:
apps.append(app) apps.append(app)
@ -93,45 +90,42 @@ def get_app(git_url, branch=None, bench_path='.', skip_assets=False, verbose=Fal
if not is_git_url(git_url): if not is_git_url(git_url):
orgs = ['frappe', 'erpnext'] orgs = ['frappe', 'erpnext']
for org in orgs: for org in orgs:
url = 'https://api.github.com/repos/{org}/{app}'.format(org=org, app=git_url) url = f'https://api.github.com/repos/{org}/{git_url}'
res = requests.get(url) res = requests.get(url)
if res.ok: if res.ok:
data = res.json() data = res.json()
if 'name' in data: if 'name' in data:
if git_url == data['name']: if git_url == data['name']:
git_url = 'https://github.com/{org}/{app}'.format(org=org, app=git_url) git_url = f'https://github.com/{org}/{git_url}'
break break
else: else:
bench.utils.log("App {app} not found".format(app=git_url), level=2) bench.utils.log(f"App {git_url} not found", level=2)
sys.exit(1) sys.exit(1)
# Gets repo name from URL # Gets repo name from URL
repo_name = git_url.rstrip('/').rsplit('/', 1)[1].rsplit('.', 1)[0] repo_name = git_url.rstrip('/').rsplit('/', 1)[1].rsplit('.', 1)[0]
shallow_clone = '--depth 1' if check_git_for_shallow_clone() else '' shallow_clone = '--depth 1' if check_git_for_shallow_clone() else ''
branch = '--branch {branch}'.format(branch=branch) if branch else '' branch = f'--branch {branch}' if branch else ''
else: else:
git_url = os.path.abspath(git_url) git_url = os.path.abspath(git_url)
_, repo_name = os.path.split(git_url) _, repo_name = os.path.split(git_url)
shallow_clone = '' shallow_clone = ''
branch = '--branch {branch}'.format(branch=branch) if branch else '' branch = f'--branch {branch}' if branch else ''
if os.path.isdir(os.path.join(bench_path, 'apps', repo_name)): if os.path.isdir(os.path.join(bench_path, 'apps', repo_name)):
# application directory already exists # application directory already exists
# prompt user to overwrite it # prompt user to overwrite it
if overwrite or click.confirm('''A directory for the application "{0}" already exists. if overwrite or click.confirm(f'''A directory for the application "{repo_name}" already exists.
Do you want to continue and overwrite it?'''.format(repo_name)): Do you want to continue and overwrite it?'''):
shutil.rmtree(os.path.join(bench_path, 'apps', repo_name)) shutil.rmtree(os.path.join(bench_path, 'apps', repo_name))
elif click.confirm('''Do you want to reinstall the existing application?''', abort=True): elif click.confirm('''Do you want to reinstall the existing application?''', abort=True):
app_name = get_app_name(bench_path, repo_name) app_name = get_app_name(bench_path, repo_name)
install_app(app=app_name, bench_path=bench_path, verbose=verbose, skip_assets=skip_assets) install_app(app=app_name, bench_path=bench_path, verbose=verbose, skip_assets=skip_assets)
sys.exit() sys.exit()
print('\n{0}Getting {1}{2}'.format(color.yellow, repo_name, color.nc)) print(f'\n{color.yellow}Getting {repo_name}{color.nc}')
logger.log('Getting app {0}'.format(repo_name)) logger.log(f'Getting app {repo_name}')
exec_cmd("git clone {git_url} {branch} {shallow_clone} --origin upstream".format( exec_cmd(f"git clone {git_url} {branch} {shallow_clone} --origin upstream",
git_url=git_url,
shallow_clone=shallow_clone,
branch=branch),
cwd=os.path.join(bench_path, 'apps')) cwd=os.path.join(bench_path, 'apps'))
app_name = get_app_name(bench_path, repo_name) app_name = get_app_name(bench_path, repo_name)
@ -162,7 +156,7 @@ def get_app_name(bench_path, repo_name):
def new_app(app, bench_path='.'): def new_app(app, bench_path='.'):
# For backwards compatibility # For backwards compatibility
app = app.lower().replace(" ", "_").replace("-", "_") app = app.lower().replace(" ", "_").replace("-", "_")
logger.log('creating new app {}'.format(app)) logger.log(f'creating new app {app}')
apps = os.path.abspath(os.path.join(bench_path, 'apps')) apps = os.path.abspath(os.path.join(bench_path, 'apps'))
run_frappe_cmd('make-app', apps, app, bench_path=bench_path) run_frappe_cmd('make-app', apps, app, bench_path=bench_path)
install_app(app, bench_path=bench_path) install_app(app, bench_path=bench_path)
@ -171,15 +165,15 @@ def new_app(app, bench_path='.'):
def install_app(app, bench_path=".", verbose=False, no_cache=False, restart_bench=True, skip_assets=False): def install_app(app, bench_path=".", verbose=False, no_cache=False, restart_bench=True, skip_assets=False):
from bench.config.common_site_config import get_config from bench.config.common_site_config import get_config
print('\n{0}Installing {1}{2}'.format(color.yellow, app, color.nc)) print(f'\n{color.yellow}Installing {app}{color.nc}')
logger.log("installing {}".format(app)) logger.log(f"installing {app}")
python_path = os.path.join(bench_path, "env", "bin", "python") python_path = os.path.join(bench_path, "env", "bin", "python")
quiet_flag = "-q" if not verbose else "" quiet_flag = "-q" if not verbose else ""
app_path = os.path.join(bench_path, "apps", app) app_path = os.path.join(bench_path, "apps", app)
cache_flag = "--no-cache-dir" if no_cache else "" cache_flag = "--no-cache-dir" if no_cache else ""
exec_cmd("{py_path} -m pip install {quiet} -U -e {app} {no_cache}".format(py_path=python_path, quiet=quiet_flag, app=app_path, no_cache=cache_flag)) exec_cmd(f"{python_path} -m pip install {quiet_flag} -U -e {app_path} {cache_flag}")
if os.path.exists(os.path.join(app_path, 'package.json')): if os.path.exists(os.path.join(app_path, 'package.json')):
exec_cmd("yarn install", cwd=app_path) exec_cmd("yarn install", cwd=app_path)
@ -203,7 +197,7 @@ def remove_app(app, bench_path='.'):
from bench.config.common_site_config import get_config from bench.config.common_site_config import get_config
if app not in get_apps(bench_path): if app not in get_apps(bench_path):
print("No app named {0}".format(app)) print(f"No app named {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)
@ -215,10 +209,10 @@ 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).decode('utf-8') out = subprocess.check_output(["bench", "--site", site, "list-apps"], cwd=bench_path).decode('utf-8')
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(f"Cannot remove, app is installed on site: {site}")
sys.exit(1) sys.exit(1)
exec_cmd("{0} -m pip uninstall -y {1}".format(py, app), cwd=bench_path) exec_cmd(f"{py} -m pip uninstall -y {app}", cwd=bench_path)
remove_from_appstxt(app, bench_path) remove_from_appstxt(app, bench_path)
shutil.rmtree(app_path) shutil.rmtree(app_path)
run_frappe_cmd("build", bench_path=bench_path) run_frappe_cmd("build", bench_path=bench_path)
@ -239,30 +233,30 @@ def pull_apps(apps=None, bench_path='.', reset=False):
for app in apps: for app in apps:
excluded_apps = get_excluded_apps() excluded_apps = get_excluded_apps()
if app in excluded_apps: if app in excluded_apps:
print("Skipping reset for app {}".format(app)) print(f"Skipping reset for app {app}")
continue continue
app_dir = get_repo_dir(app, bench_path=bench_path) app_dir = get_repo_dir(app, bench_path=bench_path)
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', shell=True, cwd=app_dir) out = subprocess.check_output('git status', shell=True, cwd=app_dir)
out = out.decode('utf-8') out = out.decode('utf-8')
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(f'''
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 "{app}" that are not committed.
Here are your choices: Here are your choices:
1. Merge the {0} app manually with "git pull" / "git pull --rebase" and fix conflicts. 1. Merge the {app} app manually with "git pull" / "git pull --rebase" and fix conflicts.
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.''')
sys.exit(1) sys.exit(1)
excluded_apps = get_excluded_apps() excluded_apps = get_excluded_apps()
for app in apps: for app in apps:
if app in excluded_apps: if app in excluded_apps:
print("Skipping pull for app {}".format(app)) print(f"Skipping pull for app {app}")
continue continue
app_dir = get_repo_dir(app, bench_path=bench_path) app_dir = get_repo_dir(app, bench_path=bench_path)
if os.path.exists(os.path.join(app_dir, '.git')): if os.path.exists(os.path.join(app_dir, '.git')):
@ -270,7 +264,7 @@ Here are your choices:
if not remote: if not remote:
# remote is False, i.e. remote doesn't exist, add the app to excluded_apps.txt # remote is False, i.e. remote doesn't exist, add the app to excluded_apps.txt
add_to_excluded_apps_txt(app, bench_path=bench_path) add_to_excluded_apps_txt(app, bench_path=bench_path)
print("Skipping pull for app {}, since remote doesn't exist, and adding it to excluded apps".format(app)) print(f"Skipping pull for app {app}, since remote doesn't exist, and adding it to excluded apps")
continue continue
if not get_config(bench_path).get('shallow_clone') or not reset: if not get_config(bench_path).get('shallow_clone') or not reset:
@ -281,11 +275,11 @@ Here are your choices:
exec_cmd(f"git fetch {remote} --unshallow", cwd=app_dir) exec_cmd(f"git fetch {remote} --unshallow", cwd=app_dir)
branch = get_current_branch(app, bench_path=bench_path) branch = get_current_branch(app, bench_path=bench_path)
logger.log('pulling {0}'.format(app)) logger.log(f'pulling {app}')
if reset: if reset:
reset_cmd = "git reset --hard {remote}/{branch}".format(remote=remote, branch=branch) reset_cmd = f"git reset --hard {remote}/{branch}"
if get_config(bench_path).get('shallow_clone'): if get_config(bench_path).get('shallow_clone'):
exec_cmd("git fetch --depth=1 --no-tags {remote} {branch}".format(remote=remote, branch=branch), exec_cmd(f"git fetch --depth=1 --no-tags {remote} {branch}",
cwd=app_dir) cwd=app_dir)
exec_cmd(reset_cmd, cwd=app_dir) exec_cmd(reset_cmd, cwd=app_dir)
exec_cmd("git reflog expire --all", cwd=app_dir) exec_cmd("git reflog expire --all", cwd=app_dir)
@ -294,8 +288,7 @@ Here are your choices:
exec_cmd("git fetch --all", cwd=app_dir) exec_cmd("git fetch --all", cwd=app_dir)
exec_cmd(reset_cmd, cwd=app_dir) exec_cmd(reset_cmd, cwd=app_dir)
else: else:
exec_cmd("git pull {rebase} {remote} {branch}".format(rebase=rebase, exec_cmd(f"git pull {rebase} {remote} {branch}", cwd=app_dir)
remote=remote, branch=branch), cwd=app_dir)
exec_cmd('find . -name "*.pyc" -delete', cwd=app_dir) exec_cmd('find . -name "*.pyc" -delete', cwd=app_dir)
@ -303,7 +296,7 @@ def is_version_upgrade(app='frappe', bench_path='.', branch=None):
upstream_version = get_upstream_version(app=app, branch=branch, bench_path=bench_path) upstream_version = get_upstream_version(app=app, branch=branch, bench_path=bench_path)
if not upstream_version: if not upstream_version:
raise InvalidBranchException('Specified branch of app {0} is not in upstream remote'.format(app)) raise InvalidBranchException(f'Specified branch of app {app} is not in upstream remote')
local_version = get_major_version(get_current_version(app, bench_path=bench_path)) local_version = get_major_version(get_current_version(app, bench_path=bench_path))
upstream_version = get_major_version(upstream_version) upstream_version = get_major_version(upstream_version)
@ -374,12 +367,12 @@ 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:
subprocess.call('git fetch --depth=1 --no-tags upstream {branch}'.format(branch=branch), shell=True, cwd=repo_dir) subprocess.call(f'git fetch --depth=1 --no-tags upstream {branch}', shell=True, cwd=repo_dir)
except CommandFailedError: except CommandFailedError:
raise InvalidRemoteException('Failed to fetch from remote named upstream for {0}'.format(app)) raise InvalidRemoteException(f'Failed to fetch from remote named upstream for {app}')
try: try:
contents = subprocess.check_output('git show upstream/{branch}:{app}/__init__.py'.format(branch=branch, app=app), contents = subprocess.check_output(f'git show upstream/{branch}:{app}/__init__.py',
shell=True, cwd=repo_dir, stderr=subprocess.STDOUT) shell=True, cwd=repo_dir, stderr=subprocess.STDOUT)
contents = contents.decode('utf-8') contents = contents.decode('utf-8')
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
@ -394,8 +387,9 @@ 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):
import git import git
from six.moves import reload_module import importlib
from bench.utils import update_requirements, update_node_packages, backup_all_sites, patch_sites, build_assets, post_upgrade from bench.utils import update_requirements, update_node_packages, backup_all_sites, patch_sites, build_assets, post_upgrade
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 = []
@ -410,29 +404,29 @@ def switch_branch(branch, apps=None, bench_path='.', upgrade=False, check_upgrad
app_dir = os.path.join(apps_dir, app) app_dir = os.path.join(apps_dir, app)
if not os.path.exists(app_dir): if not os.path.exists(app_dir):
bench.utils.log("{} does not exist!".format(app), level=2) bench.utils.log(f"{app} does not exist!", level=2)
continue continue
repo = git.Repo(app_dir) repo = git.Repo(app_dir)
unshallow_flag = os.path.exists(os.path.join(app_dir, ".git", "shallow")) unshallow_flag = os.path.exists(os.path.join(app_dir, ".git", "shallow"))
bench.utils.log("Fetching upstream {0}for {1}".format("unshallow " if unshallow_flag else "", app)) bench.utils.log(f"Fetching upstream {'unshallow ' if unshallow_flag else ''}for {app}")
bench.utils.exec_cmd("git remote set-branches upstream '*'", cwd=app_dir) bench.utils.exec_cmd("git remote set-branches upstream '*'", cwd=app_dir)
bench.utils.exec_cmd("git fetch --all{0} --quiet".format(" --unshallow" if unshallow_flag else ""), cwd=app_dir) bench.utils.exec_cmd(f"git fetch --all{' --unshallow' if unshallow_flag else ''} --quiet", cwd=app_dir)
if check_upgrade: if check_upgrade:
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:
bench.utils.log("Switching to {0} will cause upgrade from {1} to {2}. Pass --upgrade to confirm".format(branch, version_upgrade[1], version_upgrade[2]), level=2) bench.utils.log(f"Switching to {branch} will cause upgrade from {version_upgrade[1]} to {version_upgrade[2]}. Pass --upgrade to confirm", level=2)
sys.exit(1) sys.exit(1)
print("Switching for "+app) print("Switching for "+app)
bench.utils.exec_cmd("git checkout -f {0}".format(branch), cwd=app_dir) bench.utils.exec_cmd(f"git checkout -f {branch}", cwd=app_dir)
if str(repo.active_branch) == branch: if str(repo.active_branch) == branch:
switched_apps.append(app) switched_apps.append(app)
else: else:
bench.utils.log("Switching branches failed for: {}".format(app), level=2) bench.utils.log(f"Switching branches failed for: {app}", level=2)
if switched_apps: if switched_apps:
bench.utils.log("Successfully switched branches for: " + ", ".join(switched_apps), level=1) bench.utils.log("Successfully switched branches for: " + ", ".join(switched_apps), level=1)
@ -441,7 +435,7 @@ def switch_branch(branch, apps=None, bench_path='.', upgrade=False, check_upgrad
if version_upgrade[0] and upgrade: if version_upgrade[0] and upgrade:
update_requirements() update_requirements()
update_node_packages() update_node_packages()
reload_module(bench.utils) importlib.reload(bench.utils)
backup_all_sites() backup_all_sites()
patch_sites() patch_sites()
build_assets() build_assets()

View File

@ -64,7 +64,7 @@ def cli():
except BaseException as e: except BaseException as e:
return_code = getattr(e, "code", 0) return_code = getattr(e, "code", 0)
if return_code: if return_code:
logger.warning("{0} executed with exit code {1}".format(command, return_code)) logger.warning(f"{command} executed with exit code {return_code}")
sys.exit(return_code) sys.exit(return_code)
@ -140,7 +140,7 @@ def get_frappe_help(bench_path='.'):
python = get_env_cmd('python', bench_path=bench_path) python = get_env_cmd('python', bench_path=bench_path)
sites_path = os.path.join(bench_path, 'sites') sites_path = os.path.join(bench_path, 'sites')
try: try:
out = get_cmd_output("{python} -m frappe.utils.bench_helper get-frappe-help".format(python=python), cwd=sites_path) out = get_cmd_output(f"{python} -m frappe.utils.bench_helper get-frappe-help", cwd=sites_path)
return "\n\nFramework commands:\n" + out.split('Commands:')[1] return "\n\nFramework commands:\n" + out.split('Commands:')[1]
except: except:
return "" return ""

View File

@ -19,7 +19,7 @@ def remote_set_url(git_url):
@click.command('remote-reset-url', help="Reset app remote url to frappe official") @click.command('remote-reset-url', help="Reset app remote url to frappe official")
@click.argument('app') @click.argument('app')
def remote_reset_url(app): def remote_reset_url(app):
git_url = "https://github.com/frappe/{}.git".format(app) git_url = f"https://github.com/frappe/{app}.git"
set_git_remote_url(git_url) set_git_remote_url(git_url)
@ -30,6 +30,6 @@ 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', f'remote.{remote}.url'], cwd=repo_dir).strip()
print("{app} {remote_url}".format(app=app, remote_url=remote_url)) print(f"{app}\t{remote_url}")

View File

@ -35,17 +35,17 @@ def init(path, apps_path, frappe_path, frappe_branch, no_procfile, no_backups, c
skip_assets=skip_assets, skip_assets=skip_assets,
python=python, python=python,
) )
log('Bench {} initialized'.format(path), level=1) log(f'Bench {path} initialized', level=1)
except SystemExit: except SystemExit:
pass pass
except Exception as e: except Exception as e:
import os, shutil, time, six import os, shutil, time
# add a sleep here so that the traceback of other processes doesnt overlap with the prompts # add a sleep here so that the traceback of other processes doesnt overlap with the prompts
time.sleep(1) time.sleep(1)
print(e) print(e)
log("There was a problem while creating {}".format(path), level=2) log(f"There was a problem while creating {path}", level=2)
if six.moves.input("Do you want to rollback these changes? [Y/n]: ").lower() == "y": if click.confirm("Do you want to rollback these changes?"):
print('Rolling back Bench "{}"'.format(path)) print(f'Rolling back Bench "{path}"')
if os.path.exists(path): if os.path.exists(path):
shutil.rmtree(path) shutil.rmtree(path)

View File

@ -84,7 +84,7 @@ def setup_env(python="python3"):
@click.option("--force") @click.option("--force")
def setup_firewall(ssh_port=None, force=False): def setup_firewall(ssh_port=None, force=False):
if not force: if not force:
click.confirm("Setting up the firewall will block all ports except 80, 443 and {0}\nDo you want to continue?".format(ssh_port), abort=True) click.confirm(f"Setting up the firewall will block all ports except 80, 443 and {ssh_port}\nDo you want to continue?", abort=True)
if not ssh_port: if not ssh_port:
ssh_port = 22 ssh_port = 22
@ -97,7 +97,7 @@ def setup_firewall(ssh_port=None, force=False):
@click.option("--force") @click.option("--force")
def set_ssh_port(port, force=False): def set_ssh_port(port, force=False):
if not force: if not force:
click.confirm("This will change your SSH Port to {}\nDo you want to continue?".format(port), abort=True) click.confirm(f"This will change your SSH Port to {port}\nDo you want to continue?", abort=True)
run_playbook("roles/bench/tasks/change_ssh_port.yml", {"ssh_port": port}) run_playbook("roles/bench/tasks/change_ssh_port.yml", {"ssh_port": port})
@ -154,7 +154,6 @@ def setup_requirements(node=False, python=False):
@click.option("--port", help="Port on which you want to run bench manager", default=23624) @click.option("--port", help="Port on which you want to run bench manager", default=23624)
@click.option("--domain", help="Domain on which you want to run bench manager") @click.option("--domain", help="Domain on which you want to run bench manager")
def setup_manager(yes=False, port=23624, domain=None): def setup_manager(yes=False, port=23624, domain=None):
from six.moves import input
from bench.utils import get_sites from bench.utils import get_sites
from bench.config.common_site_config import get_config from bench.config.common_site_config import get_config
from bench.config.nginx import make_bench_manager_nginx_conf from bench.config.nginx import make_bench_manager_nginx_conf
@ -162,11 +161,7 @@ def setup_manager(yes=False, port=23624, domain=None):
create_new_site = True create_new_site = True
if "bench-manager.local" in os.listdir("sites"): if "bench-manager.local" in os.listdir("sites"):
ans = input("Site already exists. Overwrite existing site? [Y/n]: ").lower() create_new_site = click.confirm("Site already exists. Overwrite existing site?")
while ans not in ("y", "n", ""):
ans = input("Please enter 'y' or 'n'. Site already exists. Overwrite existing site? [Y/n]: ").lower()
if ans == "n":
create_new_site = False
if create_new_site: if create_new_site:
exec_cmd("bench new-site --force bench-manager.local") exec_cmd("bench new-site --force bench-manager.local")

View File

@ -116,7 +116,7 @@ def renew_lets_encrypt():
def backup_site(site): def backup_site(site):
from bench.utils import get_sites, backup_site from bench.utils import get_sites, backup_site
if site not in get_sites(bench_path='.'): if site not in get_sites(bench_path='.'):
print('Site `{0}` not found'.format(site)) print(f'Site `{site}` not found')
sys.exit(1) sys.exit(1)
backup_site(site, bench_path='.') backup_site(site, bench_path='.')

View File

@ -61,7 +61,7 @@ def update_config_for_frappe(config, bench_path):
for key in ('redis_cache', 'redis_queue', 'redis_socketio'): for key in ('redis_cache', 'redis_queue', 'redis_socketio'):
if key not in config: if key not in config:
config[key] = "redis://localhost:{0}".format(ports[key]) config[key] = f"redis://localhost:{ports[key]}"
for key in ('webserver_port', 'socketio_port', 'file_watcher_port'): for key in ('webserver_port', 'socketio_port', 'file_watcher_port'):
if key not in config: if key not in config:
@ -71,7 +71,7 @@ def update_config_for_frappe(config, bench_path):
# TODO Optionally we need to add the host or domain name in case dns_multitenant is false # TODO Optionally we need to add the host or domain name in case dns_multitenant is false
def make_ports(bench_path): def make_ports(bench_path):
from six.moves.urllib.parse import urlparse from urllib.parse import urlparse
benches_path = os.path.dirname(os.path.abspath(bench_path)) benches_path = os.path.dirname(os.path.abspath(bench_path))

View File

@ -24,11 +24,11 @@ def setup_letsencrypt(site, custom_domain, bench_path, interactive):
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(f"SSL for Domain {custom_domain} already exists")
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(f"No custom domain named {custom_domain} set for site")
return return
if interactive: if interactive:
@ -47,7 +47,7 @@ def setup_letsencrypt(site, custom_domain, bench_path, interactive):
def create_config(site, custom_domain): def create_config(site, custom_domain):
config = bench.config.env().get_template('letsencrypt.cfg').render(domain=custom_domain or site) config = bench.config.env().get_template('letsencrypt.cfg').render(domain=custom_domain or site)
config_path = '/etc/letsencrypt/configs/{site}.cfg'.format(site=custom_domain or site) config_path = f'/etc/letsencrypt/configs/{custom_domain or site}.cfg'
create_dir_if_missing(config_path) create_dir_if_missing(config_path)
with open(config_path, 'w') as f: with open(config_path, 'w') as f:
@ -60,13 +60,13 @@ def run_certbot_and_setup_ssl(site, custom_domain, bench_path, interactive=True)
try: try:
interactive = '' if interactive else '-n' interactive = '' if interactive else '-n'
exec_cmd("{path} {interactive} --config /etc/letsencrypt/configs/{site}.cfg certonly".format(path=get_certbot_path(), interactive=interactive, site=custom_domain or site)) exec_cmd(f"{get_certbot_path()} {interactive} --config /etc/letsencrypt/configs/{custom_domain or site}.cfg certonly")
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 = f"/etc/letsencrypt/live/{custom_domain or site}/"
ssl_config = { "ssl_certificate": os.path.join(ssl_path, "fullchain.pem"), ssl_config = { "ssl_certificate": os.path.join(ssl_path, "fullchain.pem"),
"ssl_certificate_key": os.path.join(ssl_path, "privkey.pem") } "ssl_certificate_key": os.path.join(ssl_path, "privkey.pem") }
@ -88,7 +88,7 @@ def setup_crontab():
job_command = '/opt/certbot-auto renew -a nginx --post-hook "systemctl reload nginx"' job_command = '/opt/certbot-auto renew -a nginx --post-hook "systemctl reload nginx"'
job_comment = 'Renew lets-encrypt every month' job_comment = 'Renew lets-encrypt every month'
print("Setting Up cron job to {0}".format(job_comment)) print(f"Setting Up cron job to {job_comment}")
system_crontab = CronTab(user='root') system_crontab = CronTab(user='root')
@ -106,7 +106,7 @@ def create_dir_if_missing(path):
def get_certbot(): def get_certbot():
from six.moves.urllib.request import urlretrieve from urllib.request import urlretrieve
certbot_path = get_certbot_path() certbot_path = get_certbot_path()
create_dir_if_missing(certbot_path) create_dir_if_missing(certbot_path)
@ -129,7 +129,7 @@ def renew_certs():
setup_crontab() setup_crontab()
service('nginx', 'stop') service('nginx', 'stop')
exec_cmd("{path} renew".format(path=get_certbot_path())) exec_cmd(f"{get_certbot_path()} renew")
service('nginx', 'start') service('nginx', 'start')
@ -140,7 +140,7 @@ def setup_wildcard_ssl(domain, email, bench_path, exclude_base_domain):
if not domain.startswith('*.'): if not domain.startswith('*.'):
# add wildcard caracter to domain if missing # add wildcard caracter to domain if missing
domain_list.append('*.{0}'.format(domain)) domain_list.append(f'*.{domain}')
else: else:
# include base domain based on flag # include base domain based on flag
domain_list.append(domain.replace('*.', '')) domain_list.append(domain.replace('*.', ''))
@ -159,19 +159,18 @@ def setup_wildcard_ssl(domain, email, bench_path, exclude_base_domain):
email_param = '' email_param = ''
if email: if email:
email_param = '--email {0}'.format(email) email_param = f'--email {email}'
try: try:
exec_cmd("{path} certonly --manual --preferred-challenges=dns {email_param} \ exec_cmd(f"{get_certbot_path()} certonly --manual --preferred-challenges=dns {email_param} \
--server https://acme-v02.api.letsencrypt.org/directory \ --server https://acme-v02.api.letsencrypt.org/directory \
--agree-tos -d {domain}".format(path=get_certbot_path(), domain=' -d '.join(domain_list), --agree-tos -d {' -d '.join(domain_list)}")
email_param=email_param))
except CommandFailedError: except CommandFailedError:
print("There was a problem trying to setup SSL") print("There was a problem trying to setup SSL")
return return
ssl_path = "/etc/letsencrypt/live/{domain}/".format(domain=domain) ssl_path = f"/etc/letsencrypt/live/{domain}/"
ssl_config = { ssl_config = {
"wildcard": { "wildcard": {
"domain": domain, "domain": domain,

View File

@ -6,7 +6,6 @@ import string
# imports - third party imports # imports - third party imports
import click import click
from six import string_types
# imports - module imports # imports - module imports
import bench import bench
@ -165,15 +164,15 @@ def prepare_sites(config, bench_path):
for port_number in ports_in_use: for port_number in ports_in_use:
if len(ports_in_use[port_number]) > 1: if len(ports_in_use[port_number]) > 1:
port_conflict_index += 1 port_conflict_index += 1
message += "\n{0} - Port {1} is shared among sites:".format(port_conflict_index,port_number) message += f"\n{port_conflict_index} - Port {port_number} is shared among sites:"
for site_name in ports_in_use[port_number]: for site_name in ports_in_use[port_number]:
message += " {0}".format(site_name) message += f" {site_name}"
raise Exception(message) raise Exception(message)
if not dns_multitenant: if not dns_multitenant:
message = "Port configuration list:" message = "Port configuration list:"
for site in sites_configs: for site in sites_configs:
message += "\n\nSite {0} assigned port: {1}".format(site["name"], site["port"]) message += f"\n\nSite {site['name']} assigned port: {site['port']}"
print(message) print(message)
@ -196,13 +195,13 @@ def get_sites_with_config(bench_path):
except Exception as e: except Exception as e:
strict_nginx = get_config(bench_path).get('strict_nginx') strict_nginx = get_config(bench_path).get('strict_nginx')
if strict_nginx: if strict_nginx:
print("\n\nERROR: The site config for the site {} is broken.".format(site), print(f"\n\nERROR: The site config for the site {site} is broken.",
"If you want this command to pass, instead of just throwing an error,", "If you want this command to pass, instead of just throwing an error,",
"You may remove the 'strict_nginx' flag from common_site_config.json or set it to 0", "You may remove the 'strict_nginx' flag from common_site_config.json or set it to 0",
"\n\n") "\n\n")
raise (e) raise (e)
else: else:
print("\n\nWARNING: The site config for the site {} is broken.".format(site), print(f"\n\nWARNING: The site config for the site {site} is broken.",
"If you want this command to fail, instead of just showing a warning,", "If you want this command to fail, instead of just showing a warning,",
"You may add the 'strict_nginx' flag to common_site_config.json and set it to 1", "You may add the 'strict_nginx' flag to common_site_config.json and set it to 1",
"\n\n") "\n\n")
@ -218,7 +217,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, string_types): if isinstance(domain, str):
domain = { 'domain': domain } domain = { 'domain': domain }
domain['name'] = site domain['name'] = site

View File

@ -18,7 +18,7 @@ logger = logging.getLogger(bench.PROJECT_NAME)
def setup_production_prerequisites(): def setup_production_prerequisites():
"""Installs ansible, fail2banc, NGINX and supervisor""" """Installs ansible, fail2banc, NGINX and supervisor"""
if not which("ansible"): if not which("ansible"):
exec_cmd("sudo {0} -m pip install ansible".format(sys.executable)) exec_cmd(f"sudo {sys.executable} -m pip install ansible")
if not which("fail2ban-client"): if not which("fail2ban-client"):
exec_cmd("bench setup role fail2ban") exec_cmd("bench setup role fail2ban")
if not which("nginx"): if not which("nginx"):
@ -47,13 +47,12 @@ def setup_production(user, bench_path='.', yes=False):
remove_default_nginx_configs() remove_default_nginx_configs()
bench_name = get_bench_name(bench_path) bench_name = get_bench_name(bench_path)
nginx_conf = '/etc/nginx/conf.d/{bench_name}.conf'.format(bench_name=bench_name) nginx_conf = f'/etc/nginx/conf.d/{bench_name}.conf'
print("Setting Up symlinks and reloading services...") print("Setting Up symlinks and reloading services...")
if get_config(bench_path).get('restart_supervisor_on_update'): if get_config(bench_path).get('restart_supervisor_on_update'):
supervisor_conf_extn = "ini" if is_centos7() else "conf" supervisor_conf_extn = "ini" if is_centos7() else "conf"
supervisor_conf = os.path.join(get_supervisor_confdir(), '{bench_name}.{extn}'.format( supervisor_conf = os.path.join(get_supervisor_confdir(), f'{bench_name}.{supervisor_conf_extn}')
bench_name=bench_name, extn=supervisor_conf_extn))
# Check if symlink exists, If not then create it. # Check if symlink exists, If not then create it.
if not os.path.islink(supervisor_conf): if not os.path.islink(supervisor_conf):
@ -76,8 +75,7 @@ def disable_production(bench_path='.'):
# supervisorctl # supervisorctl
supervisor_conf_extn = "ini" if is_centos7() else "conf" supervisor_conf_extn = "ini" if is_centos7() else "conf"
supervisor_conf = os.path.join(get_supervisor_confdir(), '{bench_name}.{extn}'.format( supervisor_conf = os.path.join(get_supervisor_confdir(), f'{bench_name}.{supervisor_conf_extn}')
bench_name=bench_name, extn=supervisor_conf_extn))
if os.path.islink(supervisor_conf): if os.path.islink(supervisor_conf):
os.unlink(supervisor_conf) os.unlink(supervisor_conf)
@ -86,7 +84,7 @@ def disable_production(bench_path='.'):
reload_supervisor() reload_supervisor()
# nginx # nginx
nginx_conf = '/etc/nginx/conf.d/{bench_name}.conf'.format(bench_name=bench_name) nginx_conf = f'/etc/nginx/conf.d/{bench_name}.conf'
if os.path.islink(nginx_conf): if os.path.islink(nginx_conf):
os.unlink(nginx_conf) os.unlink(nginx_conf)
@ -96,23 +94,23 @@ def disable_production(bench_path='.'):
def service(service_name, service_option): def service(service_name, service_option):
if os.path.basename(which('systemctl') or '') == 'systemctl' and is_running_systemd(): if os.path.basename(which('systemctl') or '') == 'systemctl' and is_running_systemd():
systemctl_cmd = "sudo {service_manager} {service_option} {service_name}" exec_cmd(f"sudo systemctl {service_option} {service_name}")
exec_cmd(systemctl_cmd.format(service_manager='systemctl', service_option=service_option, service_name=service_name))
elif os.path.basename(which('service') or '') == 'service': elif os.path.basename(which('service') or '') == 'service':
service_cmd = "sudo {service_manager} {service_name} {service_option}" exec_cmd(f"sudo service {service_name} {service_option}")
exec_cmd(service_cmd.format(service_manager='service', service_name=service_name, service_option=service_option))
else: else:
# look for 'service_manager' and 'service_manager_command' in environment # look for 'service_manager' and 'service_manager_command' in environment
service_manager = os.environ.get("BENCH_SERVICE_MANAGER") service_manager = os.environ.get("BENCH_SERVICE_MANAGER")
if service_manager: if service_manager:
service_manager_command = (os.environ.get("BENCH_SERVICE_MANAGER_COMMAND") service_manager_command = (
or "{service_manager} {service_option} {service}").format(service_manager=service_manager, service=service, service_option=service_option) os.environ.get("BENCH_SERVICE_MANAGER_COMMAND")
or f"{service_manager} {service_option} {service}"
)
exec_cmd(service_manager_command) exec_cmd(service_manager_command)
else: else:
log("No service manager found: '{0} {1}' failed to execute".format(service_name, service_option), level=2) log(f"No service manager found: '{service_name} {service_option}' failed to execute", level=2)
def get_supervisor_confdir(): def get_supervisor_confdir():
@ -149,15 +147,15 @@ def reload_supervisor():
try: try:
# first try reread/update # first try reread/update
exec_cmd('{0} reread'.format(supervisorctl)) exec_cmd(f'{supervisorctl} reread')
exec_cmd('{0} update'.format(supervisorctl)) exec_cmd(f'{supervisorctl} update')
return return
except CommandFailedError: except CommandFailedError:
pass pass
try: try:
# something is wrong, so try reloading # something is wrong, so try reloading
exec_cmd('{0} reload'.format(supervisorctl)) exec_cmd(f'{supervisorctl} reload')
return return
except CommandFailedError: except CommandFailedError:
pass pass
@ -178,7 +176,7 @@ def reload_supervisor():
def reload_nginx(): def reload_nginx():
try: try:
exec_cmd('sudo {0} -t'.format(which('nginx'))) exec_cmd(f"sudo {which('nginx')} -t")
except: except:
raise raise

View File

@ -9,7 +9,7 @@ from bench.config.common_site_config import get_config
def generate_config(bench_path): def generate_config(bench_path):
from six.moves.urllib.parse import urlparse from urllib.parse import urlparse
config = get_config(bench_path) config = get_config(bench_path)
@ -69,7 +69,7 @@ def get_redis_version():
return None return None
version = semantic_version.Version(version[0], partial=True) version = semantic_version.Version(version[0], partial=True)
return float('{major}.{minor}'.format(major=version.major, minor=version.minor)) return float(f'{version.major}.{version.minor}')
def get_max_redis_memory(): def get_max_redis_memory():
try: try:

View File

@ -49,7 +49,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(f"Domain {domain} already exists")
return return
if ssl_certificate_key and ssl_certificate: if ssl_certificate_key and ssl_certificate:

View File

@ -67,8 +67,7 @@ def get_supervisord_conf():
def update_supervisord_config(user=None, yes=False): def update_supervisord_config(user=None, yes=False):
"""From bench v5.x, we're moving to supervisor running as user""" """From bench v5.x, we're moving to supervisor running as user"""
from six.moves import configparser import configparser
from bench.config.production_setup import service from bench.config.production_setup import service
if not user: if not user:
@ -78,7 +77,7 @@ def update_supervisord_config(user=None, yes=False):
section = "unix_http_server" section = "unix_http_server"
updated_values = { updated_values = {
"chmod": "0760", "chmod": "0760",
"chown": "{user}:{user}".format(user=user) "chown": f"{user}:{user}"
} }
supervisord_conf_changes = "" supervisord_conf_changes = ""
@ -91,7 +90,7 @@ def update_supervisord_config(user=None, yes=False):
if section not in config.sections(): if section not in config.sections():
config.add_section(section) config.add_section(section)
action = "Section {0} Added".format(section) action = f"Section {section} Added"
logger.log(action) logger.log(action)
supervisord_conf_changes += '\n' + action supervisord_conf_changes += '\n' + action
@ -103,7 +102,7 @@ def update_supervisord_config(user=None, yes=False):
if current_value.strip() != value: if current_value.strip() != value:
config.set(section, key, value) config.set(section, key, value)
action = "Updated supervisord.conf: '{0}' changed from '{1}' to '{2}'".format(key, current_value, value) action = f"Updated supervisord.conf: '{key}' changed from '{current_value}' to '{value}'"
logger.log(action) logger.log(action)
supervisord_conf_changes += '\n' + action supervisord_conf_changes += '\n' + action
@ -112,14 +111,14 @@ def update_supervisord_config(user=None, yes=False):
return return
if not yes: if not yes:
click.confirm("{0} will be updated with the following values:\n{1}\nDo you want to continue?".format(supervisord_conf, supervisord_conf_changes), abort=True) click.confirm(f"{supervisord_conf} will be updated with the following values:\n{supervisord_conf_changes}\nDo you want to continue?", abort=True)
try: try:
with open(supervisord_conf, "w") as f: with open(supervisord_conf, "w") as f:
config.write(f) config.write(f)
logger.log("Updated supervisord.conf at '{0}'".format(supervisord_conf)) logger.log(f"Updated supervisord.conf at '{supervisord_conf}'")
except Exception as e: except Exception as e:
logger.log("Updating supervisord.conf failed due to '{0}'".format(e)) logger.log(f"Updating supervisord.conf failed due to '{e}'")
# Reread supervisor configuration, reload supervisord and supervisorctl, restart services that were started # Reread supervisor configuration, reload supervisord and supervisorctl, restart services that were started
service('supervisor', 'reload') service('supervisor', 'reload')

View File

@ -25,7 +25,7 @@ def generate_systemd_config(bench_path, user=None, yes=False,
bench_name = get_bench_name(bench_path) bench_name = get_bench_name(bench_path)
if stop: if stop:
exec_cmd('sudo systemctl stop -- $(systemctl show -p Requires {bench_name}.target | cut -d= -f2)'.format(bench_name=bench_name)) exec_cmd(f'sudo systemctl stop -- $(systemctl show -p Requires {bench_name}.target | cut -d= -f2)')
return return
if create_symlinks: if create_symlinks:
@ -185,25 +185,15 @@ def _create_symlinks(bench_path):
unit_files = get_unit_files(bench_dir) unit_files = get_unit_files(bench_dir)
for unit_file in unit_files: for unit_file in unit_files:
filename = "".join(unit_file) filename = "".join(unit_file)
exec_cmd('sudo ln -s {config_path}/{unit_file} {etc_systemd_system}/{unit_file_init}'.format( exec_cmd(f'sudo ln -s {config_path}/{filename} {etc_systemd_system}/{"".join(unit_file)}')
config_path=config_path,
etc_systemd_system=etc_systemd_system,
unit_file=filename,
unit_file_init="".join(unit_file)
))
exec_cmd('sudo systemctl daemon-reload') exec_cmd('sudo systemctl daemon-reload')
def _delete_symlinks(bench_path): def _delete_symlinks(bench_path):
bench_dir = os.path.abspath(bench_path) bench_dir = os.path.abspath(bench_path)
etc_systemd_system = os.path.join('/', 'etc', 'systemd', 'system') etc_systemd_system = os.path.join('/', 'etc', 'systemd', 'system')
config_path = os.path.join(bench_dir, 'config', 'systemd')
unit_files = get_unit_files(bench_dir) unit_files = get_unit_files(bench_dir)
for unit_file in unit_files: for unit_file in unit_files:
exec_cmd('sudo rm {etc_systemd_system}/{unit_file_init}'.format( exec_cmd(f'sudo rm {etc_systemd_system}/{"".join(unit_file)}')
config_path=config_path,
etc_systemd_system=etc_systemd_system,
unit_file_init="".join(unit_file)
))
exec_cmd('sudo systemctl daemon-reload') exec_cmd('sudo systemctl daemon-reload')
def get_unit_files(bench_path): def get_unit_files(bench_path):

View File

@ -34,13 +34,13 @@ def is_production_set(bench_path):
bench_name = get_bench_name(bench_path) bench_name = get_bench_name(bench_path)
supervisor_conf_extn = "ini" if is_centos7() else "conf" supervisor_conf_extn = "ini" if is_centos7() else "conf"
supervisor_conf_file_name = '{bench_name}.{extn}'.format(bench_name=bench_name, extn=supervisor_conf_extn) supervisor_conf_file_name = f'{bench_name}.{supervisor_conf_extn}'
supervisor_conf = os.path.join(get_supervisor_confdir(), supervisor_conf_file_name) supervisor_conf = os.path.join(get_supervisor_confdir(), supervisor_conf_file_name)
if os.path.exists(supervisor_conf): if os.path.exists(supervisor_conf):
production_setup = production_setup or True production_setup = production_setup or True
nginx_conf = '/etc/nginx/conf.d/{bench_name}.conf'.format(bench_name=bench_name) nginx_conf = f'/etc/nginx/conf.d/{bench_name}.conf'
if os.path.exists(nginx_conf): if os.path.exists(nginx_conf):
production_setup = production_setup or True production_setup = production_setup or True
@ -54,7 +54,7 @@ def execute(bench_path):
if is_sudoers_set(): if is_sudoers_set():
if is_production_set(bench_path): if is_production_set(bench_path):
exec_cmd("sudo bench setup supervisor --yes --user {user}".format(user=user)) exec_cmd(f"sudo bench setup supervisor --yes --user {user}")
service("supervisord", "restart") service("supervisord", "restart")
exec_cmd("sudo bench setup sudoers {user}".format(user=user)) exec_cmd(f"sudo bench setup sudoers {user}")

View File

@ -15,7 +15,7 @@ def prepare_beta_release(bench_path, app, owner='frappe', remote='upstream'):
beta_master = click.prompt('Branch name for beta release', type=str) beta_master = click.prompt('Branch name for beta release', type=str)
if click.confirm("Do you want to setup hotfix for beta ?"): if click.confirm("Do you want to setup hotfix for beta ?"):
beta_hotfix = click.prompt('Branch name for beta hotfix ({}_hotifx)'.format(beta_master), type=str) beta_hotfix = click.prompt(f'Branch name for beta hotfix ({beta_master}_hotifx)', type=str)
validate(bench_path) validate(bench_path)
repo_path = os.path.join(bench_path, 'apps', app) repo_path = os.path.join(bench_path, 'apps', app)
@ -68,7 +68,7 @@ def set_beta_version(repo_path, version):
repo = git.Repo(repo_path) repo = git.Repo(repo_path)
app_name = os.path.basename(repo_path) app_name = os.path.basename(repo_path)
repo.index.add([os.path.join(app_name, 'hooks.py')]) repo.index.add([os.path.join(app_name, 'hooks.py')])
repo.index.commit('bumped to version {}'.format(version)) repo.index.commit(f'bumped to version {version}')
def prepare_beta_hotfix(repo_path, beta_hotfix, remote): def prepare_beta_hotfix(repo_path, beta_hotfix, remote):
@ -83,7 +83,7 @@ def merge_beta_release_to_develop(repo_path, beta_master, remote, version):
g = repo.git g = repo.git
tag_name = 'v' + version tag_name = 'v' + version
repo.create_tag(tag_name, message='Release {}'.format(version)) repo.create_tag(tag_name, message=f'Release {version}')
g.checkout('develop') g.checkout('develop')
@ -100,11 +100,11 @@ def push_branches(repo_path, beta_master, beta_hotfix, remote):
args = [ args = [
'develop:develop', 'develop:develop',
'{beta_master}:{beta_master}'.format(beta_master=beta_master), f'{beta_master}:{beta_master}',
] ]
if beta_hotfix: if beta_hotfix:
args.append('{beta_hotfix}:{beta_hotfix}'.format(beta_hotfix=beta_hotfix)) args.append(f'{beta_hotfix}:{beta_hotfix}')
args.append('--tags') args.append('--tags')

View File

@ -93,7 +93,7 @@ def bump(bench_path, app, bump_type, from_branch, to_branch, remote, owner, repo
push_release(repo_path, from_branch=from_branch, to_branch=to_branch, remote=remote) push_release(repo_path, from_branch=from_branch, to_branch=to_branch, remote=remote)
prerelease = True if 'beta' in new_version else False prerelease = True if 'beta' in new_version else False
create_github_release(repo_path, tag_name, message, remote=remote, owner=owner, repo_name=repo_name, prerelease=prerelease) create_github_release(repo_path, tag_name, message, remote=remote, owner=owner, repo_name=repo_name, prerelease=prerelease)
print('Released {tag} for {repo_path}'.format(tag=tag_name, repo_path=repo_path)) print(f'Released {tag_name} for {repo_path}')
def update_branches_and_check_for_changelog(repo_path, from_branch, to_branch, remote='upstream'): def update_branches_and_check_for_changelog(repo_path, from_branch, to_branch, remote='upstream'):
@ -125,8 +125,7 @@ def get_release_message(repo_path, from_branch, to_branch, remote='upstream'):
repo = git.Repo(repo_path) repo = git.Repo(repo_path)
g = repo.git g = repo.git
log = g.log('{remote}/{to_branch}..{remote}/{from_branch}'.format( log = g.log(f'{remote}/{to_branch}..{remote}/{from_branch}', '--format=format:%s', '--no-merges')
remote=remote, to_branch=to_branch, from_branch=from_branch), '--format=format:%s', '--no-merges')
if log: if log:
return "* " + log.replace('\n', '\n* ') return "* " + log.replace('\n', '\n* ')
@ -246,7 +245,7 @@ def commit_changes(repo_path, new_version, to_branch):
else: else:
repo.index.add([os.path.join(app_name, 'hooks.py')]) repo.index.add([os.path.join(app_name, 'hooks.py')])
repo.index.commit('bumped to version {}'.format(new_version)) repo.index.commit(f'bumped to version {new_version}')
def create_release(repo_path, new_version, from_branch, to_branch, frontport=True): def create_release(repo_path, new_version, from_branch, to_branch, frontport=True):
print('creating release for version', new_version) print('creating release for version', new_version)
@ -259,7 +258,7 @@ def create_release(repo_path, new_version, from_branch, to_branch, frontport=Tru
handle_merge_error(e, source=from_branch, target=to_branch) handle_merge_error(e, source=from_branch, target=to_branch)
tag_name = 'v' + new_version tag_name = 'v' + new_version
repo.create_tag(tag_name, message='Release {}'.format(new_version)) repo.create_tag(tag_name, message=f'Release {new_version}')
g.checkout(from_branch) g.checkout(from_branch)
try: try:
@ -269,8 +268,8 @@ def create_release(repo_path, new_version, from_branch, to_branch, frontport=Tru
if frontport: if frontport:
for branch in branches_to_update[from_branch]: for branch in branches_to_update[from_branch]:
print ("Front porting changes to {}".format(branch)) print (f"Front porting changes to {branch}")
print('merging {0} into'.format(to_branch), branch) print(f'merging {to_branch} into', branch)
g.checkout(branch) g.checkout(branch)
try: try:
g.merge(to_branch) g.merge(to_branch)
@ -281,7 +280,7 @@ def create_release(repo_path, new_version, from_branch, to_branch, frontport=Tru
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(f'Error when merging {source} into {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)
@ -292,13 +291,13 @@ def push_release(repo_path, from_branch, to_branch, remote='upstream'):
repo = git.Repo(repo_path) repo = git.Repo(repo_path)
g = repo.git g = repo.git
args = [ args = [
'{to_branch}:{to_branch}'.format(to_branch=to_branch), f'{to_branch}:{to_branch}',
'{from_branch}:{from_branch}'.format(from_branch=from_branch) f'{from_branch}:{from_branch}'
] ]
for branch in branches_to_update[from_branch]: for branch in branches_to_update[from_branch]:
print('pushing {0} branch of'.format(branch), repo_path) print(f'pushing {branch} branch of', repo_path)
args.append('{branch}:{branch}'.format(branch=branch)) args.append(f'{branch}:{branch}')
args.append('--tags') args.append('--tags')
@ -330,8 +329,7 @@ def create_github_release(repo_path, tag_name, message, remote='upstream', owner
} }
for i in range(3): for i in range(3):
try: try:
r = requests.post('https://api.github.com/repos/{owner}/{repo_name}/releases'.format( r = requests.post(f'https://api.github.com/repos/{owner}/{repo_name}/releases',
owner=owner, repo_name=repo_name),
auth=HTTPBasicAuth(gh_username, gh_password), data=json.dumps(data)) auth=HTTPBasicAuth(gh_username, gh_password), data=json.dumps(data))
r.raise_for_status() r.raise_for_status()
break break
@ -350,9 +348,9 @@ def push_branch_for_old_major_version(bench_path, bump_type, app, repo_path, fro
return return
current_version = get_current_version(repo_path) current_version = get_current_version(repo_path)
old_major_version_branch = "v{major}.x.x".format(major=current_version.split('.')[0]) old_major_version_branch = f"v{current_version.split('.')[0]}.x.x"
click.confirm('Do you want to push {branch}?'.format(branch=old_major_version_branch), abort=True) click.confirm(f'Do you want to push {old_major_version_branch}?', abort=True)
update_branch(repo_path, to_branch, remote=remote) update_branch(repo_path, to_branch, remote=remote)
@ -360,8 +358,8 @@ def push_branch_for_old_major_version(bench_path, bump_type, app, repo_path, fro
g.checkout(b=old_major_version_branch) g.checkout(b=old_major_version_branch)
args = [ args = [
'{old_major_version_branch}:{old_major_version_branch}'.format(old_major_version_branch=old_major_version_branch), f'{old_major_version_branch}:{old_major_version_branch}',
] ]
print("Pushing {old_major_version_branch} ".format(old_major_version_branch=old_major_version_branch)) print(f"Pushing {old_major_version_branch} ")
print(g.push(remote, *args)) print(g.push(remote, *args))

View File

@ -8,14 +8,11 @@ import sys
import traceback import traceback
import unittest import unittest
# imports - third party imports
from six import PY2
# imports - module imports # imports - module imports
import bench import bench
import bench.utils import bench.utils
if PY2: if sys.version_info.major == 2:
FRAPPE_BRANCH = "version-12" FRAPPE_BRANCH = "version-12"
else: else:
FRAPPE_BRANCH = "develop" FRAPPE_BRANCH = "develop"
@ -84,7 +81,7 @@ class TestBenchBase(unittest.TestCase):
frappe_tmp_path = "/tmp/frappe" frappe_tmp_path = "/tmp/frappe"
if not os.path.exists(frappe_tmp_path): if not os.path.exists(frappe_tmp_path):
bench.utils.exec_cmd("git clone https://github.com/frappe/frappe -b {branch} --depth 1 --origin upstream {location}".format(branch=FRAPPE_BRANCH, location=frappe_tmp_path)) bench.utils.exec_cmd(f"git clone https://github.com/frappe/frappe -b {FRAPPE_BRANCH} --depth 1 --origin upstream {frappe_tmp_path}")
kwargs.update(dict( kwargs.update(dict(
python=sys.executable, python=sys.executable,

View File

@ -121,7 +121,7 @@ class TestBenchInit(TestBenchBase):
# create and install app on site # create and install app on site
self.new_site(site_name, bench_name) self.new_site(site_name, bench_name)
installed_app = not bench.utils.exec_cmd("bench --site {0} install-app frappe_theme".format(site_name), cwd=bench_path) installed_app = not bench.utils.exec_cmd(f"bench --site {site_name} install-app frappe_theme", cwd=bench_path)
app_installed_on_site = subprocess.check_output(["bench", "--site", site_name, "list-apps"], cwd=bench_path).decode('utf8') app_installed_on_site = subprocess.check_output(["bench", "--site", site_name, "list-apps"], cwd=bench_path).decode('utf8')

View File

@ -19,13 +19,13 @@ class TestSetupProduction(TestBenchBase):
for bench_name in ("test-bench-1", "test-bench-2"): for bench_name in ("test-bench-1", "test-bench-2"):
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)
self.init_bench(bench_name) self.init_bench(bench_name)
bench.utils.exec_cmd("sudo bench setup production {0} --yes".format(user), cwd=bench_path) bench.utils.exec_cmd(f"sudo bench setup production {user} --yes", cwd=bench_path)
self.assert_nginx_config(bench_name) self.assert_nginx_config(bench_name)
self.assert_supervisor_config(bench_name) self.assert_supervisor_config(bench_name)
self.assert_supervisor_process(bench_name) self.assert_supervisor_process(bench_name)
self.assert_nginx_process() self.assert_nginx_process()
bench.utils.exec_cmd("sudo bench setup sudoers {0}".format(user)) bench.utils.exec_cmd(f"sudo bench setup sudoers {user}")
self.assert_sudoers(user) self.assert_sudoers(user)
for bench_name in self.benches: for bench_name in self.benches:
@ -42,7 +42,7 @@ class TestSetupProduction(TestBenchBase):
def assert_nginx_config(self, bench_name): def assert_nginx_config(self, bench_name):
conf_src = os.path.join(os.path.abspath(self.benches_path), bench_name, 'config', 'nginx.conf') conf_src = os.path.join(os.path.abspath(self.benches_path), bench_name, 'config', 'nginx.conf')
conf_dest = "/etc/nginx/conf.d/{bench_name}.conf".format(bench_name=bench_name) conf_dest = f"/etc/nginx/conf.d/{bench_name}.conf"
self.assertTrue(self.file_exists(conf_src)) self.assertTrue(self.file_exists(conf_src))
self.assertTrue(self.file_exists(conf_dest)) self.assertTrue(self.file_exists(conf_dest))
@ -55,10 +55,10 @@ class TestSetupProduction(TestBenchBase):
f = f.read() f = f.read()
for key in ( for key in (
"upstream {bench_name}-frappe", f"upstream {bench_name}-frappe",
"upstream {bench_name}-socketio-server" f"upstream {bench_name}-socketio-server"
): ):
self.assertTrue(key.format(bench_name=bench_name) in f) self.assertTrue(key in f)
def assert_nginx_process(self): def assert_nginx_process(self):
@ -79,15 +79,15 @@ class TestSetupProduction(TestBenchBase):
with open(sudoers_file, 'r') as f: with open(sudoers_file, 'r') as f:
sudoers = f.read() sudoers = f.read()
self.assertTrue('{user} ALL = (root) NOPASSWD: {service} nginx *'.format(service=service, user=user) in sudoers) self.assertTrue(f'{user} ALL = (root) NOPASSWD: {service} nginx *' in sudoers)
self.assertTrue('{user} ALL = (root) NOPASSWD: {nginx}'.format(nginx=nginx, user=user) in sudoers) self.assertTrue(f'{user} ALL = (root) NOPASSWD: {nginx}' in sudoers)
def assert_supervisor_config(self, bench_name, use_rq=True): def assert_supervisor_config(self, bench_name, use_rq=True):
conf_src = os.path.join(os.path.abspath(self.benches_path), bench_name, 'config', 'supervisor.conf') conf_src = os.path.join(os.path.abspath(self.benches_path), bench_name, 'config', 'supervisor.conf')
supervisor_conf_dir = get_supervisor_confdir() supervisor_conf_dir = get_supervisor_confdir()
conf_dest = "{supervisor_conf_dir}/{bench_name}.conf".format(supervisor_conf_dir=supervisor_conf_dir, bench_name=bench_name) conf_dest = f"{supervisor_conf_dir}/{bench_name}.conf"
self.assertTrue(self.file_exists(conf_src)) self.assertTrue(self.file_exists(conf_src))
self.assertTrue(self.file_exists(conf_dest)) self.assertTrue(self.file_exists(conf_dest))
@ -100,38 +100,36 @@ class TestSetupProduction(TestBenchBase):
f = f.read() f = f.read()
tests = [ tests = [
"program:{bench_name}-frappe-web", f"program:{bench_name}-frappe-web",
"program:{bench_name}-redis-cache", f"program:{bench_name}-redis-cache",
"program:{bench_name}-redis-queue", f"program:{bench_name}-redis-queue",
"program:{bench_name}-redis-socketio", f"program:{bench_name}-redis-socketio",
"group:{bench_name}-web", f"group:{bench_name}-web",
"group:{bench_name}-workers", f"group:{bench_name}-workers",
"group:{bench_name}-redis" f"group:{bench_name}-redis"
] ]
if not os.environ.get("CI"): if not os.environ.get("CI"):
tests.append("program:{bench_name}-node-socketio") tests.append(f"program:{bench_name}-node-socketio")
if use_rq: if use_rq:
tests.extend([ tests.extend([
"program:{bench_name}-frappe-schedule", f"program:{bench_name}-frappe-schedule",
"program:{bench_name}-frappe-default-worker", f"program:{bench_name}-frappe-default-worker",
"program:{bench_name}-frappe-short-worker", f"program:{bench_name}-frappe-short-worker",
"program:{bench_name}-frappe-long-worker" f"program:{bench_name}-frappe-long-worker"
]) ])
else: else:
tests.extend([ tests.extend([
"program:{bench_name}-frappe-workerbeat", f"program:{bench_name}-frappe-workerbeat",
"program:{bench_name}-frappe-worker", f"program:{bench_name}-frappe-worker",
"program:{bench_name}-frappe-longjob-worker", f"program:{bench_name}-frappe-longjob-worker",
"program:{bench_name}-frappe-async-worker" f"program:{bench_name}-frappe-async-worker"
]) ])
for key in tests: for key in tests:
if key.format(bench_name=bench_name) not in f: self.assertTrue(key in f)
print(key.format(bench_name=bench_name))
self.assertTrue(key.format(bench_name=bench_name) in f)
def assert_supervisor_process(self, bench_name, use_rq=True, disable_production=False): def assert_supervisor_process(self, bench_name, use_rq=True, disable_production=False):
@ -170,9 +168,9 @@ class TestSetupProduction(TestBenchBase):
for key in tests: for key in tests:
if disable_production: if disable_production:
self.assertFalse(re.search(key.format(bench_name=bench_name), out)) self.assertFalse(re.search(key, out))
else: else:
self.assertTrue(re.search(key.format(bench_name=bench_name), out)) self.assertTrue(re.search(key, out))
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -97,7 +97,7 @@ def check_latest_version():
local_version = Version(bench.VERSION) local_version = Version(bench.VERSION)
if pypi_version > local_version: if pypi_version > local_version:
log("A newer version of bench is available: {0}{1}".format(local_version, pypi_version)) log(f"A newer version of bench is available: {local_version}{pypi_version}")
def get_frappe(bench_path='.'): def get_frappe(bench_path='.'):
@ -134,7 +134,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) and not ignore_exist: if os.path.exists(path) and not ignore_exist:
log('Path {path} already exists!'.format(path=path)) log(f'Path {path} already exists!')
sys.exit(0) sys.exit(0)
elif not os.path.exists(path): elif not os.path.exists(path):
# only create dir if it does not exist # only create dir if it does not exist
@ -213,9 +213,11 @@ def update(pull=False, apps=None, patch=False, build=False, requirements=False,
if version_upgrade[0]: if version_upgrade[0]:
if force: if force:
print("Force flag has been used for a major version change in Frappe and it's apps. \nThis will take significant time to migrate and might break custom apps.") log("""Force flag has been used for a major version change in Frappe and it's apps.
This will take significant time to migrate and might break custom apps.""", level=3)
else: else:
print("This update will cause a major version change in Frappe/ERPNext from {0} to {1}. \nThis would take significant time to migrate and might break custom apps.".format(*version_upgrade[1:])) print(f"""This update will cause a major version change in Frappe/ERPNext from {version_upgrade[1]} to {version_upgrade[2]}.
This would take significant time to migrate and might break custom apps.""")
click.confirm('Do you want to continue?', abort=True) click.confirm('Do you want to continue?', abort=True)
if not reset and conf.get('shallow_clone'): if not reset and conf.get('shallow_clone'):
@ -288,12 +290,12 @@ def copy_patches_txt(bench_path):
def clone_apps_from(bench_path, clone_from, update_app=True): def clone_apps_from(bench_path, clone_from, update_app=True):
from bench.app import install_app from bench.app import install_app
print('Copying apps from {0}...'.format(clone_from)) print(f'Copying apps from {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])
node_modules_path = os.path.join(clone_from, 'node_modules') node_modules_path = os.path.join(clone_from, 'node_modules')
if os.path.exists(node_modules_path): if os.path.exists(node_modules_path):
print('Copying node_modules from {0}...'.format(clone_from)) print(f'Copying node_modules from {clone_from}...')
subprocess.check_output(['cp', '-R', node_modules_path, bench_path]) subprocess.check_output(['cp', '-R', node_modules_path, bench_path])
def setup_app(app): def setup_app(app):
@ -309,7 +311,7 @@ def clone_apps_from(bench_path, clone_from, update_app=True):
remote = 'upstream' remote = 'upstream'
else: else:
remote = remotes[0] remote = remotes[0]
print('Cleaning up {0}'.format(app)) print(f'Cleaning up {app}')
branch = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD'], cwd=app_path).strip() branch = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD'], cwd=app_path).strip()
subprocess.check_output(['git', 'reset', '--hard'], cwd=app_path) subprocess.check_output(['git', 'reset', '--hard'], cwd=app_path)
subprocess.check_output(['git', 'pull', '--rebase', remote, branch], cwd=app_path) subprocess.check_output(['git', 'pull', '--rebase', remote, branch], cwd=app_path)
@ -325,14 +327,14 @@ def clone_apps_from(bench_path, clone_from, update_app=True):
def exec_cmd(cmd, cwd='.'): def exec_cmd(cmd, cwd='.'):
import shlex import shlex
print("{0}$ {1}{2}".format(color.silver, cmd, color.nc)) print(f"{color.silver}$ {cmd}{color.nc}")
cwd_info = "cd {0} && ".format(cwd) if cwd != "." else "" cwd_info = f"cd {cwd} && " if cwd != "." else ""
cmd_log = "{0}{1}".format(cwd_info, cmd) cmd_log = f"{cwd_info}{cmd}"
logger.debug(cmd_log) logger.debug(cmd_log)
cmd = shlex.split(cmd) cmd = shlex.split(cmd)
return_code = subprocess.call(cmd, cwd=cwd, universal_newlines=True) return_code = subprocess.call(cmd, cwd=cwd, universal_newlines=True)
if return_code: if return_code:
logger.warning("{0} executed with exit code {1}".format(cmd_log, return_code)) logger.warning(f"{cmd_log} executed with exit code {return_code}")
def which(executable, raise_err=False): def which(executable, raise_err=False):
@ -341,9 +343,7 @@ def which(executable, raise_err=False):
exec_ = find_executable(executable) exec_ = find_executable(executable)
if not exec_ and raise_err: if not exec_ and raise_err:
raise ValueError('{executable} not found.'.format( raise ValueError(f'{executable} not found.')
executable = executable
))
return exec_ return exec_
@ -356,7 +356,7 @@ def get_venv_path():
with open(os.devnull, "wb") as devnull: with open(os.devnull, "wb") as devnull:
is_venv_installed = not subprocess.call([current_python, "-m", "venv", "--help"], stdout=devnull) is_venv_installed = not subprocess.call([current_python, "-m", "venv", "--help"], stdout=devnull)
if is_venv_installed: if is_venv_installed:
venv = "{} -m venv".format(current_python) venv = f"{current_python} -m venv"
return venv or log("virtualenv cannot be found", level=2) return venv or log("virtualenv cannot be found", level=2)
@ -365,10 +365,10 @@ def setup_env(bench_path='.', python='python3'):
py = os.path.join(bench_path, "env", "bin", "python") py = os.path.join(bench_path, "env", "bin", "python")
virtualenv = get_venv_path() virtualenv = get_venv_path()
exec_cmd('{} -q env -p {}'.format(virtualenv, python), cwd=bench_path) exec_cmd(f'{virtualenv} -q env -p {python}', cwd=bench_path)
if os.path.exists(frappe): if os.path.exists(frappe):
exec_cmd('{} -m pip install -q -U -e {}'.format(py, frappe), cwd=bench_path) exec_cmd(f'{py} -m pip install -q -U -e {frappe}', cwd=bench_path)
def setup_socketio(bench_path='.'): def setup_socketio(bench_path='.'):
@ -387,7 +387,7 @@ def patch_sites(bench_path='.'):
def build_assets(bench_path='.', app=None): def build_assets(bench_path='.', app=None):
command = 'bench build' command = 'bench build'
if app: if app:
command += ' --app {}'.format(app) command += f' --app {app}'
exec_cmd(command, cwd=bench_path) exec_cmd(command, cwd=bench_path)
@ -406,8 +406,8 @@ def setup_backups(bench_path='.'):
user = get_config(bench_path=bench_dir).get('frappe_user') user = get_config(bench_path=bench_dir).get('frappe_user')
logfile = os.path.join(bench_dir, 'logs', 'backup.log') logfile = os.path.join(bench_dir, 'logs', 'backup.log')
system_crontab = CronTab(user=user) system_crontab = CronTab(user=user)
backup_command = "cd {bench_dir} && {bench} --verbose --site all backup".format(bench_dir=bench_dir, bench=sys.argv[0]) backup_command = f"cd {bench_dir} && {sys.argv[0]} --verbose --site all backup"
job_command = "{backup_command} >> {logfile} 2>&1".format(backup_command=backup_command, logfile=logfile) job_command = f"{backup_command} >> {logfile} 2>&1"
if job_command not in str(system_crontab): if job_command not in str(system_crontab):
job = system_crontab.new(command=job_command, comment="bench auto backups set for every 6 hours") job = system_crontab.new(command=job_command, comment="bench auto backups set for every 6 hours")
@ -442,7 +442,7 @@ def setup_sudoers(user):
f.write(frappe_sudoers) f.write(frappe_sudoers)
os.chmod(sudoers_file, 0o440) os.chmod(sudoers_file, 0o440)
log("Sudoers was set up for user {}".format(user), level=1) log(f"Sudoers was set up for user {user}", level=1)
def setup_logging(bench_path='.'): def setup_logging(bench_path='.'):
@ -547,39 +547,38 @@ def restart_supervisor_processes(bench_path='.', web_workers=False):
supervisor_status = get_cmd_output('supervisorctl status', cwd=bench_path) supervisor_status = get_cmd_output('supervisorctl status', cwd=bench_path)
supervisor_status = safe_decode(supervisor_status) supervisor_status = safe_decode(supervisor_status)
if web_workers and '{bench_name}-web:'.format(bench_name=bench_name) in supervisor_status: if web_workers and f'{bench_name}-web:' in supervisor_status:
group = '{bench_name}-web: '.format(bench_name=bench_name) group = f'{bench_name}-web:\t'
elif '{bench_name}-workers:'.format(bench_name=bench_name) in supervisor_status: elif f'{bench_name}-workers:' in supervisor_status:
group = '{bench_name}-workers: {bench_name}-web:'.format(bench_name=bench_name) group = f'{bench_name}-workers: {bench_name}-web:'
# backward compatibility # backward compatibility
elif '{bench_name}-processes:'.format(bench_name=bench_name) in supervisor_status: elif f'{bench_name}-processes:' in supervisor_status:
group = '{bench_name}-processes:'.format(bench_name=bench_name) group = f'{bench_name}-processes:'
# backward compatibility # backward compatibility
else: else:
group = 'frappe:' group = 'frappe:'
exec_cmd('supervisorctl restart {group}'.format(group=group), cwd=bench_path) exec_cmd(f'supervisorctl restart {group}', cwd=bench_path)
def restart_systemd_processes(bench_path='.', web_workers=False): def restart_systemd_processes(bench_path='.', web_workers=False):
bench_name = get_bench_name(bench_path) 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(f'sudo systemctl stop -- $(systemctl show -p Requires {bench_name}.target | cut -d= -f2)')
exec_cmd('sudo systemctl start -- $(systemctl show -p Requires {bench_name}.target | cut -d= -f2)'.format(bench_name=bench_name)) exec_cmd(f'sudo systemctl start -- $(systemctl show -p Requires {bench_name}.target | cut -d= -f2)')
def set_default_site(site, bench_path='.'): def set_default_site(site, bench_path='.'):
if site not in get_sites(bench_path=bench_path): if site not in get_sites(bench_path=bench_path):
raise Exception("Site not in bench") raise Exception("Site not in bench")
exec_cmd("{frappe} --use {site}".format(frappe=get_frappe(bench_path=bench_path), site=site), exec_cmd(f"{get_frappe(bench_path)} --use {site}", cwd=os.path.join(bench_path, 'sites'))
cwd=os.path.join(bench_path, 'sites'))
def update_env_pip(bench_path): def update_env_pip(bench_path):
env_py = os.path.join(bench_path, 'env', 'bin', 'python') env_py = os.path.join(bench_path, 'env', 'bin', 'python')
exec_cmd("{env_py} -m pip install -q -U pip".format(env_py=env_py)) exec_cmd(f"{env_py} -m pip install -q -U pip")
def update_requirements(bench_path='.'): def update_requirements(bench_path='.'):
@ -599,9 +598,9 @@ def update_python_packages(bench_path='.'):
update_env_pip(bench_path) update_env_pip(bench_path)
for app in get_apps(): for app in get_apps():
print('\n{0}Installing python dependencies for {1}{2}'.format(color.yellow, app, color.nc)) print(f'\n{color.yellow}Installing python dependencies for {app}{color.nc}')
app_path = os.path.join(bench_path, "apps", app) app_path = os.path.join(bench_path, "apps", app)
exec_cmd("{0} -m pip install -q -U -e {1}".format(env_py, app_path), cwd=bench_path) exec_cmd(f"{env_py} -m pip install -q -U -e {app_path}", cwd=bench_path)
def update_node_packages(bench_path='.'): def update_node_packages(bench_path='.'):
@ -629,7 +628,7 @@ def update_yarn_packages(bench_path='.'):
for app in os.listdir(apps_dir): for app in os.listdir(apps_dir):
app_path = os.path.join(apps_dir, app) app_path = os.path.join(apps_dir, app)
if os.path.exists(os.path.join(app_path, 'package.json')): if os.path.exists(os.path.join(app_path, 'package.json')):
print('\n{0}Installing node dependencies for {1}{2}'.format(color.yellow, app, color.nc)) print(f'\n{color.yellow}Installing node dependencies for {app}{color.nc}')
exec_cmd('yarn install', cwd=app_path) exec_cmd('yarn install', cwd=app_path)
@ -642,11 +641,9 @@ def update_npm_packages(bench_path='.'):
if os.path.exists(package_json_path): if os.path.exists(package_json_path):
with open(package_json_path, "r") as f: with open(package_json_path, "r") as f:
from six import iteritems
app_package_json = json.loads(f.read()) app_package_json = json.loads(f.read())
# package.json is usually a dict in a dict # package.json is usually a dict in a dict
for key, value in iteritems(app_package_json): for key, value in app_package_json.items():
if not key in package_json: if not key in package_json:
package_json[key] = value package_json[key] = value
else: else:
@ -689,15 +686,15 @@ def set_mariadb_host(host, bench_path='.'):
def set_redis_cache_host(host, bench_path='.'): def set_redis_cache_host(host, bench_path='.'):
update_common_site_config({'redis_cache': "redis://{}".format(host)}, bench_path=bench_path) update_common_site_config({'redis_cache': f"redis://{host}"}, bench_path=bench_path)
def set_redis_queue_host(host, bench_path='.'): def set_redis_queue_host(host, bench_path='.'):
update_common_site_config({'redis_queue': "redis://{}".format(host)}, bench_path=bench_path) update_common_site_config({'redis_queue': f"redis://{host}"}, bench_path=bench_path)
def set_redis_socketio_host(host, bench_path='.'): def set_redis_socketio_host(host, bench_path='.'):
update_common_site_config({'redis_socketio': "redis://{}".format(host)}, bench_path=bench_path) update_common_site_config({'redis_socketio': f"redis://{host}"}, bench_path=bench_path)
def update_common_site_config(ddict, bench_path='.'): def update_common_site_config(ddict, bench_path='.'):
@ -794,7 +791,7 @@ def post_upgrade(from_ver, to_ver, bench_path='.'):
from bench.config.supervisor import generate_supervisor_config from bench.config.supervisor import generate_supervisor_config
from bench.config.nginx import make_nginx_conf from bench.config.nginx import make_nginx_conf
conf = get_config(bench_path=bench_path) conf = get_config(bench_path=bench_path)
print("-" * 80 + "Your bench was upgraded to version {0}".format(to_ver)) print("-" * 80 + f"Your bench was upgraded to version {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)
@ -855,7 +852,7 @@ def update_translations(app, lang):
translations_dir = os.path.join('apps', app, app, 'translations') translations_dir = os.path.join('apps', app, app, 'translations')
csv_file = os.path.join(translations_dir, lang + '.csv') csv_file = os.path.join(translations_dir, lang + '.csv')
url = "https://translate.erpnext.com/files/{}-{}.csv".format(app, lang) url = f"https://translate.erpnext.com/files/{app}-{lang}.csv"
r = requests.get(url, stream=True) r = requests.get(url, stream=True)
r.raise_for_status() r.raise_for_status()
@ -925,12 +922,12 @@ 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(f"No app named {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)
if os.path.exists(os.path.join(app_dir, '.git')): if os.path.exists(os.path.join(app_dir, '.git')):
exec_cmd("git remote set-url upstream {}".format(git_url), cwd=app_dir) exec_cmd(f"git remote set-url upstream {git_url}", cwd=app_dir)
def run_playbook(playbook_name, extra_vars=None, tag=None): def run_playbook(playbook_name, extra_vars=None, tag=None):
@ -961,7 +958,7 @@ def find_benches(directory=None):
if os.path.curdir == directory: if os.path.curdir == directory:
print("You are in a bench directory!") print("You are in a bench directory!")
else: else:
print("{0} is a bench directory!".format(directory)) print(f"{directory} is a bench directory!")
return return
benches = [] benches = []
@ -969,7 +966,7 @@ def find_benches(directory=None):
sub = os.path.join(directory, sub) sub = os.path.join(directory, sub)
if os.path.isdir(sub) and not os.path.islink(sub): if os.path.isdir(sub) and not os.path.islink(sub):
if is_bench_directory(sub): if is_bench_directory(sub):
print("{} found!".format(sub)) print(f"{sub} found!")
benches.append(sub) benches.append(sub)
else: else:
benches.extend(find_benches(sub)) benches.extend(find_benches(sub))
@ -979,7 +976,7 @@ def find_benches(directory=None):
def migrate_env(python, backup=False): def migrate_env(python, backup=False):
import shutil import shutil
from six.moves.urllib.parse import urlparse from urllib.parse import urlparse
from bench.config.common_site_config import get_config from bench.config.common_site_config import get_config
from bench.app import get_apps from bench.app import get_apps
@ -993,13 +990,12 @@ def migrate_env(python, backup=False):
try: try:
config = get_config(bench_path=os.getcwd()) config = get_config(bench_path=os.getcwd())
rredis = urlparse(config['redis_cache']) rredis = urlparse(config['redis_cache'])
redis = f"{which('redis-cli')} -p {rredis.port}"
redis = '{redis} -p {port}'.format(redis=which('redis-cli'), port=rredis.port)
logger.log('Clearing Redis Cache...') logger.log('Clearing Redis Cache...')
exec_cmd('{redis} FLUSHALL'.format(redis = redis)) exec_cmd(f'{redis} FLUSHALL')
logger.log('Clearing Redis DataBase...') logger.log('Clearing Redis DataBase...')
exec_cmd('{redis} FLUSHDB'.format(redis = redis)) exec_cmd(f'{redis} FLUSHDB')
except: except:
logger.warning('Please ensure Redis Connections are running or Daemonized.') logger.warning('Please ensure Redis Connections are running or Daemonized.')
@ -1024,13 +1020,13 @@ def migrate_env(python, backup=False):
# Create virtualenv using specified python # Create virtualenv using specified python
venv_creation, packages_setup = 1, 1 venv_creation, packages_setup = 1, 1
try: try:
logger.log('Setting up a New Virtual {} Environment'.format(python)) logger.log(f'Setting up a New Virtual {python} Environment')
venv_creation = exec_cmd('{virtualenv} --python {python} {pvenv}'.format(virtualenv=virtualenv, python=python, pvenv=pvenv)) venv_creation = exec_cmd(f'{virtualenv} --python {python} {pvenv}')
apps = ' '.join(["-e {}".format(os.path.join("apps", app)) for app in get_apps()]) apps = ' '.join([f"-e {os.path.join('apps', app)}" for app in get_apps()])
packages_setup = exec_cmd('{0} -m pip install -q -U {1}'.format(pvenv, apps)) packages_setup = exec_cmd(f'{pvenv} -m pip install -q -U {apps}')
logger.log('Migration Successful to {}'.format(python)) logger.log(f'Migration Successful to {python}')
except: except:
if venv_creation or packages_setup: if venv_creation or packages_setup:
logger.warning('Migration Error') logger.warning('Migration Error')
@ -1071,7 +1067,7 @@ def generate_command_cache(bench_path='.'):
os.remove(bench_cache_file) os.remove(bench_cache_file)
try: try:
output = get_cmd_output("{0} -m frappe.utils.bench_helper get-frappe-commands".format(python), cwd=sites_path) output = get_cmd_output(f"{python} -m frappe.utils.bench_helper get-frappe-commands", cwd=sites_path)
with open(bench_cache_file, 'w') as f: with open(bench_cache_file, 'w') as f:
json.dump(eval(output), f) json.dump(eval(output), f)
return json.loads(output) return json.loads(output)

View File

@ -1,5 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from __future__ import print_function from __future__ import print_function
import os import os
import sys import sys
import subprocess import subprocess

View File

@ -1,24 +0,0 @@
{
"jasper_erpnext_report": {
"app_url": "http://localhost",
"app_name": "jasper_erpnext_report",
"app_icon": "icon-file-text",
"app_color": "black",
"app_description": "Make your own reports in jasper and print them in pdf, docx, xlsx and other formats.",
"app_publisher": "Luis Fernandes",
"repo_url": "https://github.com/saguas/jasper_erpnext_report.git",
"app_title": "Jasper Erpnext Report",
"app_version": "0.1.0"
},
"base_vat": {
"app_url": "http://localhost",
"app_name": "base_vat",
"app_icon": "icon-credit-card",
"app_color": "#C0C0C0",
"app_description": "Check the VAT number depending of the country.",
"app_publisher": "Luis Fernandes",
"repo_url": "https://github.com/saguas/frappe_base_vat.git",
"app_title": "Base VAT",
"app_version": "0.0.1"
}
}

View File

@ -1,7 +0,0 @@
[
{
"url":"https://github.com/frappe/erpnext",
"name":"erpnext",
"branch": "master"
}
]

View File

@ -1,6 +0,0 @@
[
{
"url":"https://github.com/frappe/erpnext",
"name":"erpnext"
}
]

View File

@ -6,5 +6,4 @@ python-crontab==2.4.0
requests==2.22.0 requests==2.22.0
semantic-version==2.8.2 semantic-version==2.8.2
setuptools setuptools
six
virtualenv virtualenv

View File

@ -11,6 +11,7 @@ setup(
author_email='info@frappe.io', author_email='info@frappe.io',
version=VERSION, version=VERSION,
packages=find_packages(), packages=find_packages(),
python_requires='~=3.6',
zip_safe=False, zip_safe=False,
include_package_data=True, include_package_data=True,
install_requires=install_requires, install_requires=install_requires,