Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Restructured/refactored project. #21

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]

# Temporary files:
*.swp
*.py[co]
*.egg*
*~

{{cookiecutter.project_name}}/requirements.txt
.*
!.gitignore
!.travis.yml

__pycache__/
build/
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ python:
install:
- pip install pip -U
- pip install -r requirements.txt
- pip install -r {{cookiecutter.project_name}}/requirements.in
- pip install -r {{cookiecutter.project_slug}}/requirements.in

script:
- ./runtests.sh
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Change Log
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/) but
uses date-based versions to make it easy to track changes over time.

## 2018-11-06
### Added
- Project can now be deployed to servers using Fabric and Invoke.
- Added celery for running scheduled and background tasks.
- Site is now served over HTTPS.
79 changes: 67 additions & 12 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
Wildfish Django Starter
=====================
=======================

.. image:: https://travis-ci.org/wildfish/wildfish-django-starter.svg?branch=master
:alt: Build Status
:target: https://travis-ci.org/wildfish/wildfish-django-starter

A Django 2.0 friendly project cookiecutter template to kick start development for new projects. Includes apps and settings we use in the majority of projects, along with an integrated version of our other cookiecutter-django-crud template which will also generate a model, CRUD views and tests.

A Django 2.0 friendly project cookiecutter template to kick start development
for new projects. Includes apps and settings we use in the majority of projects,
along with an integrated version of our other cookiecutter-django-crud template
which will also generate a model, CRUD views and tests.

Features
----------
--------

* 2 tier layout
* Python essentials: ipython, ipdb, flake8
Expand All @@ -22,33 +25,85 @@ Features
* A Django ModelForm using bootstrap3.
* Tests for all of the views using WebTest.
* Model Mommy generated models for the tests.
* Use Vagrant for 'local' deployments.
* Deploy to any server using Fabric and Invoke.


Quickstart
----------
Install Vagrant and virtualbox::

sudo apt-get install vagrant virtualbox

Ensure you have cookiecutter installed::
Ensure you have cookiecutter and pip-tools installed::

pip install cookiecutter
pip install pip-tools

Then use cookiecutter to generate your project from this template with::

cookiecutter git@github.com:wildfish/wildfish-django-starter.git

Then from your generated project::
The Vagrant VM is assigned a static IP address of 192.168.10.10. You will need
to add this address to your /etc/hosts file to access the web site::

192.168.10.10 <project_slug>.local

where <project_slug> is the value you chose when generating the project from
the cookiecutter template.

Then from your generated project you can deploy the full project to a local
Vagrant instance using::

npm install

pip install -r requirements.in
pip-compile requirements.in

python manage.py migrate
vagrant up --provision

vagrant ssh-config > ssh-config

fab -H <project_slug>.local --ssh-config ssh-config deploy.full

Don't forget to replace <project_slug> with the actual value you used.

Requirements using pip-compile
----------
------------------------------

The generated project uses a requirements.in file to make it straightforward to keep pinned requirements up to date using the ``pip-compile`` command from ``pip-tools``.
The generated project uses a requirements.in file to make it straightforward
to keep pinned requirements up to date using the ``pip-compile`` command
from ``pip-tools``.

To generate a requirements.txt from your project simply use the ``pip-compile`` command.

Read more here, https://github.com/nvie/pip-tools#example-usage-for-pip-compile

Project layout
--------------
The deployed site has a specific project layout as follows::

<project_slug>
+-- logs
+-- media
+-- run
+-- static
+-- venv
+-- <project_slug>
+-- manage.py
+-- requirements.txt
+-- templates/
+-- uwsgi.ini
+-- <project_slug>
+-- settings.py
+-- uwsgi.py

Everything is self contained and specified relative to the root, <project_slug>, directory.
Configuration files for nginx and supervisor are installed in /etc/nginx/sites-available and
/etc/supervisor/conf.d/ respectively.

All the paths are defined in the file, fabric.json, which is generated by Cookiecutter and
used by Fabric during the deployment. You can edit the file to set the locations according
to your preferred layout. If you have slightly different layouts for staging and production
servers for example, simply copy the file and pass it on the command line when you deploy
the project::

fab -H staging --config staging.json deploy.full

