Django pour les fainéants


@magopian

mathieu.agopian@gmail.com


Employé chez Novapost depuis un an
Développeur passionné, curieux

Petit rappel


Fainéant : OUI

Fait néant : aime ne rien faire.


Feignant : NON

Art de feindre : feindre ... pour échapper à une tâche.

Makefile


  • Mieux que des alias ou des scripts
  • Tout le monde partage la même méthode
  • A utiliser dans la documentation


Exemple : "pour les contributeurs : make && make test"

Makefile


.PHONY: develop test clean update

SETTINGS = myproject.settings
TEST_SETTINGS = myproject.test_settings

develop:
    virtualenv .
    bin/python setup.py develop

test:
    bin/django-admin.py test --settings=$(TEST_SETTINGS)

clean:
    bin/django-admin.py clean_pyc --settings=$(SETTINGS)

update:
    bin/pip install -U -r requirements.pip
            

Makefile


Un exemple plus complet :


Makefile de fainéant

Project Template


L'ancienne méthode

  1. cloner le dépôt
  2. modifier tous les fichiers
  3. contenant le nom du projet


La nouvelle méthode

django-admin.py startproject --template=TEMPLATE
                             --extension=py,rst,template
                             --name Makefile
                             PROJECT_NAME
            

Project template



TEMPLATE est un chemin ou une URL

vers un dossier ou un fichier compressé.

Plus d'information dans les release notes.

Project template


Trop fainéant pour faire ton propre template ?


Moi aussi (merci @brutasse)


Encore plus fort, le fab-bundle (merci @brutasse)

(et celui qui l'essaie et me fait un retour dessus ;)

Diverses astuces


En vrac

Utiliser les librairies Python


  • itertools (permutations, groupby, cycle, repeat, ...)
  • functools (partial, total_ordering)
  • collections (namedtuple, OrderedDict, defaultdict)
  • dateutil
  • sh
  • requests

Réutiliser des app django


Trouvez votre bonheur sur django packages

  • django-floppyforms
  • django-le-social
  • django-ratelimit-backend
  • django-discover-runner
  • django-nose
  • django-pipeline
  • django-secure
  • django-debug-toolbar
  • django_extensions

Réutiliser le javascript de l'admin


Voir l'exemple de prepopulated_field.js


<script src="{% static "admin/js/jquery.js" %}"></script>
<script src="{% static "admin/js/jquery.init.js" %}"></script>
<script src="{% static "admin/js/urlify.js" %}"></script>
<script src="{% static "admin/js/prepopulate.js" %}"></script>
<script>
  (function($) {
    #### CUSTOM CODE ####
  })(django.jQuery);
</script>
            

Flake8


Du bonheur en barre : pep8 + pyflakes (+ mccabe)


$ flake8 .

Pour les vrais (les utilisateurs de VIM)

syntastic (du mégabonheur en mégabarres)

SYNTASTIC


Pre-commit hooks

Parce que personne n'est parfait (même pas moi !)


  • exécuté avant chaque commit
  • valide que le commit est "propre"
  • parfait contre les oublis de "print", "import ipdb" ...

Le basique


Il est fourni directement en exemple

dans chaque dépôt git


.git/hooks/pre-commit.sample


À renommer ou symlink vers

.git/hooks/pre-commit

Le basique


Il empêche le commit si :

  • noms de fichier avec caractères non ASCII
  • erreurs de whitespace (espaces en fin de ligne)

Pour forcer le commit :


$ git commit -n

Le basique, amélioré


Fini les oublis de debug dans le code commité


# make sure there's no TODO, debugging... left
errors=0
for bad in 'import pdb' 'import ipdb' 'TODO' 'print' 'assert False'; do
    echo ">> checking for '$bad'"
    res=$(git diff-index --name-only --cached $against -S"$bad" --)
    if test -n "$res"; then  # if not empty, found some guilty files
        echo "ERROR, found '$bad' in files commited:"
        echo $res
        errors=$(($errors + 1))
    fi
done
exit $errors  # if errors, return an error: commit aborted
            

Une autre possibilité


Pour tout faire en Python (parce que c'est bon) :


https://gist.github.com/1376856


Inconvénient : teste tous les fichiers du dépôt, pas seulement les modifications à commiter

Le spécifique à la doc


https://gist.github.com/4086323


Compile la documentation Sphinx,

bloque le commit si il y a une erreur

Fainéant++


Automatiser tout ce qui peut l'être

  1. force à avoir un système propre
  2. reproductible
  3. facile à prendre en main pour un nouveau
  4. pas d'erreur de manipulation/typo
  5. j'ai dit "automatiser", ça suffit pas ?


BANDE DE FAUX FAINÉANTS !

GORUN

Lancer des commandes lors du changements de fichiers :

Gorun de Peter Bengtsson


Créer un fichier gorun_settings.py


DIRECTORIES = (
    ('vecc', 'make test'),
    ('docs', 'make doc'),
)
IGNORE_EXTENSIONS = ('swp',)
            

Profit

$ gorun.py gorun_settings

Foreman

Lancer tous les daemons en une seule fois :

Foreman de David Dollar


Créer un fichier Procfile

web: django-admin.py runserver --settings=$PROJ.settings 0.0.0.0:8000
compass: compass watch
tests: ./gorun.py gorun_settings.py
            

Profit

$ foreman start

Et pour les allergiques à ruby : gaffer de Benoît Chesneau

Foreman et Gorun


Merci qui ? @brutasse bien sûr !

Tests


I N D I S P E N S A B L E S


  • le meilleur cadeau à vous offrir
  • ou au nouveau venu sur le projet
  • ou à votre futur vous
  • je sais même pas pourquoi on en discute

Valider les templates


https://gist.github.com/4086398


  1. récupérer tous les répertoires de templates
  2. faire la liste de tous les templates (*.html et *.txt)
  3. vérifier que le template "compile" (Template(t))
  4. vérifier qu'il y a autant de {% que de %}
  5. vérifier qu'il y a autant de {{ que de }}

Valider les fixtures


https://gist.github.com/4086449



  1. récupérer tous les répertoires "fixtures"
  2. faire la liste de toutes les fixtures (*.json)
  3. vérifier que le nombre de fixtures n'a pas bougé
  4. vérifier que chaque fixture est chargée sans erreur

Le top de l'automatisation


Jenkins

a déployer et configurer soi-même


Travis 

magique !

gratuit

automatique sur les projets github publics

donne le statut des branches et des PRs !

Exemple de configuration Travis

Ajouter un fichier .travis.yml


language: python
python:
    - "2.6"
    - "2.7"
install:
    - pip install -r test-requirements.txt --use-mirrors
    - python setup.py develop
script: unit2 discover -v && flake8 circus
notifications:
    email: tarek@mozilla.com
    irc: "irc.freenode.org#mozilla-circus"
    on_success: change
            

Créer son compte Travis

Activer travis sur le dépôt

Travis en local : Tox

Installer tox : pip install tox


Ajouter un fichier tox.ini

[tox]
envlist = py26,py27,docs,flake8

[testenv]
deps = -r{toxinidir}/test-requirements.txt
commands =
    python setup.py develop
    unit2 discover -v

[testenv:docs]
commands = /usr/bin/make docs

[testenv:flake8]
commands = flake8 circus
            

Des questions ?


http://mathieu.agopian.info/presentations/2012_djangocon_toulouse/