From 6f10938138ff6017779d03be24c7ed012dbc90a9 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Tue, 3 Feb 2015 17:01:35 +0100 Subject: [PATCH] Add bootstrap and test. Py3.4 by default, move to django_cas_ng and fnpdeploy. --- bootstrap.sh | 133 ++++++++++++++++++++ src/_gitignore | 1 + src/fabfile.py | 4 +- src/requirements-dev.txt | 4 +- src/requirements.txt | 11 +- src/src/project_name/settings/apps.py | 3 - src/src/project_name/settings/auth.py | 12 +- src/src/project_name/settings/basic.py | 4 + src/src/project_name/settings/context.py | 6 +- src/src/project_name/settings/contrib.py | 3 +- src/src/project_name/settings/middleware.py | 22 +--- src/src/project_name/settings/static.py | 2 +- src/src/project_name/urls.py | 25 ++-- tests/test_bootstrap.sh | 44 +++++++ 14 files changed, 217 insertions(+), 57 deletions(-) create mode 100644 bootstrap.sh create mode 100755 tests/test_bootstrap.sh diff --git a/bootstrap.sh b/bootstrap.sh new file mode 100644 index 0000000..0059599 --- /dev/null +++ b/bootstrap.sh @@ -0,0 +1,133 @@ +# +# Use as: +# +# source <(curl https://py.mdrn.pl/django) +# + + +# Make it a function, so that it works with `source` +start_project() { + +local DJANGO_REQ='Django>=1.7,<1.8' +local DJANGO_ROOT='src' +local PYPI='https://py.mdrn.pl:8443/simple' +local DEFAULT_PYTHON="`which python3.4`" + +if [ -z "$DEFAULT_PYTHON" ]; then + DEFAULT_PYTHON="`which python3`" +fi +if [ -z "$DEFAULT_PYTHON" ]; then + DEFAULT_PYTHON="`which python`" +fi + +local PROJECT=$PROJECT +if [ -z "$PROJECT" ]; then + PROJECT="$1" +fi + +if [ -z "$FNP_PROJECT_TEMPLATE" ]; then + local FNP_PROJECT_TEMPLATE='https://git.mdrn.pl/fnp-django-template.git/snapshot/HEAD.tar.gz' +fi + +local VIRTUALENVWRAPPER_PATHS=" + /etc/bash_completion.d/virtualenvwrapper + /usr/bin/virtualenvwrapper.sh + /usr/local/bin/virtualenvwrapper.sh +" + +# Colorful output. +local strong='\e[0;32m' +local error='\e[1;31m' +local normal='\e[0m' + +local PYTHON="$PYTHON" +if [ -z "$PYTHON" ]; then + echo "Defaulting to $DEFAULT_PYTHON." + PYTHON="$DEFAULT_PYTHON" +fi + + +echo "Create new Django project." +while [ -z "$PROJECT" ] +do + echo "Name of the project:" + read PROJECT +done +echo -e "Project: ${strong}${PROJECT}${normal}" + +if ! type mkvirtualenv > /dev/null; then + for venv in $VIRTUALENVWRAPPER_PATHS + do + if [ -e "$venv" ] + then + local VIRTUALENVWRAPPER="$venv" + break + fi + done + if [ "$VIRTUALENVWRAPPER" ] + then + echo "virtualenvwrapper found at $VIRTUALENVWRAPPER." + source "$VIRTUALENVWRAPPER" + else + echo -e "${error}ERROR: virtualenvwrapper not found. Tried locations:${normal}" + echo "$VIRTUALENVWRAPPER_PATHS" + echo -e "${error}Install virtualenvwrapper or add the correct path to this script.${normal}" + echo "Aborting." + return + fi +fi + +echo -e "${strong}Creating virtualenv: $PROJECT $PYTHON...${normal}" +mkvirtualenv "$PROJECT" --python "$PYTHON" +echo -e "${strong}Upgrading pip...${normal}" +pip install -i "$PYPI" -U pip +echo -e "${strong}Installing Django...${normal}" +pip install -i "$PYPI" "$DJANGO_REQ" +pip install -i "$PYPI" --pre django-startproject-plus + +echo -e "${strong}Downloading project template...${normal}" +if [[ "$FNP_PROJECT_TEMPLATE" =~ ^(https?|ftp):// ]]; then + local PROJECT_TMPDIR=`mktemp -d fnp-django-template-XXX` + curl "$FNP_PROJECT_TEMPLATE" | tar xzf - -C "$PROJECT_TMPDIR" + local TEMPLATE="$PROJECT_TMPDIR"/fnp-django-template-*/src +else + local TEMPLATE="$FNP_PROJECT_TEMPLATE" +fi + +echo -e "${strong}Starting the project...${normal}" +django-startproject.py \ + --template "$TEMPLATE" \ + --name NOTICE \ + --extra_context='{"year": "`date +%Y`"}' \ + "$PROJECT" + +if [ -n "$PROJECT_TMPDIR" ]; then + rm -rf "$PROJECT_TMPDIR" +fi + +cd "$PROJECT" + +chmod +x "$DJANGO_ROOT"/manage.py +mv _gitignore .gitignore + +echo -e "${strong}Installing requirements...${normal}" +pip install -i "$PYPI" -r requirements.txt +echo -e "${strong}Installing developer requirements...${normal}" +pip install -i "$PYPI" -r requirements-dev.txt +echo -e "${strong}Running syncdb...${normal}" +"$DJANGO_ROOT"/manage.py syncdb --noinput + +echo -e "${strong}Starting new git repository...${normal}" +git init + +echo -e "${strong}What next?${normal}" +echo " * Work on your app, commit to git." +echo " * Review fabfile, use fab for deployment." + + +} +start_project + +# The following is just for displaying it as a webpage:

