def add_remote(): env.box_idx = '' if len( env.hosts) < 2 else '-%d' % (env.hosts.index(env.host_string) + 1) with settings(warn_only=True): run_local('git remote add -f %(box_remote)s%(box_idx)s' ' %(host_string)s:%(box_domain)s/')
def fetch_remote(): step('Updating git remote...') env.box_idx = '' if len( env.hosts) < 2 else '-%d' % (env.hosts.index(env.host_string) + 1) with settings(warn_only=True): run_local('git fetch %(box_remote)s%(box_idx)s')
def compilemessages(): """Wrapper around ``compilemessages`` which does not descend into venv""" run_local( '. venv/bin/activate && for dir in ' '$(find . -name venv -prune -or -name locale -print)' '; do (cd $dir; cd ..; django-admin.py compilemessages); done')
def load_db(filename=None): """Loads a dump into the database""" env.box_dump_filename = filename if not filename: abort(red('Dump missing. "fab server.load_db:filename"', bold=True)) if not os.path.exists(filename): abort(red('"%(box_dump_filename)s" does not exist.' % env, bold=True)) if not confirm( 'Completely replace the remote database' ' "%(box_database)s" (if it exists)?', default=False): return run( 'psql -c "DROP DATABASE IF EXISTS %(box_database)s"') run( 'createdb %(box_database)s --encoding=UTF8 --template=template0' ' --owner=%(box_database)s') run_local( 'cat %(box_dump_filename)s |' 'ssh %(host_string)s "source .profile && psql %(box_database)s"') run( 'psql %(box_database)s -c "REASSIGN OWNED BY admin ' ' TO %(box_database)s"')
def empty_to_password(): run_local("venv/bin/python manage.py update_empty_passwords password") puts( green( "Users with empty passwords (for example SSO users) now have a" ' password of "password" (without quotes).' ) )
def fetch_remote(): step('Updating git remote...') env.box_idx = '' if len(env.hosts) < 2 else '-%d' % ( env.hosts.index(env.host_string) + 1) with settings(warn_only=True): run_local('git fetch %(box_remote)s%(box_idx)s')
def makemessages(): """Wrapper around the ``makemessages`` management command which excludes dependencies (virtualenv, bower components, node modules)""" run_local('venv/bin/python manage.py makemessages -a' ' -i bower_components' ' -i node_modules' ' -i venv')
def add_remote(): env.box_idx = '' if len(env.hosts) < 2 else '-%d' % ( env.hosts.index(env.host_string) + 1) with settings(warn_only=True): run_local( 'git remote add -f %(box_remote)s%(box_idx)s' ' %(host_string)s:%(box_domain)s/')
def _deploy_styles_foundation5_gulp(): run_local('./node_modules/.bin/gulp build') for part in ['bower_components', 'build']: rsync_project( local_dir='%(box_staticfiles)s/%(part)s' % dict(env, part=part), remote_dir='%(box_domain)s/%(box_staticfiles)s/' % env, delete=True, )
def _deploy_styles_foundation5_grunt(): run_local('cd %(box_staticfiles)s && grunt build') for part in ['bower_components', 'css']: rsync_project( local_dir='%(box_staticfiles)s/%(part)s' % dict(env, part=part), remote_dir='%(box_domain)s/%(box_staticfiles)s/' % env, delete=True, )
def makemessages(): """Wrapper around the ``makemessages`` management command which excludes dependencies (virtualenv, bower components, node modules)""" run_local( 'venv/bin/python manage.py makemessages -a' ' -i bower_components' ' -i node_modules' ' -i venv')
def _deploy_styles_foundation4_bundler(): run_local('bundle exec compass clean %(box_staticfiles)s') run_local('bundle exec compass compile -s compressed %(box_staticfiles)s') rsync_project( local_dir='%(box_staticfiles)s/stylesheets' % env, remote_dir='%(box_domain)s/%(box_staticfiles)s/' % env, delete=True, )
def update_requirement_files(): """ Updates requirement files with specific version numbers """ with prefix(". venv/bin/activate"): # We need to pass the files manually to ensure common.txt comes # first (It's extended with all packages not defined in any other # requirement file). We also have to exclude production.txt # because every package not installed will get lost (and the # production packages are of course not installed). run_local("venv/bin/pip-dump requirements/common.txt requirements/dev.txt")
def update_requirement_files(): """ Updates requirement files with specific version numbers """ with prefix('. venv/bin/activate'): # We need to pass the files manually to ensure common.txt comes # first (It's extended with all packages not defined in any other # requirement file). We also have to exclude production.txt # because every package not installed will get lost (and the # production packages are of course not installed). run_local( 'venv/bin/pip-dump requirements/common.txt requirements/dev.txt')
def dump_db(): """Dumps the database into the tmp/ folder""" env.box_datetime = datetime.now().strftime("%Y-%m-%d-%s") env.box_dump_filename = os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "tmp", "%(box_database)s-local-%(box_datetime)s.sql" % env, ) run_local("pg_dump %(box_database_local)s --no-privileges --no-owner" " --no-reconnect > %(box_dump_filename)s") puts(green("\nWrote a dump to %(box_dump_filename)s" % env))
def dump_db(): """Dumps the database into the tmp/ folder""" env.box_datetime = datetime.now().strftime('%Y-%m-%d-%s') env.box_dump_filename = os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'tmp', '%(box_database)s-local-%(box_datetime)s.sql' % env, ) run_local('pg_dump %(box_database_local)s --no-privileges --no-owner' ' --no-reconnect > %(box_dump_filename)s') puts(green('\nWrote a dump to %(box_dump_filename)s' % env))
def dump_db(): """Dumps the database into the tmp/ folder""" env.box_datetime = datetime.now().strftime('%Y-%m-%d-%s') env.box_dump_filename = os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'tmp', '%(box_database)s-local-%(box_datetime)s.sql' % env, ) run_local( 'pg_dump %(box_database_local)s --no-privileges --no-owner' ' --no-reconnect > %(box_dump_filename)s') puts(green('\nWrote a dump to %(box_dump_filename)s' % env))
def dump_db(): """Dumps the database into the tmp/ folder""" env.box_datetime = datetime.now().strftime('%Y-%m-%d-%s') env.box_dump_filename = os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'tmp', '%(box_database)s-%(box_environment)s-%(box_datetime)s.sql' % env, ) run_local('ssh %(host_string)s "source .profile &&' ' pg_dump %(box_database)s' ' --no-privileges --no-owner --no-reconnect"' ' > %(box_dump_filename)s') puts(green('\nWrote a dump to %(box_dump_filename)s' % env))
def dump_db(): """Dumps the database into the tmp/ folder""" env.box_datetime = datetime.now().strftime('%Y-%m-%d-%s') env.box_dump_filename = os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'tmp', '%(box_database)s-%(box_environment)s-%(box_datetime)s.sql' % env, ) run_local( 'ssh %(host_string)s "source .profile &&' ' pg_dump %(box_database)s' ' --no-privileges --no-owner --no-reconnect"' ' > %(box_dump_filename)s') puts(green('\nWrote a dump to %(box_dump_filename)s' % env))
def _deploy_styles_foundation5_webpack(): step('\n Compiling static sources...') run_local('rm -rf %(box_static_src)s/dist' % env) run_local('npm run prod') step('\nUploading static files...') rsync_project( local_dir='%(box_static_src)s/dist' % env, remote_dir='%(box_domain)s/%(box_staticfiles)s/' % env, delete=True, ) put( 'tmp/webpack*json', '%(box_domain)s/tmp/' % env, )
def deploy(): """Checks whether everything is ready for deployment""" step('Checking whether we are on the expected branch...') with settings(warn_only=True), hide('everything'): branch = run_local('git symbolic-ref -q --short HEAD', capture=True) if not branch: abort(red('No branch checked out, cannot continue.', bold=True)) if branch != env.box_branch: puts( red('Warning: The currently checked out branch is \'%s\', but' ' the environment \'%s\' runs on \'%s\'.' % (branch, env.box_environment, env.box_branch))) if not confirm('Continue deployment?', default=False): abort('Aborting.') execute('check.check') execute('check.test') # XXX Maybe even execute('check.primetime') if deploying to production? with cd('%(box_domain)s'): step('\nChecking for uncommitted changes on the server...') result = run('git status --porcelain') if result: abort(red('Uncommitted changes detected, aborting deployment.'))
def deploy(): """Checks whether everything is ready for deployment""" step('Checking whether we are on the expected branch...') with settings(warn_only=True), hide('everything'): branch = run_local('git symbolic-ref -q --short HEAD', capture=True) if not branch: abort(red('No branch checked out, cannot continue.', bold=True)) if branch != env.box_branch: puts(red( 'Warning: The currently checked out branch is \'%s\', but' ' the environment \'%s\' runs on \'%s\'.' % ( branch, env.box_environment, env.box_branch))) if not confirm('Continue deployment?', default=False): abort('Aborting.') execute('check.check') execute('check.test') # XXX Maybe even execute('check.primetime') if deploying to production? with cd('%(box_domain)s'): step('\nChecking for uncommitted changes on the server...') result = run('git status --porcelain') if result: abort(red('Uncommitted changes detected, aborting deployment.'))
def create_and_migrate_database(): """Creates and migrates a Postgres database""" if not confirm( 'Completely replace the local database' ' "%(box_database_local)s" (if it exists)?'): return run_local( 'dropdb --if-exists %(box_database_local)s') run_local( 'createdb %(box_database_local)s' ' --encoding=UTF8 --template=template0') with settings(warn_only=True): run_local('venv/bin/python manage.py makemigrations elephantblog') run_local('venv/bin/python manage.py makemigrations page') run_local('venv/bin/python manage.py migrate')
def create_virtualenv(): """Creates the virtualenv and installs all Python requirements""" run_local('virtualenv --python python2.7' ' --prompt "(venv:%(box_domain)s)" venv') run_local('venv/bin/pip install -U wheel setuptools pip') if platform.system() == 'Darwin' and platform.mac_ver()[0] >= '10.9': run_local('export CFLAGS=-Qunused-arguments' ' && export CPPFLAGS=-Qunused-arguments' ' && venv/bin/pip install -r requirements/dev.txt') else: run_local('venv/bin/pip install -r requirements/dev.txt')
def create_virtualenv(): """Creates the virtualenv and installs all Python requirements""" run_local("virtualenv --python python2.7" ' --prompt "(venv:%(box_domain)s)" venv') run_local("venv/bin/pip install -U wheel setuptools pip") if platform.system() == "Darwin" and platform.mac_ver()[0] >= "10.9": run_local( "export CFLAGS=-Qunused-arguments" " && export CPPFLAGS=-Qunused-arguments" " && venv/bin/pip install -r requirements/dev.txt" ) else: run_local("venv/bin/pip install -r requirements/dev.txt")
def create_virtualenv(): """Creates the virtualenv and installs all Python requirements""" run_local( 'virtualenv --python %(box_python)s' ' --prompt "(venv:%(box_domain)s)" venv') run_local('venv/bin/pip install -U wheel setuptools pip') if platform.system() == 'Darwin' and platform.mac_ver()[0] >= '10.9': run_local( 'export CFLAGS=-Qunused-arguments' ' && export CPPFLAGS=-Qunused-arguments' ' && venv/bin/pip install -r requirements/dev.txt') else: run_local('venv/bin/pip install -r requirements/dev.txt')
def dev(): """Runs the development server, SCSS watcher and backend services if they are not running already""" jobs = [ lambda: run_local('venv/bin/python -Wall manage.py runserver'), ] if os.path.exists('gulpfile.js'): jobs.append(lambda: run_local('./node_modules/.bin/gulp')) elif os.path.exists('%(box_staticfiles)s/Gruntfile.js' % env): jobs.append(lambda: run_local('cd %(box_sass)s && grunt')) elif os.path.exists('%(box_staticfiles)s/config.rb' % env): jobs.append( lambda: run_local('bundle exec compass watch %(box_staticfiles)s')) elif os.path.exists('%(box_staticfiles)s/webpack.config.js' % env): jobs.append(lambda: run_local( './node_modules/.bin/webpack -d --watch' ' --config %(box_staticfiles)s/webpack.config.js')) jobs = [Process(target=j) for j in jobs] [j.start() for j in jobs] [j.join() for j in jobs]
def dev(host='127.0.0.1', port=8000): """Runs the development server, SCSS watcher and backend services if they are not running already""" jobs = [ lambda: run_local( 'venv/bin/python -Wall manage.py runserver %s:%s' % ( host, port, ), ), lambda: run_local('HOST=%s node server' % host), ] if os.path.exists('gulpfile.js'): jobs.append(lambda: run_local('./node_modules/.bin/gulp')) elif os.path.exists('%(box_staticfiles)s/Gruntfile.js' % env): jobs.append(lambda: run_local('cd %(box_sass)s && grunt')) elif os.path.exists('%(box_staticfiles)s/config.rb' % env): jobs.append( lambda: run_local('bundle exec compass watch %(box_staticfiles)s')) elif os.path.exists('%(box_staticfiles)s/webpack.config.js' % env): jobs.append( lambda: run_local( './node_modules/.bin/webpack -d --watch' ' --config %(box_staticfiles)s/webpack.config.js')) jobs = [Process(target=j) for j in jobs] [j.start() for j in jobs] [j.join() for j in jobs]
def init_bitbucket(): username = default_env('BITBUCKET_USERNAME') password = default_env('BITBUCKET_PASSWORD') # Should probably not be used organization = default_env('BITBUCKET_ORGANIZATION') if not username or not organization: puts( 'Consider adding default values for BITBUCKET_USERNAME' ' and BITBUCKET_ORGANIZATION to ~/.box.env') username = prompt( 'Username', default=username) if not password: password = getpass.getpass('Password ') organization = prompt( 'Organization', default=organization) repository = prompt( 'Repository', default=env.box_repository) if not confirm( 'Initialize repository at https://bitbucket.org/%s/%s?' % ( organization, repository)): puts(red('Bitbucket repository creation aborted.')) return 1 if username and password and organization and repository: env.box_auth = '%s:"%s"' % (username, password) env.box_repo = '%s/%s' % (organization, repository) with hide('running'): run_local( 'curl' ' -X POST -v -u %(box_auth)s' ' -H "content-type: application/json"' ' https://api.bitbucket.org/2.0/repositories/%(box_repo)s' ' -d \'{"scm": "git", "is_private": true,' ' "forking_policy": "no_public_forks"}\'') with hide('everything'): with settings(warn_only=True): run_local('git remote rm origin') run_local('git remote add origin [email protected]:%(box_repo)s.git') run_local('git push -u origin master')
def code(reload=True): """Deploys the currently committed project state to the server, if there are no uncommitted changes on the server and the checking step did not report any problems""" execute('check.deploy') # XXX Maybe abort deployment if branch-to-be-deployed is not checked out? step('\nPushing changes...') run_local('git push origin %(box_branch)s') step('\nDeploying new code on server...') with cd('%(box_domain)s'): run('git fetch') run('git reset --hard origin/%(box_branch)s') run('find . -name "*.pyc" -delete') run('venv/bin/pip install -r requirements/production.txt' ' --find-links file:///home/www-data/tmp/wheel/wheelhouse/') run('venv/bin/python manage.py migrate --noinput') if reload: execute('deploy.restart_server') execute('git.fetch_remote')
def clone_repository(): puts(green('We need the repository to initialize the server.')) with hide('running'): output = run_local('git config remote.origin.url', capture=True) repo = prompt('Repository', default=output) if not repo: puts(red('Cannot continue without a repository.')) return 1 env.box_repository_url = repo run('git clone -b %(box_branch)s %(box_repository_url)s %(box_domain)s') execute('git.add_remote')
def primetime(): """Check whether this project is ready for prime time""" execute('check.check') execute('check.test') step('"noindex" should not hit production servers...') run_local( "! git --no-pager grep -n -C3 -E '^Disallow: /$' -- 'robots.txt'") run_local( "! git --no-pager grep -n -C3 -E 'meta.*robots.*noindex'" " -- %(box_project_name)s") step('Checking local settings on server...') with cd('%(box_domain)s'): output = run( "DJANGO_SETTINGS_MODULE=%(box_project_name)s.settings" " venv/bin/python -c \"" "from django.conf import settings as s;" "print('fd:%%s\\ndsn:%%s\\nsso:%%s\\ndebug:%%s\\nsk:%%s' %% (" "getattr(s, 'FORCE_DOMAIN', '-')," "getattr(s, 'RAVEN_CONFIG', {}).get('dsn', '')," "bool(getattr(s, 'DJANGO_ADMIN_SSO_ADD_LOGIN_BUTTON', False))," "bool(s.DEBUG)," "s.SECRET_KEY," "))\"" % env, quiet=True).strip() output = dict( row.strip().split(':', 1) for row in re.split(r'[\r\n]+', output)) if output['fd'] == '': puts(red('Warning: FORCE_DOMAIN is empty.')) elif output['fd'] == '-': puts(red('Warning: FORCE_DOMAIN is not defined.')) if output['dsn'] == '': puts(red( 'Warning: Sentry is not configured, fill in RAVEN_CONFIG.')) if output['sso'] != 'True': puts(red( 'Warning: SSO authentication for the administration is not' ' configured.')) if output['debug'] == 'True': puts(red( 'Error: DEBUG = True!?', bold=True)) with settings(warn_only=True), hide('everything'): gitgrep = run_local( "! git --no-pager grep '%s'" % output['sk'], capture=True) grep = run_local("! grep '%s' */*.py" % output['sk'], capture=True) if gitgrep or grep: puts(red( 'Error: The remote value of SECRET_KEY also exists in local' ' files. Set a new value for SECRET_KEY in' ' .env on the server!' % env, bold=True))
def primetime(): """Check whether this project is ready for prime time""" execute('check.check') execute('check.test') step('"noindex" should not hit production servers...') run_local( "! git --no-pager grep -n -C3 -E '^Disallow: /$' -- 'robots.txt'") run_local("! git --no-pager grep -n -C3 -E 'meta.*robots.*noindex'" " -- %(box_project_name)s") step('Checking local settings on server...') with cd('%(box_domain)s'): output = run( "DJANGO_SETTINGS_MODULE=%(box_project_name)s.settings" " venv/bin/python -c \"" "from django.conf import settings as s;" "print('fd:%%s\\ndsn:%%s\\nsso:%%s\\ndebug:%%s\\nsk:%%s' %% (" "getattr(s, 'FORCE_DOMAIN', '-')," "getattr(s, 'RAVEN_CONFIG', {}).get('dsn', '')," "bool(getattr(s, 'DJANGO_ADMIN_SSO_ADD_LOGIN_BUTTON', False))," "bool(s.DEBUG)," "s.SECRET_KEY," "))\"" % env, quiet=True).strip() output = dict(row.strip().split(':', 1) for row in re.split(r'[\r\n]+', output)) if output['fd'] == '': puts(red('Warning: FORCE_DOMAIN is empty.')) elif output['fd'] == '-': puts(red('Warning: FORCE_DOMAIN is not defined.')) if output['dsn'] == '': puts( red('Warning: Sentry is not configured, fill in RAVEN_CONFIG.') ) if output['sso'] != 'True': puts( red('Warning: SSO authentication for the administration is not' ' configured.')) if output['debug'] == 'True': puts(red('Error: DEBUG = True!?', bold=True)) with settings(warn_only=True), hide('everything'): gitgrep = run_local("! git --no-pager grep '%s'" % output['sk'], capture=True) grep = run_local("! grep '%s' */*.py" % output['sk'], capture=True) if gitgrep or grep: puts( red('Error: The remote value of SECRET_KEY also exists in local' ' files. Set a new value for SECRET_KEY in' ' .env on the server!' % env, bold=True))
def create_and_migrate_database(): """Creates and migrates a Postgres database""" if not confirm("Completely replace the local database" ' "%(box_database_local)s" (if it exists)?'): return run_local("dropdb --if-exists %(box_database_local)s") run_local("createdb %(box_database_local)s" " --encoding=UTF8 --template=template0") run_local("venv/bin/python manage.py migrate")
def create_and_migrate_database(): """Creates and migrates a Postgres database""" if not confirm('Completely replace the local database' ' "%(box_database_local)s" (if it exists)?'): return run_local('dropdb --if-exists %(box_database_local)s') run_local('createdb %(box_database_local)s' ' --encoding=UTF8 --template=template0') run_local('venv/bin/python manage.py migrate')
def load_db(filename=None): """Loads a dump into the database""" env.box_dump_filename = filename if not filename: abort(red('Dump missing. "fab local.load_db:filename"', bold=True)) if not os.path.exists(filename): abort(red('"%(box_dump_filename)s" does not exist.' % env, bold=True)) run_local("dropdb --if-exists %(box_database_local)s") run_local("createdb %(box_database_local)s" " --encoding=UTF8 --template=template0") run_local("psql %(box_database_local)s < %(box_dump_filename)s")
def init_bitbucket(): username = default_env('BITBUCKET_USERNAME') password = default_env('BITBUCKET_PASSWORD') # Should probably not be used organization = default_env('BITBUCKET_ORGANIZATION') if not username or not organization: puts('Consider adding default values for BITBUCKET_USERNAME' ' and BITBUCKET_ORGANIZATION to ~/.box.env') username = prompt('Username', default=username) if not password: password = getpass.getpass('Password ') organization = prompt('Organization', default=organization) repository = prompt('Repository', default=env.box_repository) if not confirm('Initialize repository at https://bitbucket.org/%s/%s?' % (organization, repository)): puts(red('Bitbucket repository creation aborted.')) return 1 if username and password and organization and repository: env.box_auth = '%s:"%s"' % (username, password) env.box_repo = '%s/%s' % (organization, repository) with hide('running'): run_local( 'curl' ' -X POST -v -u %(box_auth)s' ' -H "content-type: application/json"' ' https://api.bitbucket.org/2.0/repositories/%(box_repo)s' ' -d \'{"scm": "git", "is_private": true,' ' "forking_policy": "no_public_forks"}\'') with hide('everything'): with settings(warn_only=True): run_local('git remote rm origin') run_local('git remote add origin [email protected]:%(box_repo)s.git') run_local('git push -u origin master')
def load_db(filename=None): """Loads a dump into the database""" env.box_dump_filename = filename if not filename: abort(red('Dump missing. "fab local.load_db:filename"', bold=True)) if not os.path.exists(filename): abort(red('"%(box_dump_filename)s" does not exist.' % env, bold=True)) run_local('dropdb --if-exists %(box_database_local)s') run_local('createdb %(box_database_local)s' ' --encoding=UTF8 --template=template0') run_local('psql %(box_database_local)s < %(box_dump_filename)s')
def pull_database(): """Pulls the database contents from the server, dropping the local database first (if it exists)""" if not confirm("Completely replace the local database" ' "%(box_database_local)s" (if it exists)?'): return run_local("dropdb --if-exists %(box_database_local)s") run_local("createdb %(box_database_local)s" " --encoding=UTF8 --template=template0") run_local( 'ssh %(host_string)s "source .profile &&' " pg_dump %(box_database)s" ' --no-privileges --no-owner --no-reconnect"' " | psql %(box_database_local)s" )
def pull_database(): """Pulls the database contents from the server, dropping the local database first (if it exists)""" if not confirm('Completely replace the local database' ' "%(box_database_local)s" (if it exists)?'): return run_local('dropdb --if-exists %(box_database_local)s') run_local('createdb %(box_database_local)s' ' --encoding=UTF8 --template=template0') run_local('ssh %(host_string)s "source .profile &&' ' pg_dump %(box_database)s' ' --no-privileges --no-owner --no-reconnect"' ' | psql %(box_database_local)s')
def check(): """Runs coding style checks, and Django's checking framework""" step('Searching for debugging statements...') run_local("! git --no-pager grep -n -C3 -E 'import i?pdb' -- '*.py'") run_local( "! git --no-pager grep -n -C3 -E 'console\.log' -- '*.html' '*.js'") run_local("! git --no-pager grep -n -C3 -E '(^| )print( |\(|$)' -- '*.py'") step('Checking Python code with flake8...') run_local('venv/bin/flake8 .') step('Checking Javascript code...') run_local('./node_modules/.bin/jshint %(box_staticfiles)s/') step('Invoking Django\'s systems check framework...') run_local('venv/bin/python manage.py check') with settings(warn_only=True), hide('warnings'): # Remind the user about uglyness, but do not fail (there are good # reasons to use the patterns warned about here). step('Pointing to potential tasks...') run_local("! git --no-pager grep -n -E '#.*noqa'" " -- '%(box_project_name)s/*.py'") run_local("! git --no-pager grep -n -E '(XXX|FIXME|TODO)'") complain_on_failure( run_local("! git --no-pager grep -n -E '^-e.+$' -- requirements/"), 'Warning: Editable requirements found. Releases are preferred!')
def frontend_tools(): """Installs frontend tools. Knows how to handle npm/bower and bundler""" if os.path.exists('package.json'): run_local('npm install') if os.path.exists('bower.json'): run_local('bower install') if os.path.exists('%(box_staticfiles)s/bower.json' % env): run_local('cd %(box_staticfiles)s && npm install') run_local('cd %(box_staticfiles)s && bower install') if os.path.exists('Gemfile'): run_local('bundle install --path=.bundle/gems') if not os.path.exists('%(box_staticfiles)s/bower_components' % env): return if not os.path.exists('%(box_staticfiles)s/scss/_settings.scss' % env): run_local( 'cp %(box_staticfiles)s/bower_components/foundation/scss/' 'foundation/_settings.scss %(box_staticfiles)s/scss/') puts(red( 'Please commit %(box_staticfiles)s/scss/_settings.scss if you' ' intend to modify this file!' % env)) else: puts(red( 'Not replacing %(box_staticfiles)s/scss/_settings.scss with' ' Foundation\'s version, file exists already.' % env))
def update(): run_local('venv/bin/pip install -r requirements/dev.txt') execute('local.frontend_tools') run_local('venv/bin/python manage.py migrate')
def test(): step('Running backend testsuite...') run_local('venv/bin/python manage.py test') step('We do not have a frontend testsuite yet...')
def frontend_tools(): """Installs frontend tools. Knows how to handle npm/bower and bundler""" if os.path.exists('bower.json'): run_local('npm install') run_local('bower install') if os.path.exists('%(box_staticfiles)s/bower.json' % env): run_local('cd %(box_staticfiles)s && npm install') run_local('cd %(box_staticfiles)s && bower install') if os.path.exists('Gemfile'): run_local('bundle install --path=.bundle/gems') if not os.path.exists('%(box_staticfiles)s/scss' % env): return if not os.path.exists('%(box_staticfiles)s/scss/_settings.scss' % env): run_local('cp %(box_staticfiles)s/bower_components/foundation/scss/' 'foundation/_settings.scss %(box_staticfiles)s/scss/') puts( red('Please commit %(box_staticfiles)s/scss/_settings.scss if you' ' intend to modify this file!' % env)) else: puts( red('Not replacing %(box_staticfiles)s/scss/_settings.scss with' ' Foundation\'s version, file exists already.' % env))
def check(): """Runs coding style checks, and Django's checking framework""" step('Searching for debugging statements...') run_local( "! git --no-pager grep -n -C3 -E 'import i?pdb' -- '*.py'") run_local( "! git --no-pager grep -n -C3 -E '(^| )print( |\(|$)' -- '*.py'") step('Checking Python code with flake8...') run_local('venv/bin/flake8 .') step('Checking Javascript code...') run_local('./node_modules/.bin/eslint %(box_static_src)s/js/ webpack*js') step('Invoking Django\'s systems check framework...') run_local('venv/bin/python manage.py check') with settings(warn_only=True), hide('warnings'): # Remind the user about uglyness, but do not fail (there are good # reasons to use the patterns warned about here). step('Pointing to potential tasks...') run_local( "! git --no-pager grep -n -C3 -E 'console\.log' -- '*.html' '*.js'" ) run_local( "! git --no-pager grep -n -E '#.*noqa'" " -- '%(box_project_name)s/*.py'") run_local("! git --no-pager grep -n -E '(XXX|FIXME|TODO)'") complain_on_failure( run_local("! git --no-pager grep -n -E '^-e.+$' -- requirements/"), 'Warning: Editable requirements found. Releases are preferred!')
def empty_to_password(): run_local('venv/bin/python manage.py update_empty_passwords password') puts( green('Users with empty passwords (for example SSO users) now have a' ' password of "password" (without quotes).'))