20 changes: 11 additions & 9 deletions cookiecutter.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
{
"project_title": "New Project",
"project_name": "newproject",
"author_name": "Your name",
"author_email": "you@somewhere.com",
"domain_name": "wildfish.com",
"secret_key": "Change me to a random string!",
"project_name": "Project",
"project_slug": "{{cookiecutter.project_name|lower|replace(' ', '_')|replace('.', '_') }}",
"python_version": "3.6",
"install_dir": "/home/vagrant/sites/{{cookiecutter.project_slug }}",
"django_admin_name": "Django Admin",
"django_admin_email": "admin@example.com",
"subdomain": "www",
"domain": "example.com",
"time_zone": "Europe/London",
"host_user": "{{cookiecutter.project_slug }}",
"email_user": "",
"email_password": "",
"sentry_dsn": "",
"app_name": "things",
"model_name": "Thing",
"model_name_lower": "{{ cookiecutter.model_name|lower }}"
"app_name": "app",
"model_name": "App"
}
32 changes: 32 additions & 0 deletions hooks/post_gen_project.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/env python

import os
import random
import string

from jinja2 import Environment, FileSystemLoader


def render_template(template, context):
env = Environment(loader=FileSystemLoader(os.getcwd()))
template = env.get_template(template)
return template.render(**context)


if __name__ == '__main__':

settings_path = '{{cookiecutter.project_slug }}/settings.py'

secret_key = ''.join(
random.SystemRandom().choice(
string.ascii_uppercase + string.ascii_lowercase + string.digits
) for _ in range(64)
)

settings = render_template(settings_path, {
'secret_key': secret_key
})

with open(settings_path, 'wb') as fh:
fh.write(settings.encode('utf-8'))

13 changes: 10 additions & 3 deletions runtests.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
#!/bin/bash

# cookiecutter will overwrite the project if it already exists. That ensures
# the tests will run for each python version even if one fails. We also want
# to remove the generated project so that everything is left in a clean state.

set -e
py.test
cookiecutter ./ --no-input
cd newproject
cookiecutter . --no-input --overwrite-if-exists
cd project
npm install
pip install -r requirements.in
python manage.py makemigrations
python manage.py test
cd ..
rm -rf newproject
rm -rf project
4 changes: 2 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[pytest]
[tools:pytest]
python_paths = .
norecursedirs = .tox .git */migrations/* */static/* docs venv */{{cookiecutter.project_name}}/*
norecursedirs = .tox .git */migrations/* */static/* docs venv */{{cookiecutter.project_slug}}/*
25 changes: 19 additions & 6 deletions tests/base.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import os
import random
import shutil
import string
import sys
import unittest
from os.path import exists, dirname, join

Expand All @@ -15,9 +18,16 @@ class DjangoCookieTestCase(unittest.TestCase):
destpath = None

def generate_project(self, extra_context=None):

secret_key = ''.join(
random.SystemRandom().choice(
string.ascii_uppercase + string.ascii_lowercase + string.digits
) for _ in range(64)
)

ctx = {
'project_title': 'Some New Project',
'project_name': 'thenewtestproject',
'project_name': 'Test Project',
'project_slug': 'test_project',
'author_name': 'Your name',
'author_email': 'you@somewhere.com',
'domain_name': 'wildfish.com',
Expand All @@ -26,17 +36,20 @@ def generate_project(self, extra_context=None):
'email_user': '',
'email_password': '',
'sentry_dsn': '',
'app_name': 'testthings',
'model_name': 'TestThing'
'app_name': 'test_app',
'model_name': 'TestApp',
'secret_key': secret_key,
'python_version': '{}.{}'.format(sys.version_info[0], sys.version_info[1])
}

if extra_context:
assert isinstance(extra_context, dict)
ctx.update(extra_context)

self.ctx = ctx
self.destpath = join(self.root_dir, self.ctx['project_name'])
self.destpath = join(self.root_dir, 'build', self.ctx['project_slug'])

cookiecutter(template='./', checkout=None, no_input=True, extra_context=ctx)
cookiecutter('./', checkout=None, no_input=True, overwrite_if_exists=True, extra_context=ctx)

# Build a list containing absolute paths to the generated files
paths = [os.path.join(dirpath, file_path)
Expand Down
13 changes: 13 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Tox (https://tox.readthedocs.io/) is a tool for running tests
# in multiple virtualenvs. This configuration file will run the
# test suite on all supported python versions. To use it, "pip install tox"
# and then run "tox" from this directory.

[tox]
envlist = py34, py35, py36
skipsdist=True

[testenv]
deps = -rrequirements.txt
commands = ./runtests.sh

28 changes: 0 additions & 28 deletions {{cookiecutter.project_name}}/.gitignore

This file was deleted.

10 changes: 0 additions & 10 deletions {{cookiecutter.project_name}}/etc/uwsgi.ini

This file was deleted.

7 changes: 0 additions & 7 deletions {{cookiecutter.project_name}}/scripts/entrypoint.sh

This file was deleted.

3 changes: 0 additions & 3 deletions {{cookiecutter.project_name}}/scripts/reset-db.sh

This file was deleted.

Empty file.

This file was deleted.

Loading