basing the django project on rdegges' django-skel
[oweals/karmaworld.git] / fabfile.py
1 """Management utilities."""
2
3
4 from fabric.contrib.console import confirm
5 from fabric.api import abort, env, local, settings, task
6
7
8 ########## GLOBALS
9 env.run = 'heroku run python manage.py'
10 HEROKU_ADDONS = (
11     'cloudamqp:lemur',
12     'heroku-postgresql:dev',
13     'scheduler:standard',
14     'memcache:5mb',
15     'newrelic:standard',
16     'pgbackups:auto-month',
17     'sentry:developer',
18 )
19 HEROKU_CONFIGS = (
20     'DJANGO_SETTINGS_MODULE=karmaworld.settings.prod',
21     'SECRET_KEY=(s1k!&^7l28k&nrm2ek(qqo&19%y(zn#=^zq_*ur2@irjun0x4'
22     'AWS_ACCESS_KEY_ID=xxx',
23     'AWS_SECRET_ACCESS_KEY=xxx',
24     'AWS_STORAGE_BUCKET_NAME=xxx',
25 )
26 ########## END GLOBALS
27
28
29 ########## HELPERS
30 def cont(cmd, message):
31     """Given a command, ``cmd``, and a message, ``message``, allow a user to
32     either continue or break execution if errors occur while executing ``cmd``.
33
34     :param str cmd: The command to execute on the local system.
35     :param str message: The message to display to the user on failure.
36
37     .. note::
38         ``message`` should be phrased in the form of a question, as if ``cmd``'s
39         execution fails, we'll ask the user to press 'y' or 'n' to continue or
40         cancel exeuction, respectively.
41
42     Usage::
43
44         cont('heroku run ...', "Couldn't complete %s. Continue anyway?" % cmd)
45     """
46     with settings(warn_only=True):
47         result = local(cmd, capture=True)
48
49     if message and result.failed and not confirm(message):
50         abort('Stopped execution per user request.')
51 ########## END HELPERS
52
53
54 ########## DATABASE MANAGEMENT
55 @task
56 def syncdb():
57     """Run a syncdb."""
58     local('%(run)s syncdb --noinput' % env)
59
60
61 @task
62 def migrate(app=None):
63     """Apply one (or more) migrations. If no app is specified, fabric will
64     attempt to run a site-wide migration.
65
66     :param str app: Django app name to migrate.
67     """
68     if app:
69         local('%s migrate %s --noinput' % (env.run, app))
70     else:
71         local('%(run)s migrate --noinput' % env)
72 ########## END DATABASE MANAGEMENT
73
74
75 ########## FILE MANAGEMENT
76 @task
77 def collectstatic():
78     """Collect all static files, and copy them to S3 for production usage."""
79     local('%(run)s collectstatic --noinput' % env)
80 ########## END FILE MANAGEMENT
81
82
83 ########## HEROKU MANAGEMENT
84 @task
85 def bootstrap():
86     """Bootstrap your new application with Heroku, preparing it for a production
87     deployment. This will:
88
89         - Create a new Heroku application.
90         - Install all ``HEROKU_ADDONS``.
91         - Sync the database.
92         - Apply all database migrations.
93         - Initialize New Relic's monitoring add-on.
94     """
95     cont('heroku create', "Couldn't create the Heroku app, continue anyway?")
96
97     for addon in HEROKU_ADDONS:
98         cont('heroku addons:add %s' % addon,
99             "Couldn't add %s to your Heroku app, continue anyway?" % addon)
100
101     for config in HEROKU_CONFIGS:
102         cont('heroku config:add %s' % config,
103             "Couldn't add %s to your Heroku app, continue anyway?" % config)
104
105     cont('git push heroku master',
106             "Couldn't push your application to Heroku, continue anyway?")
107
108     syncdb()
109     migrate()
110
111     cont('%(run)s newrelic-admin validate-config - stdout' % env,
112             "Couldn't initialize New Relic, continue anyway?")
113
114
115 @task
116 def destroy():
117     """Destroy this Heroku application. Wipe it from existance.
118
119     .. note::
120         This really will completely destroy your application. Think twice.
121     """
122     local('heroku apps:destroy')
123 ########## END HEROKU MANAGEMENT