├── BSDmakefile ├── GNUmakefile ├── Makefile └── README.rst /BSDmakefile: -------------------------------------------------------------------------------- 1 | do_nothing: 2 | 3 | virtual_env_set: 4 | 5 | .ifndef VIRTUAL_ENV 6 | 7 | .error VIRTUAL_ENV not set 8 | 9 | .endif 10 | 11 | site_set: 12 | 13 | .ifndef SITE 14 | 15 | .error SITE not set 16 | 17 | .endif 18 | 19 | .include "Makefile" 20 | 21 | -------------------------------------------------------------------------------- /GNUmakefile: -------------------------------------------------------------------------------- 1 | do_nothing: 2 | 3 | virtual_env_set: 4 | 5 | ifndef VIRTUAL_ENV 6 | 7 | $(error VIRTUAL_ENV not set) 8 | 9 | endif 10 | 11 | site_set: 12 | 13 | ifndef SITE 14 | 15 | $(error SITE not set) 16 | 17 | endif 18 | 19 | include Makefile 20 | 21 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SHELL := /bin/sh 2 | 3 | # SET THIS! Directory containing wsgi.py 4 | # PROJECT := someproject 5 | 6 | LOCALPATH := ./src 7 | PYTHONPATH := $(LOCALPATH)/ 8 | SETTINGS := production 9 | DJANGO_SETTINGS_MODULE = $(PROJECT).settings.$(SETTINGS) 10 | DJANGO_POSTFIX := --settings=$(DJANGO_SETTINGS_MODULE) --pythonpath=$(PYTHONPATH) 11 | LOCAL_SETTINGS := local 12 | DJANGO_LOCAL_SETTINGS_MODULE = $(PROJECT).settings.$(LOCAL_SETTINGS) 13 | DJANGO_LOCAL_POSTFIX := --settings=$(DJANGO_LOCAL_SETTINGS_MODULE) --pythonpath=$(PYTHONPATH) 14 | TEST_SETTINGS := test 15 | DJANGO_TEST_SETTINGS_MODULE = $(PROJECT).settings.$(TEST_SETTINGS) 16 | DJANGO_POSTFIX := --settings=$(DJANGO_SETTINGS_MODULE) --pythonpath=$(PYTHONPATH) 17 | DJANGO_TEST_POSTFIX := --settings=$(DJANGO_TEST_SETTINGS_MODULE) --pythonpath=$(PYTHONPATH) 18 | PYTHON_BIN := $(VIRTUAL_ENV)/bin 19 | 20 | .PHONY: clean showenv coverage test bootstrap pip virtualenv sdist virtual_env_set 21 | 22 | showenv: 23 | @echo 'Environment:' 24 | @echo '-----------------------' 25 | @$(PYTHON_BIN)/python -c "import sys; print 'sys.path:', sys.path" 26 | @echo 'PYTHONPATH:' $(PYTHONPATH) 27 | @echo 'PROJECT:' $(PROJECT) 28 | @echo 'DJANGO_SETTINGS_MODULE:' $(DJANGO_SETTINGS_MODULE) 29 | @echo 'DJANGO_LOCAL_SETTINGS_MODULE:' $(DJANGO_LOCAL_SETTINGS_MODULE) 30 | @echo 'DJANGO_TEST_SETTINGS_MODULE:' $(DJANGO_TEST_SETTINGS_MODULE) 31 | 32 | showenv.all: showenv showenv.virtualenv showenv.site 33 | 34 | showenv.virtualenv: virtual_env_set 35 | PATH := $(VIRTUAL_ENV)/bin:$(PATH) 36 | export $(PATH) 37 | @echo 'VIRTUAL_ENV:' $(VIRTUAL_ENV) 38 | @echo 'PATH:' $(PATH) 39 | 40 | showenv.site: site_set 41 | @echo 'SITE:' $(SITE) 42 | 43 | djangohelp: virtual_env_set 44 | $(PYTHON_BIN)/django-admin.py help $(DJANGO_POSTFIX) 45 | 46 | collectstatic: virtual_env_set 47 | -mkdir -p .$(LOCALPATH)/static 48 | $(PYTHON_BIN)/django-admin.py collectstatic -c --noinput $(DJANGO_POSTFIX) 49 | 50 | runserver: virtual_env_set 51 | $(PYTHON_BIN)/django-admin.py runserver $(DJANGO_POSTFIX) 52 | 53 | syncdb: virtual_env_set 54 | $(PYTHON_BIN)/django-admin.py syncdb $(DJANGO_POSTFIX) 55 | 56 | cmd: virtual_env_set 57 | $(PYTHON_BIN)/django-admin.py $(CMD) $(DJANGO_POSTFIX) 58 | 59 | localcmd: virtual_env_set 60 | $(PYTHON_BIN)/django-admin.py $(CMD) $(DJANGO_LOCAL_POSTFIX) 61 | 62 | refresh: 63 | touch src/$(PROJECT)/*wsgi.py 64 | 65 | rsync: 66 | rsync -avz --checksum --exclude-from .gitignore --exclude-from .rsyncignore . ${REMOTE_URI} 67 | 68 | compare: 69 | rsync -avz --checksum --dry-run --exclude-from .gitignore --exclude-from .rsyncignore . ${REMOTE_URI} 70 | 71 | clean: 72 | find . -name "*.pyc" -print0 | xargs -0 rm -rf 73 | -rm -rf htmlcov 74 | -rm -rf .coverage 75 | -rm -rf build 76 | -rm -rf dist 77 | -rm -rf src/*.egg-info 78 | 79 | test: clean virtual_env_set 80 | -$(PYTHON_BIN)/coverage run $(PYTHON_BIN)/django-admin.py test $(APP) $(DJANGO_TEST_POSTFIX) 81 | 82 | coverage: virtual_env_set 83 | $(PYTHON_BIN)/coverage html --include="$(LOCALPATH)/*" --omit="*/admin.py,*/test*" 84 | 85 | predeploy: test 86 | 87 | register: virtual_env_set 88 | python setup.py register 89 | 90 | sdist: virtual_env_set 91 | python setup.py sdist 92 | 93 | upload: sdist virtual_env_set 94 | python setup.py upload 95 | make clean 96 | 97 | bootstrap: virtualenv pip virtual_env_set 98 | 99 | pip: requirements/$(SETTINGS).txt virtual_env_set 100 | pip install -r requirements/$(SETTINGS).txt 101 | 102 | virtualenv: 103 | virtualenv --no-site-packages $(VIRTUAL_ENV) 104 | echo $(VIRTUAL_ENV) 105 | 106 | all: collectstatic refresh 107 | 108 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | =============== 2 | django-makefile 3 | =============== 4 | 5 | Makefile templates to aid in development and deployment of Django sites 6 | 7 | Why Make? 8 | --------- 9 | 10 | Because it's there. 11 | 12 | Because calling commands from a file hosted with the rest of the source 13 | greatly simplifies deployment scripts. The deployment script need know 14 | of fewer paths. 15 | 16 | Because 17 | 18 | :: 19 | 20 | cd someproject-dir 21 | make test 22 | 23 | is easier to type than 24 | 25 | :: 26 | 27 | django-admin.py test --settings=someproject.settings.test --pythonpath=/path/to/project/src 28 | 29 | especially on the Monday the first working day after your vacation. 30 | 31 | Because ``fabric`` gave me indigestion. 32 | 33 | 34 | Deployment 35 | ---------- 36 | 37 | Currently I use a shell script, something along the lines of:: 38 | 39 | #!/bin/bash 40 | 41 | PROJECT_HOME="/path/to/project" 42 | REMOTE="user@remote.machine.some.domain" 43 | REMOTE_HOME="/path/on/remote/machine" 44 | REMOTE_VENV="/path/to/remote/virtualenv" 45 | LOCAL_VENV="/path/to/local/virtualenv" 46 | SECRET_KEY='production_secret_key_whatever_that_is' 47 | REMOTE_PREFIX="export SECRET_KEY='${SECRET_KEY}' " 48 | REMOTE_MAKE="${REMOTE_PREFIX} && make -C ${REMOTE_HOME} VIRTUAL_ENV=${REMOTE_VENV}" 49 | LOCAL_MAKE="make -C ${PROJECT_HOME} VIRTUAL_ENV=${LOCAL_VENV} " 50 | 51 | ${LOCAL_MAKE} REMOTE_URI=${REMOTE}:${REMOTE_HOME} rsync 52 | 53 | ssh ${REMOTE} "${REMOTE_MAKE} all" 54 | 55 | This is not under version control since it needs to be updated per project, 56 | per client machine, and per remote machine. 57 | 58 | 59 | Most Useful Targets 60 | ------------------- 61 | 62 | cmd: 63 | Runs any django command with production settings (in the CMD variable) 64 | 65 | refresh: 66 | Touches the wsgi-file, thereby refreshing/reloading the site 67 | 68 | showenv: 69 | Dumps some relevant environment variables 70 | 71 | djangohelp: 72 | Runs ``django-admin.py help`` 73 | 74 | test: 75 | Runs all tests 76 | 77 | bootstrap: 78 | Sets up a virtualenv and runs pip, provided there's a requirements-file 79 | 80 | all: 81 | Regenerates static files and reloads the site 82 | --------------------------------------------------------------------------------