source <(curl )

+ diff --git a/src/_gitignore b/src/_gitignore index d376dd0..3fd46ac 100644 --- a/src/_gitignore +++ b/src/_gitignore @@ -1,3 +1,4 @@ +/var localsettings.py *~ *.orig diff --git a/src/fabfile.py b/src/fabfile.py index 6196757..2f0fe53 100644 --- a/src/fabfile.py +++ b/src/fabfile.py @@ -1,11 +1,11 @@ -from fnpdjango.deploy import * +from fnpdeploy import * env.project_name = '{{ project_name }}' env.hosts = ['giewont.icm.edu.pl'] env.user = '{{ project_name }}' env.app_path = '/srv/{{ project_name }}' env.services = [ - DebianGunicorn('{{ project_name }}'), + Supervisord('{{ project_name }}'), ] env.django_root_path = 'src' diff --git a/src/requirements-dev.txt b/src/requirements-dev.txt index 108a2ec..fe1e0c6 100644 --- a/src/requirements-dev.txt +++ b/src/requirements-dev.txt @@ -1 +1,3 @@ -fabric>=1.5,<1.6 +-i https://py.mdrn.pl:8443/simple + +fnpdeploy diff --git a/src/requirements.txt b/src/requirements.txt index 6568c8e..aea9e3c 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -1,14 +1,13 @@ --i http://pypi.nowoczesnapolska.org.pl/simple +-i https://py.mdrn.pl:8443/simple -Django>=1.6,<1.7 -South>=0.7.4 -django-pipeline>=1.2,<1.3 +Django>=1.7,<1.8 +django-pipeline>=1.3,<1.4 django-piwik #pyScss #git+git://github.com/Kronuz/pyScss.git@d8f4da23a3c87696a75b3830ed4ab49b75550a93#egg=pyScss #TODO: pyScss support, for now just install sass -django_cas>=2.1,<2.2 -fnpdjango<0.2 +django_cas_ng>=3.4,<3.5 +fnpdjango>=0.2,<0.3 ipython diff --git a/src/src/project_name/settings/apps.py b/src/src/project_name/settings/apps.py index 1ab943f..bf246ff 100644 --- a/src/src/project_name/settings/apps.py +++ b/src/src/project_name/settings/apps.py @@ -1,12 +1,9 @@ INSTALLED_APPS = ( '{{ project_name }}', 'fnpdjango', - 'south', 'pipeline', # Disable, if not using Piwik. 'piwik', - # Disable, if not using CAS. - 'django_cas', 'django.contrib.auth', 'django.contrib.contenttypes', diff --git a/src/src/project_name/settings/auth.py b/src/src/project_name/settings/auth.py index d53af51..e914ebb 100644 --- a/src/src/project_name/settings/auth.py +++ b/src/src/project_name/settings/auth.py @@ -1,8 +1,6 @@ -from . import INSTALLED_APPS +# Remove if not using CAS. +AUTHENTICATION_BACKENDS = ( + 'django.contrib.auth.backends.ModelBackend', + 'django_cas_ng.backends.CASBackend', +) - -if 'django_cas' in INSTALLED_APPS: - AUTHENTICATION_BACKENDS = ( - 'django.contrib.auth.backends.ModelBackend', - 'fnpdjango.auth_backends.AttrCASBackend', - ) diff --git a/src/src/project_name/settings/basic.py b/src/src/project_name/settings/basic.py index da47145..f5dcfb8 100644 --- a/src/src/project_name/settings/basic.py +++ b/src/src/project_name/settings/basic.py @@ -18,6 +18,10 @@ DATABASES = { SITE_ID = 1 +SILENCED_SYSTEM_CHECKS = [ + '1_6.W001', + ] + # List of callables that know how to import templates from various sources. TEMPLATE_LOADERS = ( 'django.template.loaders.filesystem.Loader', diff --git a/src/src/project_name/settings/context.py b/src/src/project_name/settings/context.py index ec4ef61..46eea9d 100644 --- a/src/src/project_name/settings/context.py +++ b/src/src/project_name/settings/context.py @@ -2,14 +2,12 @@ from . import INSTALLED_APPS TEMPLATE_CONTEXT_PROCESSORS = tuple(x for x in ( - "django.contrib.auth.context_processors.auth" - if "django.contrib.auth" in INSTALLED_APPS else None, + "django.contrib.auth.context_processors.auth", "django.core.context_processors.debug", "django.core.context_processors.i18n", "django.core.context_processors.media", "django.core.context_processors.static", "django.core.context_processors.tz", - "django.contrib.messages.context_processors.messages" - if 'django.contrib.messages' in INSTALLED_APPS else None, + "django.contrib.messages.context_processors.messages", "django.core.context_processors.request" ) if x is not None) diff --git a/src/src/project_name/settings/contrib.py b/src/src/project_name/settings/contrib.py index 6db84f1..fe850ed 100644 --- a/src/src/project_name/settings/contrib.py +++ b/src/src/project_name/settings/contrib.py @@ -1,2 +1,3 @@ -CAS_SERVER_URL = 'http://logowanie.nowoczesnapolska.org.pl/cas/' +# CAS-specific +CAS_SERVER_URL = 'https://logowanie.nowoczesnapolska.org.pl/cas/' CAS_VERSION = '3' diff --git a/src/src/project_name/settings/middleware.py b/src/src/project_name/settings/middleware.py index 80ffc44..7f6ba73 100644 --- a/src/src/project_name/settings/middleware.py +++ b/src/src/project_name/settings/middleware.py @@ -1,25 +1,15 @@ -from . import INSTALLED_APPS - -MIDDLEWARE_CLASSES = tuple(x for x in ( - 'django.contrib.sessions.middleware.SessionMiddleware' - if "django.contrib.sessions" in INSTALLED_APPS else None, +MIDDLEWARE_CLASSES = [ + 'django.contrib.sessions.middleware.SessionMiddleware', #'django.middleware.locale.LocaleMiddleware', 'fnpdjango.middleware.URLLocaleMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware' - if "django.contrib.auth" in INSTALLED_APPS else None, - 'django_cas.middleware.CASMiddleware' - if "django_cas" in INSTALLED_APPS else None, - 'django.contrib.messages.middleware.MessageMiddleware' - if "django.contrib.messages" in INSTALLED_APPS else None, - 'piwik.django.middleware.PiwikMiddleware' - if "piwik.django" in INSTALLED_APPS else None, + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django_cas_ng.middleware.CASMiddleware', # Remove if not using CAS. + 'django.contrib.messages.middleware.MessageMiddleware', # Uncomment the next line for simple clickjacking protection: # 'django.middleware.clickjacking.XFrameOptionsMiddleware', - 'pagination.middleware.PaginationMiddleware' - if "pagination" in INSTALLED_APPS else None, 'fnpdjango.middleware.SetRemoteAddrFromXRealIP' -) if x is not None) +] diff --git a/src/src/project_name/settings/static.py b/src/src/project_name/settings/static.py index 9349365..32be508 100644 --- a/src/src/project_name/settings/static.py +++ b/src/src/project_name/settings/static.py @@ -1,5 +1,5 @@ from os import path -from paths import PROJECT_DIR +from .paths import PROJECT_DIR MEDIA_ROOT = path.join(PROJECT_DIR, 'var/media/') diff --git a/src/src/project_name/urls.py b/src/src/project_name/urls.py index c579b39..3303eb4 100644 --- a/src/src/project_name/urls.py +++ b/src/src/project_name/urls.py @@ -1,29 +1,21 @@ from django.conf.urls import patterns, include, url from django.conf import settings +from django.contrib import admin urlpatterns = patterns('', # Examples: # url(r'^$', '{{ project_name }}.views.home', name='home'), # url(r'^{{ project_name }}/', include('foo.urls')), -) - -# Admin stuff, if necessary. -if 'django.contrib.admin' in settings.INSTALLED_APPS: - from django.contrib import admin - admin.autodiscover() - urlpatterns += patterns('', - url(r'^admin/doc/', include('django.contrib.admindocs.urls')), - url(r'^admin/', include(admin.site.urls)), - ) + # Admin stuff. + url(r'^admin/doc/', include('django.contrib.admindocs.urls')), + url(r'^admin/', include(admin.site.urls)), -# Auth stuff, if necessary -if 'django_cas' in settings.INSTALLED_APPS: - urlpatterns += patterns('', - (r'^accounts/login/$', 'django_cas.views.login'), - (r'^accounts/logout/$', 'django_cas.views.logout'), - ) + # CAS stuff. + url(r'^accounts/login/$', 'django_cas_ng.views.login'), + url(r'^accounts/logout/$', 'django_cas_ng.views.logout'), +) # Media in DEBUG mode if settings.DEBUG: @@ -32,3 +24,4 @@ if settings.DEBUG: 'document_root': settings.MEDIA_ROOT, }), ) + diff --git a/tests/test_bootstrap.sh b/tests/test_bootstrap.sh new file mode 100755 index 0000000..68e1c6f --- /dev/null +++ b/tests/test_bootstrap.sh @@ -0,0 +1,44 @@ +#!/bin/bash +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +# Colorful output. +strong='\e[0;32m' +error='\e[1;31m' +normal='\e[0m' + +tmpdir="`mktemp -d "$DIR/test-XXX"`" +echo "$tmpdir" + + +export WORKON_HOME="$tmpdir/v" +mkdir "$WORKON_HOME" + + +PYTHON="$1" +if [ -z "$PYTHON" ]; then + PYTHON=python +fi +PYTHON_VER="`$PYTHON -V 2>&1`" +echo -e "${strong}Using $PYTHON_VER${normal}" +PYTHON="`which $PYTHON`" + +FNP_PROJECT_TEMPLATE="$DIR"/.. +projectdir="$tmpdir"/p +mkdir "$projectdir" +cd "$projectdir" +. "$DIR"/../bootstrap.sh TEST_PROJECT --python "$PYTHON" + + +# Test for active virtualenv +if [ "$VIRTUAL_ENV" != "$WORKON_HOME/TEST_PROJECT" ]; then + echo -e "${error}Expected to be in virtualenv, found python: `which python`${normal}" +fi +if [ "`python -V 2>&1`" != "$PYTHON_VER" ]; then + echo -e "${error}Expected $PYTHON_VER, found `python -V 2>&1`${normal}" +fi + +# Test that there is only project dir in the dir. +if [ "`ls "$projectdir"`" != "TEST_PROJECT" ]; then + echo -e "${error}Only created project expected in project dir, found: `ls "$projectdir"`${normal}" +fi + +rm -rf "$tmpdir" -- 2.20.1