From 44470366323d55967b5e15d652b622f95aab76f6 Mon Sep 17 00:00:00 2001 From: Xavier Beaudouin Date: Fri, 27 Sep 2024 16:25:52 +0200 Subject: [PATCH] Fix --- www/py-frappe-bench/Makefile | 25 +- www/py-frappe-bench/files.old/patch-a93acec | 1763 ----------------- www/py-frappe-bench/files.old/patch-setup.py | 20 - .../files/patch-pyproject.toml | 11 + 4 files changed, 25 insertions(+), 1794 deletions(-) delete mode 100644 www/py-frappe-bench/files.old/patch-a93acec delete mode 100644 www/py-frappe-bench/files.old/patch-setup.py create mode 100644 www/py-frappe-bench/files/patch-pyproject.toml diff --git a/www/py-frappe-bench/Makefile b/www/py-frappe-bench/Makefile index 989c465..569c0e4 100644 --- a/www/py-frappe-bench/Makefile +++ b/www/py-frappe-bench/Makefile @@ -8,21 +8,24 @@ CATEGORIES= www python MASTER_SITES= PYPI PKGNAMEPREFIX= ${PYTHON_PKGNAMEPREFIX} -MAINTAINER= loader@FreeBSD.org +MAINTAINER= kiwi@oav.net COMMENT= Frappe / ERPNext apps setup tool LICENSE= GPLv3 -LICENSE_FILE= ${WRKSRC}/LICENSE.md +#LICENSE_FILE= ${WRKSRC}/LICENSE.md -#RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}click>0:devel/py-click@${PY_FLAVOR} \ -# ${PYTHON_PKGNAMEPREFIX}Jinja2>0:devel/py-Jinja2@${PY_FLAVOR} \ -# ${PYTHON_PKGNAMEPREFIX}virtualenv>0:devel/py-virtualenv@${PY_FLAVOR} \ -# ${PYTHON_PKGNAMEPREFIX}requests>0:www/py-requests@${PY_FLAVOR} \ -# ${PYTHON_PKGNAMEPREFIX}honcho>0:sysutils/py-honcho@${PY_FLAVOR} \ -# ${PYTHON_PKGNAMEPREFIX}semantic_version>0:devel/py-semantic_version@${PY_FLAVOR} \ -# ${PYTHON_PKGNAMEPREFIX}GitPython>=1.0.1:devel/py-gitpython@${PY_FLAVOR} \ -# ${PYTHON_PKGNAMEPREFIX}pip>0:devel/py-pip@${PY_FLAVOR} \ -# git:devel/git +BUILD_DEPENDS= ${PYTHON_PKGNAMEPREFIX}hatchling>=0:devel/py-hatchling@${PY_FLAVOR} + +RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}click>0:devel/py-click@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}Jinja2>0:devel/py-Jinja2@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}virtualenv>0:devel/py-virtualenv@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}requests>0:www/py-requests@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}semantic_version>0:devel/py-semantic_version@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}GitPython>=1.0.1:devel/py-gitpython@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}honcho>0:sysutils/py-honcho@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}python-crontab>0:sysutils/py-python-crontab@${PY_FLAVOR} \ + ${PYTHON_PKGNAMEPREFIX}pip>0:devel/py-pip@${PY_FLAVOR} \ + git:devel/git USE_GITHUB= yes GH_ACCOUNT= frappe diff --git a/www/py-frappe-bench/files.old/patch-a93acec b/www/py-frappe-bench/files.old/patch-a93acec deleted file mode 100644 index 42d14c7..0000000 --- a/www/py-frappe-bench/files.old/patch-a93acec +++ /dev/null @@ -1,1763 +0,0 @@ ---- README.md.orig 2014-11-19 06:36:44 UTC -+++ README.md -@@ -5,7 +5,7 @@ The bench allows you to setup Frappe / E - - To do this install, you must have basic information on how Linux works and should be able to use the command-line. If you are looking easier ways to get started and evaluate ERPNext, [download the Virtual Machine or take a free trial at FrappeCloud.com](https://erpnext.com/use). - --For questions, please join the [developer forum](https://groups.google.com/group/erpnext-developer-forum). -+For questions, please join the [developer forum](https://discuss.frappe.io/). - - Installation - ============ -@@ -37,6 +37,15 @@ Install pre-requisites, - * Redis - * [wkhtmltopdf](http://wkhtmltopdf.org/downloads.html) (optional, required for pdf generation) - * Memcached -+ -+For installing MaraiDB on OSX, use: -+``` -+brew install mariadb -+mysql_install_db -+mysql.server start -+mysqladmin -uroot password ROOTPASSWORD -+``` -+ - - Install bench as a *non root* user, - -@@ -105,11 +114,9 @@ To setup a bench that runs ERPNext, run - cd ~ - bench init frappe-bench - cd frappe-bench --bench get-app erpnext https://github.com/frappe/erpnext # Add ERPNext to your bench apps --bench get-app shopping_cart https://github.com/frappe/shopping-cart # Add Shopping cart to your bench apps --bench new-site site1.local # Create a new site --bench frappe --install_app erpnext site1.local # Install ERPNext for the site --bench frappe --install_app shopping_cart site1.local # Install Shopping cart for the site -+bench get-app erpnext https://github.com/frappe/erpnext # Add ERPNext to your bench apps -+bench new-site site1.local # Create a new site -+bench install-app erpnext # Install ERPNext for the site - ``` - - You can now either use `bench start` or setup the bench for production use. -@@ -162,7 +169,7 @@ Frappe Processes - * WSGI Server - - * The WSGI server is responsible for responding to the HTTP requests to -- frappe. In development scenario (`frappe --serve` or `bench start`), the -+ frappe. In development scenario (`bench serve` or `bench start`), the - Werkzeug WSGI server is used and in production, gunicorn (automatically - configured in supervisor) is used. - ---- bench/app.py.orig 2014-11-19 06:36:44 UTC -+++ bench/app.py -@@ -1,12 +1,22 @@ - import os --from .utils import exec_cmd, get_frappe, check_git_for_shallow_clone, get_config, build_assets, restart_supervisor_processes, get_cmd_output -+from .utils import exec_cmd, get_frappe, check_git_for_shallow_clone, get_config, build_assets, restart_supervisor_processes, get_cmd_output, run_frappe_cmd - - import logging - import requests -+import semantic_version - import json -+import re -+import subprocess -+ - - logger = logging.getLogger(__name__) - -+class MajorVersionUpgradeException(Exception): -+ def __init__(self, message, upstream_version, local_version): -+ super(MajorVersionUpgradeException, self).__init__(message) -+ self.upstream_version = upstream_version -+ self.local_version = local_version -+ - def get_apps(bench='.'): - try: - with open(os.path.join(bench, 'sites', 'apps.txt')) as f: -@@ -18,10 +28,19 @@ def add_to_appstxt(app, bench='.'): - apps = get_apps(bench=bench) - if app not in apps: - apps.append(app) -- with open(os.path.join(bench, 'sites', 'apps.txt'), 'w') as f: -- return f.write('\n'.join(apps)) -+ return write_appstxt(apps, bench=bench) - --def get_app(app, git_url, branch=None, bench='.'): -+def remove_from_appstxt(app, bench='.'): -+ apps = get_apps(bench=bench) -+ if app in apps: -+ apps.remove(app) -+ return write_appstxt(apps, bench=bench) -+ -+def write_appstxt(apps, bench='.'): -+ with open(os.path.join(bench, 'sites', 'apps.txt'), 'w') as f: -+ return f.write('\n'.join(apps)) -+ -+def get_app(app, git_url, branch=None, bench='.', build_asset_files=True): - logger.info('getting app {}'.format(app)) - shallow_clone = '--depth 1' if check_git_for_shallow_clone() and get_config().get('shallow_clone') else '' - branch = '--branch {branch}'.format(branch=branch) if branch else '' -@@ -33,14 +52,20 @@ def get_app(app, git_url, branch=None, b - cwd=os.path.join(bench, 'apps')) - print 'installing', app - install_app(app, bench=bench) -- build_assets(bench=bench) -+ if build_asset_files: -+ build_assets(bench=bench) - conf = get_config() - if conf.get('restart_supervisor_on_update'): - restart_supervisor_processes(bench=bench) - - def new_app(app, bench='.'): - logger.info('creating new app {}'.format(app)) -- exec_cmd("{frappe} --make_app {apps}".format(frappe=get_frappe(bench=bench), apps=os.path.join(bench, 'apps'))) -+ apps = os.path.abspath(os.path.join(bench, 'apps')) -+ if FRAPPE_VERSION == 4: -+ exec_cmd("{frappe} --make_app {apps} {app}".format(frappe=get_frappe(bench=bench), -+ apps=apps, app=app)) -+ else: -+ run_frappe_cmd('make-app', apps, app, bench=bench) - install_app(app, bench=bench) - - def install_app(app, bench='.'): -@@ -57,19 +82,112 @@ def pull_all_apps(bench='.'): - apps_dir = os.path.join(bench, 'apps') - apps = [app for app in os.listdir(apps_dir) if os.path.isdir(os.path.join(apps_dir, app))] - rebase = '--rebase' if get_config().get('rebase_on_pull') else '' -+ frappe_dir = os.path.join(apps_dir, 'frappe') -+ - for app in apps: - app_dir = os.path.join(apps_dir, app) - if os.path.exists(os.path.join(app_dir, '.git')): - logger.info('pulling {0}'.format(app)) - exec_cmd("git pull {rebase} upstream {branch}".format(rebase=rebase, branch=get_current_branch(app_dir)), cwd=app_dir) - -+def is_version_upgrade(bench='.', branch=None): -+ apps_dir = os.path.join(bench, 'apps') -+ frappe_dir = os.path.join(apps_dir, 'frappe') -+ -+ fetch_upstream(frappe_dir) -+ upstream_version = get_upstream_version(frappe_dir, branch=branch) -+ -+ if not upstream_version: -+ raise Exception("Current branch of 'frappe' not in upstream") -+ -+ local_version = get_major_version(get_current_version(frappe_dir)) -+ upstream_version = get_major_version(upstream_version) -+ -+ if upstream_version - local_version > 0: -+ return (local_version, upstream_version) -+ return False -+ -+def get_current_frappe_version(bench='.'): -+ apps_dir = os.path.join(bench, 'apps') -+ frappe_dir = os.path.join(apps_dir, 'frappe') -+ -+ try: -+ return get_major_version(get_current_version(frappe_dir)) -+ except IOError: -+ return '' -+ - def get_current_branch(repo_dir): - return get_cmd_output("basename $(git symbolic-ref -q HEAD)", cwd=repo_dir) - -+def fetch_upstream(repo_dir): -+ return exec_cmd("git fetch upstream", cwd=repo_dir) -+ -+def get_current_version(repo_dir): -+ with open(os.path.join(repo_dir, 'setup.py')) as f: -+ return get_version_from_string(f.read()) -+ -+def get_upstream_version(repo_dir, branch=None): -+ if not branch: -+ branch = get_current_branch(repo_dir) -+ try: -+ contents = subprocess.check_output(['git', 'show', 'upstream/{branch}:setup.py'.format(branch=branch)], cwd=repo_dir, stderr=subprocess.STDOUT) -+ except subprocess.CalledProcessError, e: -+ if "Invalid object" in e.output: -+ return None -+ else: -+ raise -+ return get_version_from_string(contents) -+ -+def switch_branch(branch, apps=None, bench='.', upgrade=False): -+ from .utils import update_requirements, backup_all_sites, patch_sites, build_assets, pre_upgrade, post_upgrade -+ import utils -+ apps_dir = os.path.join(bench, 'apps') -+ version_upgrade = is_version_upgrade(bench=bench, branch=branch) -+ if version_upgrade and not upgrade: -+ raise MajorVersionUpgradeException("Switching to {0} will cause upgrade from {1} to {2}. Pass --upgrade to confirm".format(branch, version_upgrade[0], version_upgrade[1]), version_upgrade[0], version_upgrade[1]) -+ -+ if not apps: -+ apps = ('frappe', 'erpnext', 'shopping_cart') -+ for app in apps: -+ app_dir = os.path.join(apps_dir, app) -+ if os.path.exists(app_dir): -+ unshallow = "--unshallow" if os.path.exists(os.path.join(app_dir, ".git", "shallow")) else "" -+ exec_cmd("git config --unset-all remote.upstream.fetch", cwd=app_dir) -+ exec_cmd("git config --add remote.upstream.fetch '+refs/heads/*:refs/remotes/upstream/*'", cwd=app_dir) -+ exec_cmd("git fetch upstream {unshallow}".format(unshallow=unshallow), cwd=app_dir) -+ exec_cmd("git checkout {branch}".format(branch=branch), cwd=app_dir) -+ exec_cmd("git merge upstream/{branch}".format(branch=branch), cwd=app_dir) -+ -+ if version_upgrade and upgrade: -+ update_requirements() -+ pre_upgrade(version_upgrade[0], version_upgrade[1]) -+ reload(utils) -+ backup_all_sites() -+ patch_sites() -+ build_assets() -+ post_upgrade(version_upgrade[0], version_upgrade[1]) -+ -+def switch_to_master(apps=None, bench='.', upgrade=False): -+ switch_branch('master', apps=apps, bench=bench, upgrade=upgrade) -+ -+def switch_to_develop(apps=None, bench='.', upgrade=False): -+ switch_branch('develop', apps=apps, bench=bench, upgrade=upgrade) -+ -+def switch_to_v4(apps=None, bench='.', upgrade=False): -+ switch_branch('v4.x.x', apps=apps, bench=bench, upgrade=upgrade) -+ -+def get_version_from_string(contents): -+ match = re.search(r"^(\s*%s\s*=\s*['\\\"])(.+?)(['\"])(?sm)" % 'version', -+ contents) -+ return match.group(2) -+ -+def get_major_version(version): -+ return semantic_version.Version(version).major -+ - def install_apps_from_path(path, bench='.'): - apps = get_apps_json(path) - for app in apps: -- get_app(app['name'], app['url'], branch=app.get('branch'), bench=bench) -+ get_app(app['name'], app['url'], branch=app.get('branch'), bench=bench, build_asset_files=False) - - def get_apps_json(path): - if path.startswith('http'): -@@ -78,3 +196,5 @@ def get_apps_json(path): - else: - with open(path) as f: - return json.load(f) -+ -+FRAPPE_VERSION = get_current_frappe_version() ---- bench/cli.py.orig 2014-11-19 06:36:44 UTC -+++ bench/cli.py -@@ -8,32 +8,54 @@ from .utils import setup_sudoers as _set - from .utils import start as _start - from .utils import setup_procfile as _setup_procfile - from .utils import set_nginx_port as _set_nginx_port --from .utils import set_nginx_port as _set_nginx_port -+from .utils import set_url_root as _set_url_root - from .utils import set_default_site as _set_default_site --from .utils import (build_assets, patch_sites, exec_cmd, update_bench, get_frappe, setup_logging, -+from .utils import (build_assets, patch_sites, exec_cmd, update_bench, get_env_cmd, get_frappe, setup_logging, - get_config, update_config, restart_supervisor_processes, put_config, default_config, update_requirements, -- backup_all_sites, backup_site, get_sites, prime_wheel_cache, is_root, set_mariadb_host, drop_privileges) -+ backup_all_sites, backup_site, get_sites, prime_wheel_cache, is_root, set_mariadb_host, drop_privileges, -+ fix_file_perms, fix_prod_setup_perms, set_ssl_certificate, set_ssl_certificate_key, get_cmd_output, post_upgrade, -+ pre_upgrade, PatchError, download_translations_p) - from .app import get_app as _get_app - from .app import new_app as _new_app --from .app import pull_all_apps --from .config import generate_nginx_config, generate_supervisor_config -+from .app import pull_all_apps, get_apps, get_current_frappe_version, is_version_upgrade, switch_to_v4, switch_to_master, switch_to_develop -+from .config import generate_nginx_config, generate_supervisor_config, generate_redis_config - from .production_setup import setup_production as _setup_production -+from .migrate_to_v5 import migrate_to_v5 - import os - import sys - import logging - import copy -+import json - import pwd - import grp -+import subprocess - - logger = logging.getLogger('bench') - -+global FRAPPE_VERSION -+ - def cli(): - check_uid() - change_dir() - change_uid() - if len(sys.argv) > 2 and sys.argv[1] == "frappe": -- return frappe() -- return bench() -+ return old_frappe_cli() -+ elif len(sys.argv) > 1 and sys.argv[1] in get_frappe_commands(): -+ return frappe_cmd() -+ elif len(sys.argv) > 1 and sys.argv[1] in ("--site", "--verbose", "--force", "--profile"): -+ return frappe_cmd() -+ elif len(sys.argv) > 1 and sys.argv[1]=="--help": -+ print click.Context(bench).get_help() -+ print -+ print get_frappe_help() -+ return -+ elif len(sys.argv) > 1 and sys.argv[1] in get_apps(): -+ return app_cmd() -+ else: -+ try: -+ bench() -+ except PatchError: -+ sys.exit(1) - - def cmd_requires_root(): - if len(sys.argv) > 2 and sys.argv[2] in ('production', 'sudoers'): -@@ -57,17 +79,51 @@ def change_uid(): - sys.exit(1) - - def change_dir(): -+ if os.path.exists('config.json') or "init" in sys.argv: -+ return - dir_path_file = '/etc/frappe_bench_dir' - if os.path.exists(dir_path_file): - with open(dir_path_file) as f: - dir_path = f.read().strip() -- os.chdir(dir_path) -+ if os.path.exists(dir_path): -+ os.chdir(dir_path) - --def frappe(bench='.'): -+def old_frappe_cli(bench='.'): - f = get_frappe(bench=bench) - os.chdir(os.path.join(bench, 'sites')) - os.execv(f, [f] + sys.argv[2:]) - -+def app_cmd(bench='.'): -+ f = get_env_cmd('python', bench=bench) -+ os.chdir(os.path.join(bench, 'sites')) -+ os.execv(f, [f] + ['-m', 'frappe.utils.bench_helper'] + sys.argv[1:]) -+ -+def frappe_cmd(bench='.'): -+ f = get_env_cmd('python', bench=bench) -+ os.chdir(os.path.join(bench, 'sites')) -+ os.execv(f, [f] + ['-m', 'frappe.utils.bench_helper', 'frappe'] + sys.argv[1:]) -+ -+def get_frappe_commands(bench='.'): -+ python = get_env_cmd('python', bench=bench) -+ sites_path = os.path.join(bench, 'sites') -+ if not os.path.exists(sites_path): -+ return [] -+ try: -+ return json.loads(get_cmd_output("{python} -m frappe.utils.bench_helper get-frappe-commands".format(python=python), cwd=sites_path)) -+ except subprocess.CalledProcessError: -+ return [] -+ -+def get_frappe_help(bench='.'): -+ python = get_env_cmd('python', bench=bench) -+ sites_path = os.path.join(bench, 'sites') -+ if not os.path.exists(sites_path): -+ return [] -+ try: -+ out = get_cmd_output("{python} -m frappe.utils.bench_helper get-frappe-help".format(python=python), cwd=sites_path) -+ return "Framework commands:\n" + out.split('Commands:')[1] -+ except subprocess.CalledProcessError: -+ return "" -+ - @click.command() - def shell(bench='.'): - if not os.environ.get('SHELL'): -@@ -86,6 +142,8 @@ def shell(bench='.'): - def bench(bench='.'): - "Bench manager for Frappe" - # TODO add bench path context -+ global FRAPPE_VERSION -+ FRAPPE_VERSION = get_current_frappe_version() - setup_logging(bench=bench) - - @click.command() -@@ -134,8 +192,9 @@ def new_site(site, mariadb_root_password - @click.option('--requirements',flag_value=True, type=bool, help="Update requirements") - @click.option('--restart-supervisor',flag_value=True, type=bool, help="restart supervisor processes after update") - @click.option('--auto',flag_value=True, type=bool) -+@click.option('--upgrade',flag_value=True, type=bool) - @click.option('--no-backup',flag_value=True, type=bool) --def update(pull=False, patch=False, build=False, bench=False, auto=False, restart_supervisor=False, requirements=False, no_backup=False): -+def update(pull=False, patch=False, build=False, bench=False, auto=False, restart_supervisor=False, requirements=False, no_backup=False, upgrade=False): - "Update bench" - - if not (pull or patch or build or bench or requirements): -@@ -155,12 +214,36 @@ def update(pull=False, patch=False, buil - 'build': build, - 'requirements': requirements, - 'no-backup': no_backup, -- 'restart-supervisor': restart_supervisor -+ 'restart-supervisor': restart_supervisor, -+ 'upgrade': upgrade - }) -+ -+ version_upgrade = is_version_upgrade() -+ -+ if version_upgrade and not upgrade: -+ print -+ print -+ print "This update will cause a major version change in Frappe/ERPNext from {0} to {1} (beta).".format(*version_upgrade) -+ print "This would take significant time to migrate and might break custom apps. Please run `bench update --upgrade` to confirm." -+ print -+ # print "You can also pin your bench to {0} by running `bench swtich-to-v{0}`".format(version_upgrade[0]) -+ print "You can stay on the latest stable release by running `bench switch-to-master` or pin your bench to {0} by running `bench swtich-to-v{0}`".format(version_upgrade[0]) -+ sys.exit(1) -+ elif not version_upgrade and upgrade: -+ upgrade = False -+ - if pull: - pull_all_apps() -+ - if requirements: - update_requirements() -+ -+ if upgrade: -+ pre_upgrade(version_upgrade[0], version_upgrade[1]) -+ import utils, app -+ reload(utils) -+ reload(app) -+ - if patch: - if not no_backup: - backup_all_sites() -@@ -169,14 +252,23 @@ def update(pull=False, patch=False, buil - build_assets() - if restart_supervisor or conf.get('restart_supervisor_on_update'): - restart_supervisor_processes() -+ if upgrade: -+ post_upgrade(version_upgrade[0], version_upgrade[1]) - - print "_"*80 - print "https://frappe.io/buy - Donate to help make better free and open source tools" - print - -+@click.command('retry-upgrade') -+@click.option('--version', default=5) -+def retry_upgrade(version): -+ pull_all_apps() -+ patch_sites() -+ build_assets() -+ post_upgrade(version-1, version) -+ - def restart_update(kwargs): - args = ['--'+k for k, v in kwargs.items() if v] -- print 'restarting ' - os.execv(sys.argv[0], sys.argv[:2] + args) - - @click.command('restart') -@@ -198,6 +290,33 @@ def migrate_3to4(path): - migrate_3to4=os.path.join(os.path.dirname(__file__), 'migrate3to4.py'), - site=path)) - -+@click.command('switch-to-master') -+@click.option('--upgrade',flag_value=True, type=bool) -+def _switch_to_master(upgrade=False): -+ "Switch frappe and erpnext to master branch" -+ switch_to_master(upgrade=upgrade) -+ print -+ print 'Switched to master' -+ print 'Please run `bench update --patch` to be safe from any differences in database schema' -+ -+@click.command('switch-to-develop') -+@click.option('--upgrade',flag_value=True, type=bool) -+def _switch_to_develop(upgrade=False): -+ "Switch frappe and erpnext to develop branch" -+ switch_to_develop(upgrade=upgrade) -+ print -+ print 'Switched to develop' -+ print 'Please run `bench update --patch` to be safe from any differences in database schema' -+ -+@click.command('switch-to-v4') -+@click.option('--upgrade',flag_value=True, type=bool) -+def _switch_to_v4(upgrade=False): -+ "Switch frappe and erpnext to v4 branch" -+ switch_to_v4(upgrade=upgrade) -+ print -+ print 'Switched to v4' -+ print 'Please run `bench update --patch` to be safe from any differences in database schema' -+ - @click.command('set-nginx-port') - @click.argument('site') - @click.argument('port', type=int) -@@ -205,6 +324,27 @@ def set_nginx_port(site, port): - "Set nginx port for site" - _set_nginx_port(site, port) - -+@click.command('set-ssl-certificate') -+@click.argument('site') -+@click.argument('ssl-certificate-path') -+def _set_ssl_certificate(site, ssl_certificate_path): -+ "Set ssl certificate path for site" -+ set_ssl_certificate(site, ssl_certificate_path) -+ -+@click.command('set-ssl-key') -+@click.argument('site') -+@click.argument('ssl-certificate-key-path') -+def _set_ssl_certificate_key(site, ssl_certificate_key_path): -+ "Set ssl certificate private key path for site" -+ set_ssl_certificate_key(site, ssl_certificate_key_path) -+ -+@click.command('set-url-root') -+@click.argument('site') -+@click.argument('url-root') -+def set_url_root(site, url_root): -+ "Set url root for site" -+ _set_url_root(site, url_root) -+ - @click.command('set-mariadb-host') - @click.argument('host') - def _set_mariadb_host(host): -@@ -239,11 +379,13 @@ def _prime_wheel_cache(): - @click.command('release') - @click.argument('app', type=click.Choice(['frappe', 'erpnext', 'shopping_cart'])) - @click.argument('bump-type', type=click.Choice(['major', 'minor', 'patch'])) --def _release(app, bump_type): -+@click.option('--develop', default='develop') -+@click.option('--master', default='master') -+def _release(app, bump_type, develop, master): - "Release app (internal to the Frappe team)" - from .release import release - repo = os.path.join('apps', app) -- release(repo, bump_type) -+ release(repo, bump_type, develop, master) - - ## Setup - @click.group() -@@ -267,6 +409,11 @@ def setup_supervisor(): - "generate config for supervisor" - generate_supervisor_config() - -+@click.command('redis-cache') -+def setup_redis_cache(): -+ "generate config for redis cache" -+ generate_redis_config() -+ - @click.command('production') - @click.argument('user') - def setup_production(user): -@@ -305,6 +452,7 @@ def setup_config(): - setup.add_command(setup_nginx) - setup.add_command(setup_sudoers) - setup.add_command(setup_supervisor) -+setup.add_command(setup_redis_cache) - setup.add_command(setup_auto_update) - setup.add_command(setup_dnsmasq) - setup.add_command(setup_backups) -@@ -380,40 +528,32 @@ config.add_command(config_http_timeout) - def patch(): - pass - --@click.command('fix-perms') --def _fix_perms(): -+@click.command('fix-prod-perms') -+def _fix_prod_perms(): -+ "Fix permissions if supervisor processes were run as root" - if os.path.exists("config/supervisor.conf"): - exec_cmd("supervisorctl stop frappe:") - -- "Fix permissions if supervisor processes were run as root" -- files = [ -- "logs/web.error.log", -- "logs/web.log", -- "logs/workerbeat.error.log", -- "logs/workerbeat.log", -- "logs/worker.error.log", -- "logs/worker.log", -- "config/nginx.conf", -- "config/supervisor.conf", -- ] -- -- frappe_user = get_config().get('frappe_user') -- if not frappe_user: -- print "frappe user not set" -- sys.exit(1) -- -- for path in files: -- if os.path.exists(path): -- uid = pwd.getpwnam(frappe_user).pw_uid -- gid = grp.getgrnam(frappe_user).gr_gid -- os.chown(path, uid, gid) -+ fix_prod_setup_perms() - - if os.path.exists("config/supervisor.conf"): - exec_cmd("{bench} setup supervisor".format(bench=sys.argv[0])) - exec_cmd("supervisorctl reload") - - --patch.add_command(_fix_perms) -+@click.command('fix-file-perms') -+def _fix_file_perms(): -+ "Fix file permissions" -+ fix_file_perms() -+ -+patch.add_command(_fix_file_perms) -+patch.add_command(_fix_prod_perms) -+ -+ -+@click.command('download-translations') -+def _download_translations(): -+ "Download latest translations" -+ download_translations_p() - - #Bench commands - -@@ -427,12 +567,20 @@ bench.add_command(restart) - bench.add_command(config) - bench.add_command(start) - bench.add_command(set_nginx_port) -+bench.add_command(_set_ssl_certificate) -+bench.add_command(_set_ssl_certificate_key) - bench.add_command(_set_mariadb_host) - bench.add_command(set_default_site) - bench.add_command(migrate_3to4) -+bench.add_command(_switch_to_master) -+bench.add_command(_switch_to_develop) -+bench.add_command(_switch_to_v4) - bench.add_command(shell) - bench.add_command(_backup_all_sites) - bench.add_command(_backup_site) - bench.add_command(_prime_wheel_cache) - bench.add_command(_release) - bench.add_command(patch) -+bench.add_command(set_url_root) -+bench.add_command(retry_upgrade) -+bench.add_command(_download_translations) ---- bench/config.py.orig 2014-11-19 06:36:44 UTC -+++ bench/config.py -@@ -1,12 +1,27 @@ - import os - import getpass - import json -+import subprocess -+import shutil - from jinja2 import Environment, PackageLoader --from .utils import get_sites, get_config, update_config -+from .utils import get_sites, get_config, update_config, get_redis_version - - env = Environment(loader=PackageLoader('bench', 'templates'), trim_blocks=True) - -+def write_config_file(bench, file_name, config): -+ config_path = os.path.join(bench, 'config') -+ file_path = os.path.join(config_path, file_name) -+ number = (len([path for path in os.listdir(config_path) if path.startswith(file_name)]) -1 ) or '' -+ if number: -+ number = '.' + str(number) -+ if os.path.exists(file_path): -+ shutil.move(file_path, file_path + '.save' + number) -+ -+ with open(file_path, 'wb') as f: -+ f.write(config) -+ - def generate_supervisor_config(bench='.', user=None): -+ from .app import get_current_frappe_version - template = env.get_template('supervisor.conf') - bench_dir = os.path.abspath(bench) - sites_dir = os.path.join(bench_dir, "sites") -@@ -20,9 +35,11 @@ def generate_supervisor_config(bench='.' - "sites_dir": sites_dir, - "user": user, - "http_timeout": config.get("http_timeout", 120), -+ "redis_server": subprocess.check_output('which redis-server', shell=True).strip(), -+ "redis_config": os.path.join(bench_dir, 'config', 'redis.conf'), -+ "frappe_version": get_current_frappe_version() - }) -- with open("config/supervisor.conf", 'w') as f: -- f.write(config) -+ write_config_file(bench, 'supervisor.conf', config) - update_config({'restart_supervisor_on_update': True}) - - def get_site_config(site, bench='.'): -@@ -31,10 +48,16 @@ def get_site_config(site, bench='.'): - - def get_sites_with_config(bench='.'): - sites = get_sites() -- return [{ -- "name": site, -- "port": get_site_config(site, bench=bench).get('nginx_port') -- } for site in sites] -+ ret = [] -+ for site in sites: -+ site_config = get_site_config(site, bench=bench) -+ ret.append({ -+ "name": site, -+ "port": site_config.get('nginx_port'), -+ "ssl_certificate": site_config.get('ssl_certificate'), -+ "ssl_certificate_key": site_config.get('ssl_certificate_key') -+ }) -+ return ret - - def generate_nginx_config(bench='.'): - template = env.get_template('nginx.conf') -@@ -59,5 +82,14 @@ def generate_nginx_config(bench='.'): - "dns_multitenant": get_config().get('dns_multitenant'), - "sites": sites - }) -- with open("config/nginx.conf", 'w') as f: -- f.write(config) -+ write_config_file(bench, 'nginx.conf', config) -+ -+def generate_redis_config(bench='.'): -+ template = env.get_template('redis.conf') -+ conf = { -+ "maxmemory": get_config().get('cache_maxmemory', '50'), -+ "port": get_config().get('redis_cache_port', '11311'), -+ "redis_version": get_redis_version() -+ } -+ config = template.render(**conf) -+ write_config_file(bench, 'redis.conf', config) ---- bench/migrate_to_v5.py.orig 2015-07-31 10:19:27 UTC -+++ bench/migrate_to_v5.py -@@ -0,0 +1,46 @@ -+from .utils import exec_cmd, get_frappe, run_frappe_cmd -+from .release import get_current_version -+from .app import remove_from_appstxt -+import os -+import shutil -+import sys -+ -+repos = ('frappe', 'erpnext') -+ -+def migrate_to_v5(bench='.'): -+ validate_v4(bench=bench) -+ for repo in repos: -+ checkout_v5(repo, bench=bench) -+ remove_shopping_cart(bench=bench) -+ exec_cmd("{bench} update".format(bench=sys.argv[0])) -+ -+def remove_shopping_cart(bench='.'): -+ archived_apps_dir = os.path.join(bench, 'archived_apps') -+ shopping_cart_dir = os.path.join(bench, 'apps', 'shopping_cart') -+ -+ if not os.path.exists(shopping_cart_dir): -+ return -+ -+ run_frappe_cmd('--site', 'all', 'remove-from-installed-apps', 'shopping_cart', bench=bench) -+ remove_from_appstxt('shopping_cart', bench=bench) -+ exec_cmd("{pip} --no-input uninstall -y shopping_cart".format(pip=os.path.join(bench, 'env', 'bin', 'pip'))) -+ -+ if not os.path.exists(archived_apps_dir): -+ os.mkdir(archived_apps_dir) -+ shutil.move(shopping_cart_dir, archived_apps_dir) -+ -+def validate_v4(bench='.'): -+ for repo in repos: -+ path = os.path.join(bench, 'apps', repo) -+ if os.path.exists(path): -+ current_version = get_current_version(path) -+ if not current_version.startswith('4'): -+ raise Exception("{} is not on v4.x.x".format(repo)) -+ -+def checkout_v5(repo, bench='.'): -+ cwd = os.path.join(bench, 'apps', repo) -+ if os.path.exists(cwd): -+ exec_cmd("git fetch upstream", cwd=cwd) -+ exec_cmd("git checkout v5.0", cwd=cwd) -+ exec_cmd("git clean -df", cwd=cwd) -+ ---- bench/production_setup.py.orig 2014-11-19 06:36:44 UTC -+++ bench/production_setup.py -@@ -1,17 +1,16 @@ --from .utils import get_program, exec_cmd, get_cmd_output -+from .utils import get_program, exec_cmd, get_cmd_output, fix_prod_setup_perms - from .config import generate_nginx_config, generate_supervisor_config - from jinja2 import Environment, PackageLoader - import os - import shutil - - def restart_service(service): -- program = get_program(['systemctl', 'service']) -- if not program: -+ if os.path.basename(get_program(['systemctl']) or '') == 'systemctl' and is_running_systemd(): -+ exec_cmd("{prog} restart {service}".format(prog='systemctl', service=service)) -+ elif os.path.basename(get_program(['service']) or '') == 'service': -+ exec_cmd("{prog} {service} restart ".format(prog='service', service=service)) -+ else: - raise Exception, 'No service manager found' -- elif os.path.basename(program) == 'systemctl': -- exec_cmd("{prog} restart {service}".format(prog=program, service=service)) -- elif os.path.basename(program) == 'service': -- exec_cmd("{prog} {service} restart ".format(prog=program, service=service)) - - def get_supervisor_confdir(): - possiblities = ('/etc/supervisor/conf.d', '/etc/supervisor.d/', '/etc/supervisord/conf.d', '/etc/supervisord.d') -@@ -30,6 +29,14 @@ def remove_default_nginx_configs(): - def is_centos7(): - return os.path.exists('/etc/redhat-release') and get_cmd_output("cat /etc/redhat-release | sed 's/Linux\ //g' | cut -d' ' -f3 | cut -d. -f1").strip() == '7' - -+def is_running_systemd(): -+ with open('/proc/1/comm') as f: -+ comm = f.read().strip() -+ if comm == "init": -+ return False -+ elif comm == "systemd": -+ return True -+ return False - - def copy_default_nginx_config(): - shutil.copy(os.path.join(os.path.dirname(__file__), 'templates', 'nginx_default.conf'), '/etc/nginx/nginx.conf') -@@ -37,6 +44,7 @@ def copy_default_nginx_config(): - def setup_production(user, bench='.'): - generate_supervisor_config(bench=bench, user=user) - generate_nginx_config(bench=bench) -+ fix_prod_setup_perms(frappe_user=user) - remove_default_nginx_configs() - - if is_centos7(): ---- bench/release.py.orig 2014-11-19 06:36:44 UTC -+++ bench/release.py -@@ -34,10 +34,10 @@ def create_release(repo_path, version, r - g.merge(master_branch) - return tag_name - --def push_release(repo_path): -+def push_release(repo_path, develop_branch='develop', master_branch='master'): - repo = git.Repo(repo_path) - g = repo.git -- print g.push('upstream', 'master:master', 'develop:develop', '--tags') -+ print g.push('upstream', '{master}:{master}'.format(master=master_branch), '{develop}:{develop}'.format(develop=develop_branch), '--tags') - - def create_github_release(owner, repo, tag_name, log, gh_username=None, gh_password=None): - global github_username, github_password -@@ -137,25 +137,40 @@ def get_current_version(repo): - contents) - return match.group(2) - --def bump_repo(repo, bump_type): -- update_branch(repo, 'master', remote='upstream') -- update_branch(repo, 'develop', remote='upstream') -- git.Repo(repo).git.checkout('develop') -- current_version = get_current_version(repo) -- new_version = get_bumped_version(current_version, bump_type) -- set_version(repo, new_version) -- return new_version -+def check_for_unmerged_changelog(repo): -+ current = os.path.join(repo, os.path.basename(repo), 'change_log', 'current') -+ if os.path.exists(current) and [f for f in os.listdir(current) if f != "readme.md"]: -+ raise Exception("Unmerged change log! in " + repo) - --def bump(repo, bump_type): -+def bump_repo(repo, bump_type, develop='develop', master='master', remote='upstream'): -+ update_branch(repo, master, remote=remote) -+ update_branch(repo, develop, remote=remote) -+ git.Repo(repo).git.checkout(develop) -+ check_for_unmerged_changelog(repo) -+ current_version = get_current_version(repo) -+ new_version = get_bumped_version(current_version, bump_type) -+ set_version(repo, new_version) -+ return new_version -+ -+def get_release_message(repo_path, develop_branch='develop', master_branch='master'): -+ repo = git.Repo(repo_path) -+ g = repo.git -+ return "* " + g.log('upstream/{master_branch}..upstream/{develop_branch}'.format(master_branch=master_branch, develop_branch=develop_branch), '--format=format:%s', '--no-merges').replace('\n', '\n* ') -+ -+def bump(repo, bump_type, develop='develop', master='master', remote='upstream'): - assert bump_type in ['minor', 'major', 'patch'] -- new_version = bump_repo(repo, bump_type) -+ new_version = bump_repo(repo, bump_type, develop=develop, master=master, remote=remote) -+ message = get_release_message(repo, develop_branch=develop, master_branch=master) -+ print -+ print message -+ print - commit_changes(repo, new_version) -- tag_name = create_release(repo, new_version) -- push_release(repo) -- create_github_release('frappe', repo, tag_name, '') -+ tag_name = create_release(repo, new_version, develop_branch=develop, master_branch=master) -+ push_release(repo, develop_branch=develop, master_branch=master) -+ create_github_release('frappe', repo, tag_name, message) - print 'Released {tag} for {repo}'.format(tag=tag_name, repo=repo) - --def release(repo, bump_type): -+def release(repo, bump_type, develop, master): - if not get_config().get('release_bench'): - print 'bench not configured to release' - sys.exit(1) -@@ -164,7 +179,7 @@ def release(repo, bump_type): - github_password = getpass.getpass() - r = requests.get('https://api.github.com/user', auth=HTTPBasicAuth(github_username, github_password)) - r.raise_for_status() -- bump(repo, bump_type) -+ bump(repo, bump_type, develop=develop, master=master) - - if __name__ == "__main__": - main() ---- bench/templates/nginx.conf.orig 2014-11-19 06:36:44 UTC -+++ bench/templates/nginx.conf -@@ -5,15 +5,7 @@ upstream frappe { - server 127.0.0.1:8000 fail_timeout=0; - } - --{% macro server_block(site, port=80, default=False, server_name=None, sites=None, dns_multitenant=False) -%} -- server { -- listen {{ site.port if not default and site.port else port }} {% if default %} default {% endif %}; -- client_max_body_size 4G; -- {% if dns_multitenant and sites %} -- server_name {% for site in sites %} {{ site.name }} {% endfor %}; -- {% else %} -- server_name {{ site.name if not server_name else server_name }}; -- {% endif %} -+{% macro location_block(site, port=80, default=False, server_name=None, sites=None, dns_multitenant=False) -%} - keepalive_timeout 5; - sendfile on; - root {{ sites_dir }}; -@@ -34,30 +26,66 @@ upstream frappe { - location @magic { - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - {% if not dns_multitenant %} -- proxy_set_header Host {{ site.name }}; -- {% else %} -- proxy_set_header Host $host; -+ proxy_set_header X-Frappe-Site-Name {{ site.name }}; - {% endif %} -+ proxy_set_header Host $host; - proxy_set_header X-Use-X-Accel-Redirect True; - proxy_read_timeout {{http_timeout}}; - proxy_redirect off; - proxy_pass http://frappe; - } -+{%- endmacro %} -+ -+{% macro server_name_block(site, default=False, server_name=None, sites=None, dns_multitenant=False) -%} -+ client_max_body_size 4G; -+ {% if dns_multitenant and sites %} -+ server_name {% for site in sites %} {{ site.name }} {% endfor %}; -+ {% else %} -+ server_name {{ site.name if not server_name else server_name }}; -+ {% endif %} -+{%- endmacro %} -+ -+{% macro server_block_http(site, port=80, default=False, server_name=None, sites=None, dns_multitenant=False) -%} -+ server { -+ listen {{ site.port if not default and site.port else port }} {% if default %} default {% endif %}; -+ {{ server_name_block(site, default=default, server_name=server_name, sites=sites, dns_multitenant=dns_multitenant) }} -+ {{ location_block(site, port=port, default=default, server_name=server_name, sites=sites, dns_multitenant=dns_multitenant) }} -+ } -+{%- endmacro %} -+ -+{% macro server_block_https(site, port=443, default=False, server_name=None, sites=None, dns_multitenant=False) -%} -+ server { -+ listen {{ site.ssl_port if not default and site.ssl_port else port }} {% if default %} default {% endif %}; -+ {{ server_name_block(site, default=default, server_name=server_name, sites=sites, dns_multitenant=dns_multitenant) }} -+ -+ ssl on; -+ ssl_certificate {{ site.ssl_certificate }}; -+ ssl_certificate_key {{ site.ssl_certificate_key }}; -+ ssl_session_timeout 5m; -+ ssl_protocols TLSv1 TLSv1.1 TLSv1.2; -+ ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"; -+ ssl_prefer_server_ciphers on; -+ -+ {{ location_block(site, port=port, default=default, server_name=server_name, sites=sites, dns_multitenant=dns_multitenant) }} - } - {%- endmacro %} - - {% for site in sites %} - - {% if site.port %} --{{ server_block(site) }} -+{{ server_block_http(site) }} -+{% endif %} -+ -+{% if site.ssl_certificate_key and site.ssl_certificate %} -+{{ server_block_https(site) }} - {% endif %} - - {% endfor %} - - {% if default_site %} --{{ server_block(default_site, default=True, server_name="frappe_default_site") }} -+{{ server_block_http(default_site, default=True, server_name="frappe_default_site") }} - {% endif %} - - {% if dns_multitenant and sites %} --{{ server_block(None, default=False, sites=sites, dns_multitenant=True) }} -+{{ server_block_http(None, default=False, sites=sites, dns_multitenant=True) }} - {% endif %} ---- bench/templates/redis.conf.orig 2015-07-31 10:19:27 UTC -+++ bench/templates/redis.conf -@@ -0,0 +1,72 @@ -+activerehashing yes -+appendfsync everysec -+appendonly no -+auto-aof-rewrite-min-size 64mb -+auto-aof-rewrite-percentage 100 -+daemonize no -+databases 16 -+dbfilename dump.rdb -+list-max-ziplist-entries 512 -+list-max-ziplist-value 64 -+no-appendfsync-on-rewrite no -+pidfile /var/run/redis.pid -+port {{port}} -+rdbcompression yes -+set-max-intset-entries 512 -+slave-serve-stale-data yes -+slowlog-log-slower-than 10000 -+slowlog-max-len 128 -+timeout 0 -+zset-max-ziplist-entries 128 -+zset-max-ziplist-value 64 -+ -+maxmemory {{maxmemory}}mb -+maxmemory-policy allkeys-lru -+ -+{% if redis_version == "2.4"%} -+hash-max-zipmap-entries 512 -+hash-max-zipmap-value 64 -+loglevel verbose -+vm-enabled no -+vm-max-memory 0 -+vm-max-threads 4 -+vm-page-size 32 -+vm-pages 134217728 -+vm-swap-file /tmp/redis.swap -+{% endif %} -+ -+{% if redis_version == "2.6"%} -+aof-rewrite-incremental-fsync yes -+client-output-buffer-limit normal 0 0 0 -+client-output-buffer-limit pubsub 32mb 8mb 60 -+client-output-buffer-limit slave 256mb 64mb 60 -+hash-max-ziplist-entries 512 -+hash-max-ziplist-value 64 -+hz 10 -+loglevel notice -+lua-time-limit 5000 -+rdbchecksum yes -+repl-disable-tcp-nodelay no -+slave-read-only yes -+stop-writes-on-bgsave-error yes -+tcp-keepalive 0 -+{% endif %} -+ -+{% if redis_version == "2.8"%} -+aof-rewrite-incremental-fsync yes -+appendfilename "appendonly.aof" -+client-output-buffer-limit normal 0 0 0 -+client-output-buffer-limit pubsub 32mb 8mb 60 -+client-output-buffer-limit slave 256mb 64mb 60 -+hash-max-ziplist-entries 512 -+hash-max-ziplist-value 64 -+hz 10 -+logfile "" -+loglevel notice -+lua-time-limit 5000 -+notify-keyspace-events "" -+rdbchecksum yes -+slave-read-only yes -+stop-writes-on-bgsave-error yes -+tcp-keepalive 0 -+{% endif %} ---- bench/templates/supervisor.conf.orig 2014-11-19 06:36:44 UTC -+++ bench/templates/supervisor.conf -@@ -28,5 +28,18 @@ stderr_logfile={{ bench_dir }}/logs/work - user={{ user }} - directory={{ sites_dir }} - -+ -+{% if frappe_version > 4%} -+[program:redis-cache] -+command={{ redis_server }} {{ redis_config }} -+autostart=true -+autorestart=true -+stopsignal=QUIT -+stdout_logfile={{ bench_dir }}/logs/redis.log -+stderr_logfile={{ bench_dir }}/logs/redis.error.log -+user={{ user }} -+directory={{ sites_dir }} -+{% endif %} -+ - [group:frappe] - programs=frappe-web,frappe-worker,frappe-workerbeat ---- bench/utils.py.orig 2014-11-19 06:36:44 UTC -+++ bench/utils.py -@@ -1,14 +1,24 @@ - import os -+import re - import sys - import subprocess - import getpass - import logging -+import itertools -+import requests - import json -+import platform -+import multiprocessing - from distutils.spawn import find_executable - import pwd, grp - -+ -+class PatchError(Exception): -+ pass -+ - logger = logging.getLogger(__name__) - -+ - default_config = { - 'restart_supervisor_on_update': False, - 'auto_update': False, -@@ -20,15 +30,20 @@ default_config = { - } - - def get_frappe(bench='.'): -- frappe = os.path.abspath(os.path.join(bench, 'env', 'bin', 'frappe')) -+ frappe = get_env_cmd('frappe', bench=bench) - if not os.path.exists(frappe): - print 'frappe app is not installed. Run the following command to install frappe' - print 'bench get-app frappe https://github.com/frappe/frappe.git' - return frappe - -+def get_env_cmd(cmd, bench='.'): -+ return os.path.abspath(os.path.join(bench, 'env', 'bin', cmd)) -+ - def init(path, apps_path=None, no_procfile=False, no_backups=False, - no_auto_update=False, frappe_path=None, frappe_branch=None, wheel_cache_dir=None): - from .app import get_app, install_apps_from_path -+ from .config import generate_redis_config -+ global FRAPPE_VERSION - if os.path.exists(path): - print 'Directory {} already exists!'.format(path) - sys.exit(1) -@@ -44,9 +59,10 @@ def init(path, apps_path=None, no_procfi - if wheel_cache_dir: - update_config({"wheel_cache_dir":wheel_cache_dir}, bench=path) - prime_wheel_cache(bench=path) -+ - if not frappe_path: - frappe_path = 'https://github.com/frappe/frappe.git' -- get_app('frappe', frappe_path, branch=frappe_branch, bench=path) -+ get_app('frappe', frappe_path, branch=frappe_branch, bench=path, build_asset_files=False) - if not no_procfile: - setup_procfile(bench=path) - if not no_backups: -@@ -55,6 +71,9 @@ def init(path, apps_path=None, no_procfi - setup_auto_update(bench=path) - if apps_path: - install_apps_from_path(apps_path, bench=path) -+ FRAPPE_VERSION = get_current_frappe_version(bench=path) -+ build_assets(bench=path) -+ generate_redis_config(bench=path) - - def exec_cmd(cmd, cwd='.'): - try: -@@ -69,18 +88,31 @@ def setup_env(bench='.'): - exec_cmd('./env/bin/pip -q install https://github.com/frappe/MySQLdb1/archive/MySQLdb-1.2.5-patched.tar.gz', cwd=bench) - - def setup_procfile(bench='.'): -+ from .app import get_current_frappe_version -+ frappe_version = get_current_frappe_version() -+ procfile_contents = { -+ 'web': "./env/bin/frappe --serve --sites_path sites", -+ 'worker': "sh -c 'cd sites && exec ../env/bin/python -m frappe.celery_app worker'", -+ 'workerbeat': "sh -c 'cd sites && exec ../env/bin/python -m frappe.celery_app beat -s scheduler.schedule'" -+ } -+ if frappe_version > 4: -+ procfile_contents['redis_cache'] = "redis-server config/redis.conf" -+ procfile_contents['web'] = "bench serve" -+ -+ procfile = '\n'.join(["{0}: {1}".format(k, v) for k, v in procfile_contents.items()]) -+ - with open(os.path.join(bench, 'Procfile'), 'w') as f: -- f.write("""web: ./env/bin/frappe --serve --sites_path sites --worker: sh -c 'cd sites && exec ../env/bin/python -m frappe.celery_app worker' --workerbeat: sh -c 'cd sites && exec ../env/bin/python -m frappe.celery_app beat -s scheduler.schedule'""") -+ f.write(procfile) - - def new_site(site, mariadb_root_password=None, admin_password=None, bench='.'): -+ import hashlib - logger.info('creating new site {}'.format(site)) - mariadb_root_password_fragment = '--root_password {}'.format(mariadb_root_password) if mariadb_root_password else '' - admin_password_fragment = '--admin_password {}'.format(admin_password) if admin_password else '' -- exec_cmd("{frappe} --install {site} {site} {mariadb_root_password_fragment} {admin_password_fragment}".format( -+ exec_cmd("{frappe} {site} --install {db_name} {mariadb_root_password_fragment} {admin_password_fragment}".format( - frappe=get_frappe(bench=bench), - site=site, -+ db_name = hashlib.sha1(site).hexdigest()[:10], - mariadb_root_password_fragment=mariadb_root_password_fragment, - admin_password_fragment=admin_password_fragment - ), cwd=os.path.join(bench, 'sites')) -@@ -88,14 +120,23 @@ def new_site(site, mariadb_root_password - exec_cmd("{frappe} --use {site}".format(frappe=get_frappe(bench=bench), site=site), cwd=os.path.join(bench, 'sites')) - - def patch_sites(bench='.'): -- exec_cmd("{frappe} --latest all".format(frappe=get_frappe(bench=bench)), cwd=os.path.join(bench, 'sites')) -+ try: -+ if FRAPPE_VERSION == 4: -+ exec_cmd("{frappe} --latest all".format(frappe=get_frappe(bench=bench)), cwd=os.path.join(bench, 'sites')) -+ else: -+ run_frappe_cmd('--site', 'all', 'migrate', bench=bench) -+ except subprocess.CalledProcessError: -+ raise PatchError - - def build_assets(bench='.'): -- exec_cmd("{frappe} --build".format(frappe=get_frappe(bench=bench)), cwd=os.path.join(bench, 'sites')) -+ if FRAPPE_VERSION == 4: -+ exec_cmd("{frappe} --build".format(frappe=get_frappe(bench=bench)), cwd=os.path.join(bench, 'sites')) -+ else: -+ run_frappe_cmd('build', bench=bench) - - def get_sites(bench='.'): - sites_dir = os.path.join(bench, "sites") -- sites = [site for site in os.listdir(sites_dir) -+ sites = [site for site in os.listdir(sites_dir) - if os.path.isdir(os.path.join(sites_dir, site)) and site not in ('assets',)] - return sites - -@@ -115,14 +156,22 @@ def setup_auto_update(bench='.'): - - def setup_backups(bench='.'): - logger.info('setting up backups') -- add_to_crontab('0 */6 * * * cd {sites_dir} && {frappe} --backup all >> {logfile} 2>&1'.format(sites_dir=get_sites_dir(bench=bench), -- frappe=get_frappe(bench=bench), -+ bench_dir = get_bench_dir(bench=bench) -+ if FRAPPE_VERSION == 4: -+ backup_command = "cd {sites_dir} && {frappe} --backup all".format(frappe=get_frappe(bench=bench),) -+ else: -+ backup_command = "cd {bench_dir} && {bench} --site all backup".format(bench_dir=bench_dir, bench=sys.argv[0]) -+ -+ add_to_crontab('0 */6 * * * {backup_command} >> {logfile} 2>&1'.format(backup_command=backup_command, - logfile=os.path.join(get_bench_dir(bench=bench), 'logs', 'backup.log'))) - - def add_to_crontab(line): - current_crontab = read_crontab() - if not line in current_crontab: -- s = subprocess.Popen("crontab", stdin=subprocess.PIPE) -+ cmd = ["crontab"] -+ if platform.system() == 'FreeBSD': -+ cmd = ["crontab", "-"] -+ s = subprocess.Popen(cmd, stdin=subprocess.PIPE) - s.stdin.write(current_crontab) - s.stdin.write(line + '\n') - s.stdin.close() -@@ -182,11 +231,12 @@ def get_program(programs): - - def get_process_manager(): - return get_program(['foreman', 'forego', 'honcho']) -- -+ - def start(): - program = get_process_manager() - if not program: - raise Exception("No process manager found") -+ os.environ['PYTHONUNBUFFERED'] = "true" - os.execv(program, [program, 'start']) - - def check_cmd(cmd, cwd='.'): -@@ -208,9 +258,10 @@ def check_git_for_shallow_clone(): - - def get_cmd_output(cmd, cwd='.'): - try: -- return subprocess.check_output(cmd, cwd=cwd, shell=True) -+ return subprocess.check_output(cmd, cwd=cwd, shell=True, stderr=open(os.devnull, 'wb')).strip() - except subprocess.CalledProcessError, e: -- print "Error:", e.output -+ if e.output: -+ print e.output - raise - - def restart_supervisor_processes(bench='.'): -@@ -236,13 +287,28 @@ def update_site_config(site, new_config, - put_site_config(site, config, bench=bench) - - def set_nginx_port(site, port, bench='.', gen_config=True): -+ set_site_config_nginx_property(site, {"nginx_port": port}, bench=bench) -+ -+def set_ssl_certificate(site, ssl_certificate, bench='.', gen_config=True): -+ set_site_config_nginx_property(site, {"ssl_certificate": ssl_certificate}, bench=bench) -+ -+def set_ssl_certificate_key(site, ssl_certificate_key, bench='.', gen_config=True): -+ set_site_config_nginx_property(site, {"ssl_certificate_key": ssl_certificate_key}, bench=bench) -+ -+def set_nginx_port(site, port, bench='.', gen_config=True): -+ set_site_config_nginx_property(site, {"nginx_port": port}, bench=bench) -+ -+def set_site_config_nginx_property(site, config, bench='.', gen_config=True): - from .config import generate_nginx_config - if site not in get_sites(bench=bench): - raise Exception("No such site") -- update_site_config(site, {"nginx_port": port}, bench=bench) -+ update_site_config(site, config, bench=bench) - if gen_config: - generate_nginx_config() - -+def set_url_root(site, url_root, bench='.'): -+ update_site_config(site, {"host_name": url_root}, bench=bench) -+ - def set_default_site(site, bench='.'): - if not site in get_sites(bench=bench): - raise Exception("Site not in bench") -@@ -258,8 +324,11 @@ def update_requirements(bench='.'): - exec_cmd("{pip} install -q -r {req_file}".format(pip=pip, req_file=req_file)) - - def backup_site(site, bench='.'): -- exec_cmd("{frappe} --backup {site}".format(frappe=get_frappe(bench=bench), site=site), -- cwd=os.path.join(bench, 'sites')) -+ if FRAPPE_VERSION == 4: -+ exec_cmd("{frappe} --backup {site}".format(frappe=get_frappe(bench=bench), site=site), -+ cwd=os.path.join(bench, 'sites')) -+ else: -+ run_frappe_cmd('--site', site, 'backup', bench=bench) - - def backup_all_sites(bench='.'): - for site in get_sites(bench=bench): -@@ -313,4 +382,133 @@ def drop_privileges(uid_name='nobody', g - os.setuid(running_uid) - - # Ensure a very conservative umask -- old_umask = os.umask(077) -+ old_umask = os.umask(022) -+ -+def fix_prod_setup_perms(frappe_user=None): -+ files = [ -+ "logs/web.error.log", -+ "logs/web.log", -+ "logs/workerbeat.error.log", -+ "logs/workerbeat.log", -+ "logs/worker.error.log", -+ "logs/worker.log", -+ "config/nginx.conf", -+ "config/supervisor.conf", -+ ] -+ -+ if not frappe_user: -+ frappe_user = get_config().get('frappe_user') -+ -+ if not frappe_user: -+ print "frappe user not set" -+ sys.exit(1) -+ -+ for path in files: -+ if os.path.exists(path): -+ uid = pwd.getpwnam(frappe_user).pw_uid -+ gid = grp.getgrnam(frappe_user).gr_gid -+ os.chown(path, uid, gid) -+ -+def fix_file_perms(): -+ for dir_path, dirs, files in os.walk('.'): -+ for _dir in dirs: -+ os.chmod(os.path.join(dir_path, _dir), 0755) -+ for _file in files: -+ os.chmod(os.path.join(dir_path, _file), 0644) -+ bin_dir = './env/bin' -+ if os.path.exists(bin_dir): -+ for _file in os.listdir(bin_dir): -+ if not _file.startswith('activate'): -+ os.chmod(os.path.join(bin_dir, _file), 0755) -+ -+def get_redis_version(): -+ version_string = subprocess.check_output('redis-server --version', shell=True).strip() -+ if re.search("Redis server version 2.4", version_string): -+ return "2.4" -+ if re.search("Redis server v=2.6", version_string): -+ return "2.6" -+ if re.search("Redis server v=2.8", version_string): -+ return "2.8" -+ -+def get_current_frappe_version(bench='.'): -+ from .app import get_current_frappe_version as fv -+ return fv(bench=bench) -+ -+def run_frappe_cmd(*args, **kwargs): -+ bench = kwargs.get('bench', '.') -+ f = get_env_cmd('python', bench=bench) -+ sites_dir = os.path.join(bench, 'sites') -+ subprocess.check_call((f, '-m', 'frappe.utils.bench_helper', 'frappe') + args, cwd=sites_dir) -+ -+ -+def pre_upgrade(from_ver, to_ver, bench='.'): -+ from .migrate_to_v5 import validate_v4, remove_shopping_cart -+ pip = os.path.join(bench, 'env', 'bin', 'pip') -+ if from_ver == 4 and to_ver == 5: -+ apps = ('frappe', 'erpnext') -+ remove_shopping_cart(bench=bench) -+ -+ for app in apps: -+ cwd = os.path.abspath(os.path.join(bench, 'apps', app)) -+ if os.path.exists(cwd): -+ exec_cmd("git clean -dxf", cwd=cwd) -+ exec_cmd("{pip} install --upgrade -e {app}".format(pip=pip, app=cwd)) -+ -+def post_upgrade(from_ver, to_ver, bench='.'): -+ from .app import get_current_frappe_version -+ from .config import generate_nginx_config, generate_supervisor_config, generate_redis_config -+ conf = get_config(bench=bench) -+ if from_ver == 4 and to_ver == 5: -+ print "-"*80 -+ print "Your bench was upgraded to version 5" -+ if conf.get('restart_supervisor_on_update'): -+ generate_redis_config(bench=bench) -+ generate_supervisor_config(bench=bench) -+ generate_nginx_config(bench=bench) -+ setup_procfile(bench=bench) -+ setup_backups(bench=bench) -+ 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 -+ print "sudo service nginx restart" -+ print "sudo supervisorctl reload" -+ -+def update_translations_p(args): -+ update_translations(*args) -+ -+def download_translations_p(): -+ pool = multiprocessing.Pool(8) -+ -+ langs = get_langs() -+ apps = ('frappe', 'erpnext') -+ args = list(itertools.product(apps, langs)) -+ -+ pool.map(update_translations_p, args) -+ -+def download_translations(): -+ langs = get_langs() -+ apps = ('frappe', 'erpnext') -+ for app, lang in itertools.product(apps, langs): -+ update_translations(app, lang) -+ -+ -+def get_langs(): -+ lang_file = 'apps/frappe/frappe/data/languages.txt' -+ with open(lang_file) as f: -+ lang_data = f.read() -+ langs = [line.split('\t')[0] for line in lang_data.splitlines()] -+ langs.remove('en') -+ return langs -+ -+ -+def update_translations(app, lang): -+ translations_dir = os.path.join('apps', app, app, 'translations') -+ csv_file = os.path.join(translations_dir, lang + '.csv') -+ r = requests.get("https://translate.erpnext.com/files/{}-{}.csv".format(app, lang)) -+ r.raise_for_status() -+ with open(csv_file, 'wb') as f: -+ f.write(r.text.encode('utf-8')) -+ print 'downloaded for', app, lang -+ -+ -+FRAPPE_VERSION = get_current_frappe_version() ---- completion.sh.orig 2015-07-31 10:19:27 UTC -+++ completion.sh -@@ -0,0 +1,30 @@ -+_setup_bench_tab_completion () { -+ if [ -n "$BASH" ] ; then -+ _bench () { -+ local cur=${COMP_WORDS[COMP_CWORD]} -+ local prev=${COMP_WORDS[COMP_CWORD-1]} -+ if [[ $prev == "--site" ]]; then -+ COMPREPLY=( $(compgen -W "`_site_dirs`" -- $cur) ) -+ fi -+ } -+ complete -F _bench bench -+ elif [ -n "$ZSH_VERSION" ]; then -+ _bench () { -+ local a -+ local prev -+ read -l a -+ prev=`echo $a| awk '{ print $NF }'` -+ if [[ $prev == "--site" ]]; then -+ reply=($(_site_dirs)) -+ fi -+ } -+ compctl -K _bench bench -+ fi -+} -+ -+_site_dirs() { -+ ls -d sites/*/ | sed "s/sites\///g" | sed "s/\/$//g" | xargs echo -+} -+ -+ -+_setup_bench_tab_completion ---- install_scripts/erpnext-apps-master.json.orig 2014-11-19 06:36:44 UTC -+++ install_scripts/erpnext-apps-master.json -@@ -3,10 +3,5 @@ - "url":"https://github.com/frappe/erpnext", - "name":"erpnext", - "branch": "master" -- }, -- { -- "url":"https://github.com/frappe/shopping-cart", -- "name":"shopping_cart", -- "branch": "master" - } - ] ---- install_scripts/erpnext-apps.json.orig 2014-11-19 06:36:44 UTC -+++ install_scripts/erpnext-apps.json -@@ -2,9 +2,5 @@ - { - "url":"https://github.com/frappe/erpnext", - "name":"erpnext" -- }, -- { -- "url":"https://github.com/frappe/shopping-cart", -- "name":"shopping_cart" - } - ] ---- install_scripts/setup_frappe.sh.orig 2014-11-19 06:36:44 UTC -+++ install_scripts/setup_frappe.sh -@@ -16,7 +16,7 @@ get_passwd() { - } - - set_opts () { -- OPTS=`getopt -o v --long verbose,mysql-root-password:,frappe-user:,setup-production,help -n 'parse-options' -- "$@"` -+ OPTS=`getopt -o v --long verbose,mysql-root-password:,frappe-user:,bench-branch:,setup-production,skip-setup-bench,help -n 'parse-options' -- "$@"` - - if [ $? != 0 ] ; then echo "Failed parsing options." >&2 ; exit 1 ; fi - -@@ -25,10 +25,21 @@ set_opts () { - VERBOSE=false - HELP=false - FRAPPE_USER=false -- FRAPPE_USER_PASS=`get_passwd` -- MSQ_PASS=`get_passwd` -- ADMIN_PASS=`get_passwd` -+ BENCH_BRANCH="master" - SETUP_PROD=false -+ SETUP_BENCH=true -+ -+ if [ -f ~/frappe_passwords.sh ]; then -+ source ~/frappe_passwords.sh -+ else -+ FRAPPE_USER_PASS=`get_passwd` -+ MSQ_PASS=`get_passwd` -+ ADMIN_PASS=`get_passwd` -+ -+ echo "FRAPPE_USER_PASS=$FRAPPE_USER_PASS" > ~/frappe_passwords.sh -+ echo "MSQ_PASS=$MSQ_PASS" >> ~/frappe_passwords.sh -+ echo "ADMIN_PASS=$ADMIN_PASS" >> ~/frappe_passwords.sh -+ fi - - while true; do - case "$1" in -@@ -37,6 +48,8 @@ set_opts () { - --mysql-root-password ) MSQ_PASS="$2"; shift; shift ;; - --frappe-user ) FRAPPE_USER="$2"; shift; shift ;; - --setup-production ) SETUP_PROD=true; shift;; -+ --bench-branch ) BENCH_BRANCH="$2"; shift;; -+ --skip-setup-bench ) SETUP_BENCH=false; shift;; - -- ) shift; break ;; - * ) break ;; - esac -@@ -94,7 +107,7 @@ add_centos6_mariadb_repo() { - echo " - [mariadb] - name = MariaDB --baseurl = http://yum.mariadb.org/5.5/centos$OS_VER-$ARCH -+baseurl = http://yum.mariadb.org/10.0/centos$OS_VER-$ARCH - gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB - gpgcheck=1 - " > /etc/yum.repos.d/mariadb.repo -@@ -105,7 +118,7 @@ add_ubuntu_mariadb_repo() { - run_cmd sudo apt-get update - run_cmd sudo apt-get install -y software-properties-common python-software-properties - run_cmd sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db -- run_cmd sudo add-apt-repository "deb http://ams2.mirrors.digitalocean.com/mariadb/repo/5.5/ubuntu $OS_VER main" -+ run_cmd sudo add-apt-repository "deb http://ams2.mirrors.digitalocean.com/mariadb/repo/10.0/ubuntu $OS_VER main" - } - - add_debian_mariadb_repo() { -@@ -122,15 +135,15 @@ add_debian_mariadb_repo() { - run_cmd sudo apt-get update - run_cmd sudo apt-get install -y python-software-properties - run_cmd sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 0xcbcb082a1bb943db -- run_cmd sudo add-apt-repository "deb http://ams2.mirrors.digitalocean.com/mariadb/repo/5.5/debian $CODENAME main" -+ run_cmd sudo add-apt-repository "deb http://ams2.mirrors.digitalocean.com/mariadb/repo/10.0/debian $CODENAME main" - } - - add_ius_repo() { - if [ $OS_VER -eq "6" ]; then - wget http://dl.iuscommunity.org/pub/ius/stable/CentOS/$OS_VER/$T_ARCH/epel-release-6-5.noarch.rpm -- wget http://dl.iuscommunity.org/pub/ius/stable/CentOS/$OS_VER/$T_ARCH/ius-release-1.0-13.ius.centos6.noarch.rpm -+ wget http://dl.iuscommunity.org/pub/ius/stable/CentOS/$OS_VER/$T_ARCH/ius-release-1.0-14.ius.centos6.noarch.rpm - rpm --quiet -q epel-release || rpm -Uvh epel-release-6-5.noarch.rpm -- rpm --quiet -q ius-release || rpm -Uvh ius-release-1.0-13.ius.centos6.noarch.rpm -+ rpm --quiet -q ius-release || rpm -Uvh ius-release-1.0-14.ius.centos6.noarch.rpm - fi - } - -@@ -139,7 +152,9 @@ add_epel_centos7() { - } - - add_maria_db_repo() { -- if [ "$OS" == "centos" ]; then -+ if [ "$OS" == "Ubuntu" ] && [ $OS_VER == "utopic" ]; then -+ return -+ elif [ "$OS" == "centos" ]; then - echo Adding centos mariadb repo - add_centos6_mariadb_repo - -@@ -148,7 +163,7 @@ add_maria_db_repo() { - add_debian_mariadb_repo - - elif [ "$OS" == "Ubuntu" ]; then -- echo Adding debian mariadb repo -+ echo Adding ubuntu mariadb repo - add_ubuntu_mariadb_repo - else - echo Unsupported Distribution -@@ -164,10 +179,10 @@ install_packages() { - run_cmd sudo yum groupinstall -y "Development tools" - if [ $OS_VER == "6" ]; then - run_cmd add_ius_repo -- run_cmd sudo yum install -y git MariaDB-server MariaDB-client MariaDB-compat python-setuptools nginx zlib-devel bzip2-devel openssl-devel memcached postfix python27-devel python27 libxml2 libxml2-devel libxslt libxslt-devel redis MariaDB-devel libXrender libXext python27-setuptools -+ run_cmd sudo yum install -y git MariaDB-server MariaDB-client MariaDB-compat python-setuptools nginx zlib-devel bzip2-devel openssl-devel postfix python27-devel python27 libxml2 libxml2-devel libxslt libxslt-devel redis MariaDB-devel libXrender libXext python27-setuptools cronie sudo which xorg-x11-fonts-Type1 xorg-x11-fonts-75dpi - elif [ $OS_VER == "7" ]; then - run_cmd add_epel_centos7 -- run_cmd sudo yum install -y git mariadb-server mariadb-devel python-setuptools nginx zlib-devel bzip2-devel openssl-devel memcached postfix python-devel libxml2 libxml2-devel libxslt libxslt-devel redis libXrender libXext supervisor -+ run_cmd sudo yum install -y git mariadb-server mariadb-devel python-setuptools nginx zlib-devel bzip2-devel openssl-devel postfix python-devel libxml2 libxml2-devel libxslt libxslt-devel redis libXrender libXext supervisor cronie sudo which xorg-x11-fonts-75dpi xorg-x11-fonts-Type1 - fi - echo "Installing wkhtmltopdf" - install_wkhtmltopdf_centos -@@ -178,7 +193,7 @@ install_packages() { - export DEBIAN_FRONTEND=noninteractive - setup_debconf - run_cmd sudo apt-get update -- run_cmd sudo apt-get install python-dev python-setuptools build-essential python-mysqldb git memcached ntp vim screen htop mariadb-server mariadb-common libmariadbclient-dev libxslt1.1 libxslt1-dev redis-server libssl-dev libcrypto++-dev postfix nginx supervisor python-pip fontconfig libxrender1 libxext6 -y -+ run_cmd sudo apt-get install python-dev python-setuptools build-essential python-mysqldb git ntp vim screen htop mariadb-server mariadb-common libmariadbclient-dev libxslt1.1 libxslt1-dev redis-server libssl-dev libcrypto++-dev postfix nginx supervisor python-pip fontconfig libxrender1 libxext6 xfonts-75dpi xfonts-base -y - echo "Installing wkhtmltopdf" - install_wkhtmltopdf_deb - -@@ -190,17 +205,17 @@ install_packages() { - - install_wkhtmltopdf_centos () { - -- if [[ $OS == "centos" && $OS_VER == "7" && $T_ARCH="i386" ]]; then -+ if [[ $OS == "centos" && $OS_VER == "7" && $T_ARCH == "i386" ]]; then - echo "Cannot install wkhtmltodpdf. Skipping..." - return 0 - fi -- RPM="wkhtmltox-0.12.1_linux-$OS$OS_VER-$WK_ARCH.rpm" -- run_cmd wget http://downloads.sourceforge.net/project/wkhtmltopdf/0.12.1/$RPM -+ RPM="wkhtmltox-0.12.2.1_linux-$OS$OS_VER-$WK_ARCH.rpm" -+ run_cmd wget http://download.gna.org/wkhtmltopdf/0.12/0.12.2.1/$RPM - rpm --quiet -q wkhtmltox || run_cmd rpm -Uvh $RPM - } - - install_wkhtmltopdf_deb () { -- if [[ $OS_VER == "utopic" ]]; then -+ if [[ $OS_VER == "utopic" || $OS_VER == "vivid" ]]; then - echo "Cannot install wkhtmltodpdf. Skipping..." - return 0 - fi -@@ -209,8 +224,8 @@ install_wkhtmltopdf_deb () { - else - WK_VER=$OS_VER - fi -- run_cmd wget http://downloads.sourceforge.net/project/wkhtmltopdf/0.12.1/wkhtmltox-0.12.1_linux-$WK_VER-$WK_ARCH.deb -- run_cmd dpkg -i wkhtmltox-0.12.1_linux-$WK_VER-$WK_ARCH.deb -+ run_cmd wget http://download.gna.org/wkhtmltopdf/0.12/0.12.2.1/wkhtmltox-0.12.2.1_linux-$WK_VER-$WK_ARCH.deb -+ run_cmd dpkg -i wkhtmltox-0.12.2.1_linux-$WK_VER-$WK_ARCH.deb - } - - -@@ -274,18 +289,47 @@ configure_services_centos6() { - - configure_services_centos7() { - run_cmd systemctl enable nginx -- run_cmd systemctl enable mariadb -+ run_cmd systemctl enable mysql - run_cmd systemctl enable redis - run_cmd systemctl enable supervisord -- run_cmd systemctl enable memcached - } - - start_services_centos7() { - run_cmd systemctl start nginx -- run_cmd systemctl start mariadb -+ run_cmd systemctl start mysql - run_cmd systemctl start redis - run_cmd systemctl start supervisord -- run_cmd systemctl start memcached -+} -+ -+configure_mariadb() { -+ config=" -+[mysqld] -+innodb-file-format=barracuda -+innodb-file-per-table=1 -+innodb-large-prefix=1 -+character-set-client-handshake = FALSE -+character-set-server = utf8mb4 -+collation-server = utf8mb4_unicode_ci -+ -+[mysql] -+default-character-set = utf8mb4 -+ " -+ deb_cnf_path="/etc/mysql/conf.d/barracuda.cnf" -+ centos_cnf_path="/etc/my.cnf.d/barracuda.cnf" -+ -+ if [ $OS == "centos" ]; then -+ -+ echo "$config" > $centos_cnf_path -+ if [ $OS_VER == "6" ]; then -+ run_cmd sudo service mysql restart -+ elif [ $OS_VER == "7" ]; then -+ run_cmd sudo systemctl restart mysql -+ fi -+ -+ elif [ $OS == "debian" ] || [ $OS == "Ubuntu" ]; then -+ echo "$config" > $deb_cnf_path -+ sudo service mysql restart -+ fi - } - - setup_debconf() { -@@ -296,14 +340,14 @@ setup_debconf() { - } - - install_bench() { -- run_cmd sudo su $FRAPPE_USER -c "cd /home/$FRAPPE_USER && git clone https://github.com/frappe/bench bench-repo" -- if hash pip-2.7; then -+ run_cmd sudo su $FRAPPE_USER -c "cd /home/$FRAPPE_USER && git clone https://github.com/frappe/bench --branch $BENCH_BRANCH bench-repo" -+ if hash pip-2.7 &> /dev/null; then - PIP="pip-2.7" -- elif hash pip2.7; then -+ elif hash pip2.7 &> /dev/null; then - PIP="pip2.7" -- elif hash pip2; then -+ elif hash pip2 &> /dev/null; then - PIP="pip2" -- elif hash pip; then -+ elif hash pip &> /dev/null; then - PIP="pip" - else - echo PIP not installed -@@ -325,12 +369,12 @@ setup_bench() { - echo Setting up first site - echo /home/$FRAPPE_USER/frappe-bench > /etc/frappe_bench_dir - run_cmd sudo su $FRAPPE_USER -c "cd /home/$FRAPPE_USER/frappe-bench && bench new-site site1.local --mariadb-root-password $MSQ_PASS --admin-password $ADMIN_PASS" -- run_cmd sudo su $FRAPPE_USER -c "cd /home/$FRAPPE_USER/frappe-bench && bench frappe --install_app erpnext" -- run_cmd sudo su $FRAPPE_USER -c "cd /home/$FRAPPE_USER/frappe-bench && bench frappe --install_app shopping_cart" -+ run_cmd sudo su $FRAPPE_USER -c "cd /home/$FRAPPE_USER/frappe-bench && bench install-app erpnext" - run_cmd bash -c "cd /home/$FRAPPE_USER/frappe-bench && bench setup sudoers $FRAPPE_USER" - if $SETUP_PROD; then - run_cmd bash -c "cd /home/$FRAPPE_USER/frappe-bench && bench setup production $FRAPPE_USER" - fi -+ chown $FRAPPE_USER /home/$FRAPPE_USER/frappe-bench/logs/* - } - - add_user() { -@@ -377,10 +421,13 @@ main() { - fi - configure_mariadb_centos - fi -+ configure_mariadb - echo "Adding frappe user" - add_user - install_bench -- setup_bench -+ if $SETUP_BENCH; then -+ setup_bench -+ fi - - echo - RUNNING="" ---- setup.py.orig 2014-11-19 06:36:44 UTC -+++ setup.py -@@ -2,7 +2,7 @@ from setuptools import setup, find_packa - - setup( - name='bench', -- version='0.1', -+ version='0.92', - py_modules=find_packages(), - include_package_data=True, - url='https://github.com/frappe/bench', diff --git a/www/py-frappe-bench/files.old/patch-setup.py b/www/py-frappe-bench/files.old/patch-setup.py deleted file mode 100644 index 2aff43a..0000000 --- a/www/py-frappe-bench/files.old/patch-setup.py +++ /dev/null @@ -1,20 +0,0 @@ ---- setup.py.orig 2015-07-31 10:13:11 UTC -+++ setup.py -@@ -3,7 +3,7 @@ from setuptools import setup, find_packa - setup( - name='bench', - version='0.92', -- py_modules=find_packages(), -+ packages=find_packages(), - include_package_data=True, - url='https://github.com/frappe/bench', - author='Web Notes Technologies Pvt. Ltd.', -@@ -15,7 +15,7 @@ setup( - 'requests', - 'honcho', - 'semantic_version', -- 'GitPython==0.3.2.RC1' -+ 'GitPython>=0.3.2.RC1' - ], - entry_points=''' - [console_scripts] diff --git a/www/py-frappe-bench/files/patch-pyproject.toml b/www/py-frappe-bench/files/patch-pyproject.toml new file mode 100644 index 0000000..8811eaa --- /dev/null +++ b/www/py-frappe-bench/files/patch-pyproject.toml @@ -0,0 +1,11 @@ +--- pyproject.toml.orig 2024-09-27 13:44:50 UTC ++++ pyproject.toml +@@ -44,7 +44,7 @@ requires = [ + + [build-system] + requires = [ +- "hatchling>=1.6.0,<=1.21.0", ++ "hatchling>=1.6.0,<=1.30.0", + ] + build-backend = "hatchling.build" +