diff --git a/README.md b/README.md index a641142..8a70e74 100644 --- a/README.md +++ b/README.md @@ -39,11 +39,11 @@ $ gem install asciidoctor-diagram ```bash asciidoctor -a rouge-style=monokai -a pdf-themesdir=resources/themes -a pdf-theme=gwift main.adoc -t -r asciidoctor-diagram -asciidoctor-pdf -a rouge-style=monokai -a pdf-themesdir=resources/themes -a pdf-theme=gwift main.adoc -t -r asciidoctor-diagram +asciidoctor-pdf -a pdf-themesdir=resources/themes -a pdf-theme=gwift main.adoc -t -r asciidoctor-diagram ``` ## Configuration de l'espace utilisateur ```bash source /usr/share/powerline/bindings/bash/powerline.sh -``` \ No newline at end of file +``` diff --git a/source/toolchain/django.adoc b/source/part-1-workspace/django.adoc similarity index 100% rename from source/toolchain/django.adoc rename to source/part-1-workspace/django.adoc diff --git a/source/toolchain/documentation.adoc b/source/part-1-workspace/documentation.adoc similarity index 100% rename from source/toolchain/documentation.adoc rename to source/part-1-workspace/documentation.adoc diff --git a/source/toolchain/external_tools.adoc b/source/part-1-workspace/external_tools.adoc similarity index 100% rename from source/toolchain/external_tools.adoc rename to source/part-1-workspace/external_tools.adoc diff --git a/source/part-1-workspace/main.adoc b/source/part-1-workspace/main.adoc index 57de937..c8541aa 100644 --- a/source/part-1-workspace/main.adoc +++ b/source/part-1-workspace/main.adoc @@ -4,7 +4,7 @@ Avant de démarrer le développement, il est nécessaire de passer un peu de tem Les morceaux de code seront développés pour Python3.6+ et Django 3.0+. Ils nécessiteront peut-être quelques adaptations pour fonctionner sur une version antérieure. -Django fonctionne sur un link:roulement de trois versions mineures pour une version majeure[https://docs.djangoproject.com/en/dev/internals/release-process/], clôturé par une version LTS (_Long Term Support_). +Django fonctionne sur un link:++roulement de trois versions mineures pour une version majeure++[https://docs.djangoproject.com/en/dev/internals/release-process/], clôturé par une version LTS (_Long Term Support_). image::http://ser-libre.com.ar/wp-content/uploads/2016/11/django.png[Support des versions Django] @@ -26,12 +26,12 @@ include::environment.adoc[] include::venvs.adoc[] -include::toolchain/django.adoc[] +include::django.adoc[] -include::toolchain/tools.adoc[] +include::tools.adoc[] -include::toolchain/external_tools.adoc[] +include::external_tools.adoc[] include::unit_tests.adoc[] -include::toolchain/summary.adoc[] \ No newline at end of file +include::summary.adoc[] \ No newline at end of file diff --git a/source/toolchain/maintainable-applications.adoc b/source/part-1-workspace/maintainable-applications.adoc similarity index 97% rename from source/toolchain/maintainable-applications.adoc rename to source/part-1-workspace/maintainable-applications.adoc index b21742a..684cda2 100644 --- a/source/toolchain/maintainable-applications.adoc +++ b/source/part-1-workspace/maintainable-applications.adoc @@ -1,6 +1,6 @@ == Construire des applications maintenables -Pour cette section, je me base d'un résumé de l'ebook **Building Maintenable Software** disponible chez link:O'Reilly[http://shop.oreilly.com/product/0636920049555.do]. +Pour cette section, je me base d'un résumé de l'ebook **Building Maintenable Software** disponible chez link:++O'Reilly++[http://shop.oreilly.com/product/0636920049555.do]. Ce livre répartit un ensemble de conseils parmi quatre niveaux de composants: diff --git a/source/part-1-workspace/summary.adoc b/source/part-1-workspace/summary.adoc new file mode 100644 index 0000000..3001093 --- /dev/null +++ b/source/part-1-workspace/summary.adoc @@ -0,0 +1,6 @@ +== En résumé + +* Créez systématiquement un environnement virtuel pour chaque projet sur lequel vous travaillez +* La description des dépendances utilisées pour un projet doivent faire partie intégrante des sources + +C'est ici que le projet http://cookiecutter.readthedocs.io/en/latest/readme.html[CookieCutter] va être intéressant: les X premières étapes peuvent être *bypassées* par une simple commande. diff --git a/source/toolchain/tools.adoc b/source/part-1-workspace/tools.adoc similarity index 100% rename from source/toolchain/tools.adoc rename to source/part-1-workspace/tools.adoc diff --git a/source/part-1-workspace/venvs.adoc b/source/part-1-workspace/venvs.adoc index fff3929..7e333b2 100644 --- a/source/part-1-workspace/venvs.adoc +++ b/source/part-1-workspace/venvs.adoc @@ -7,11 +7,11 @@ Cette section est aussi utile pour une personne travaillant seule, que pour tran Cette pratique est cependant fortement déconseillée pour plusieurs raisons: . Il est tout à fait envisagable que deux applications différentes soient déployées sur un même hôte, et nécessitent chacune deux versions différentes d'une même dépendance. -. Pour la reproductibilité d'un environnement spécifique. Cela évite notamment les réponses type "Ca juste marche chez moi", puisque la construction d'un nouvel environnement fait partie de la documentation du projet; grace à elle, on a la possibilité de construire un environnement sain et d'appliquer des dépendances identiques, quelle que soit la machine hôte. +. Pour la reproductibilité d'un environnement spécifique. Cela évite notamment les réponses type "Ca juste marche chez moi", puisque la construction d'un nouvel environnement fait partie intégrante du processus de construction et de la documentation du projet; grace à elle, on a la possibilité de construire un environnement sain et d'appliquer des dépendances identiques, quelle que soit la machine hôte. image::https://res.cloudinary.com/teepublic/image/private/s--hOdhXtVV--/t_Preview/b_rgb:ffffff,c_limit,f_jpg,h_630,q_90,w_630/v1464028809/production/designs/521845_1.jpg -Depuis la version 3.5 de Python, le module `venv` est link:recommandé[https://docs.python.org/3/library/venv.html] afin de créer un environnement virtuel. +Depuis la version 3.5 de Python, le module `venv` est https://docs.python.org/3/library/venv.html[recommandé] afin de créer un environnement virtuel. Il existe plusieurs autres modules permettant d'arriver au même résultat, avec quelques avantages et inconvénients pour chacun d'entre eux. @@ -24,20 +24,20 @@ Commencons par créer un environnement virtuel, afin d'y stocker les dépendance Ceci créera l'arborescence de fichiers suivante, qui peut à nouveau être un peu différente en fonction du système d'exploitation: [source,bash] ---- +---- fred@aerys:~/Sources/.venvs/gwift-env$ ls bin include lib lib64 pyvenv.cfg share ---- +---- Nous pouvons ensuite l'activer grâce à la commande `source gwift-env/bin/activate`. [source,bash] ---- +---- (gwift-env) fred@aerys:~/Sources/.venvs/gwift-env$ <1> ---- +---- <1> Le *shell* signale que nous sommes bien dans l'environnement `gwift-env`. -Par la suite, nous considérerons que l'environnement virtuel est toujours activé, même si ``gwift-env`` à chaque snippet de code. +Par la suite, nous considérerons que l'environnement virtuel est toujours activé, même si `gwift-env` à chaque snippet de code. A présent que l'environnement est activé, tous les binaires de cet environnement prendront le pas sur les binaires du système. De la même manière, une variable `PATH` propre est définie et utilisée, afin que les librairies Python y soient stockées. C'est donc dans cet environnement virtuel que nous retrouverons le code source de Django, ainsi que des librairies externes pour Python une fois que nous les aurons installées. @@ -49,7 +49,7 @@ Pour désactiver l'environnement virtuel, il suffit d'utiliser la commande `deac === Installation de Django et création du répertoire de travail -Après avoir activé l'environnement, on peut à présent y installer Django. La librairie restera indépendante du reste du système, et ne polluera aucun autre projet. +Après avoir activé l'environnement, on peut à présent y installer Django. Comme expliqué ci-dessus, la librairie restera indépendante du reste du système, et ne polluera aucun autre projet. C'est parti: `pip install 'django<3.1' ! @@ -65,20 +65,21 @@ Successfully installed django-3.0.5 Les commandes de création d'un nouveau site sont à présent disponibles, la principale étant `django-admin startproject`. Par la suite, nous utiliserons `manage.py`, qui constitue un *wrapper* autour de `django-admin`. -Pour démarrer notre projet, nous lançons donc ``django-admin startproject gwift``. +Pour démarrer notre projet, nous lançons donc `django-admin startproject gwift`. [source,bash] ---- $ django-admin startproject gwift ---- -Cette action a pour effet de créer un nouveau dossier ``gwift``, dans lequel on trouve la structure suivante: +Cette action a pour effet de créer un nouveau dossier `gwift`, dans lequel on trouve la structure suivante: [source,bash] ---- $ tree gwift gwift ├── gwift +| |── asgi.py │   ├── __init__.py │   ├── settings.py │   ├── urls.py @@ -86,7 +87,19 @@ gwift └── manage.py ---- -C'est sans ce répertoire que vont vivre tous les fichiers liés au projet. Le but est de faire en sorte que toutes les opérations (maintenance, déploiement, écriture, tests, ...) puissent se faire à partir d'un seul point d'entrée. Tant qu'on y est, nous pouvons rajouter les répertoires utiles à la gestion de notre projet, à savoir la documentation, les dépendances et le README: +C'est sans ce répertoire que vont vivre tous les fichiers liés au projet. Le but est de faire en sorte que toutes les opérations (maintenance, déploiement, écriture, tests, ...) puissent se faire à partir d'un seul point d'entrée. + +L'utilité de ces fichiers est définie ci-dessous: + + * `settings.py` contient tous les paramètres globaux à notre projet. + * `urls.py` contient les variables de routes, les adresses utilisées et les fonctions vers lesquelles elles pointent. + * `manage.py`, pour toutes les commandes de gestion. + * `asgi.py` contient la définition de l'interface https://en.wikipedia.org/wiki/Asynchronous_Server_Gateway_Interface[ASGI], le protocole pour la passerelle asynchrone entre votre application et le serveur Web. + * `wsgi.py` contient la définition de l'interface https://en.wikipedia.org/wiki/Web_Server_Gateway_Interface[WSGI], qui permettra à votre serveur Web (Nginx, Apache, ...) de faire un pont vers votre projet. + +NOTE: déplacer la configuration dans un répertoire `config` à part. + +Tant qu'on y est, nous pouvons rajouter les répertoires utiles à la gestion de notre projet, à savoir la documentation, les dépendances et le README: [source,bash] ---- @@ -96,45 +109,78 @@ $ touch docs/README.md [source,bash] ---- -$ tree gwift +(gwift) fred@aerys:~/Sources$ tree gwift gwift +├── docs +│   └── README.md ├── gwift +│   ├── asgi.py │   ├── __init__.py │   ├── settings.py │   ├── urls.py │   └── wsgi.py └── manage.py -|-- docs/ -|-- requirements/ -|-- README ---- -Chacun de ces fichiers sert à: - - * ``settings.py`` contient tous les paramètres globaux à notre projet. - * ``urls.py`` contient les variables de routes, les adresses utilisées et les fonctions vers lesquelles elles pointent. - * ``manage.py``, pour toutes les commandes de gestion. - * ``wsgi.py`` contient la définition de l'interface `WSGI `_, qui permettra à votre serveur Web (Nginx, Apache, ...) de faire un pont vers votre projet. - -NOTE: déplacer la configuration dans un répertoire ``config`` à part. === Gestion des dépendances -Comme nous venons d'ajouter une dépendance à notre projet, nous allons créer un fichier reprenant tous les dépendances de notre projet. Celles-ci sont normalement placées dans un fichier ``requirements.txt``. Dans un premier temps, ce fichier peut être placé directement à la racine du projet, mais on préférera rapidement le déplacer dans un sous-répertoire spécifique (``requirements``), afin de grouper les dépendances en fonction de leur utilité: +Comme nous venons d'ajouter une dépendance à notre projet, profitons-en pour créer un fichier reprenant tous les dépendances de notre projet. Celles-ci sont normalement placées dans un fichier `requirements.txt`. Dans un premier temps, ce fichier peut être placé directement à la racine du projet, mais on préférera rapidement le déplacer dans un sous-répertoire spécifique (`requirements`), afin de grouper les dépendances en fonction de leur utilité: - * ``base.txt`` - * ``dev.txt`` - * ``staging.txt`` - * ``production.txt`` + * `base.txt` + * `dev.txt` + * `production.txt` -Au début de chaque fichier, il suffira d'ajouter la ligne ``-r base.txt``, puis de lancer l'installation grâce à un ``pip install -r ``. De cette manière, il est tout à fait acceptable de n'installer `flake8` et `django-debug-toolbar` qu'en développement par exemple. Dans l'immédiat, ajoutez simplement ``django`` dans le fichier ``requirements/base.txt``. +Au début de chaque fichier, il suffit d'ajouter la ligne `-r base.txt`, puis de lancer l'installation grâce à un `pip install -r `. De cette manière, il est tout à fait acceptable de n'installer `flake8` et `django-debug-toolbar` qu'en développement par exemple. Dans l'immédiat, on va simplement ajouter `django` dans une version strictement inférieure à la version 3.1 dans le fichier `requirements/base.txt`. [source,bash] ---- -$ echo django >> requirements/base.txt +$ echo 'django<3.1' > requirements/base.txt +$ echo '-r base.txt' > requirements/prod.txt +$ echo '-r base.txt' > requirements/dev.txt ---- -Par la suite, il vous faudra **absolument** spécifier les versions à utiliser: les librairies que vous utilisez comme dépendances évoluent, de la même manière que vos projets. Des fonctions sont cassées, certaines signatures sont modifiées, des comportements sont altérés, etc. Si vous voulez être sûr et certain que le code que vous avez écrit continue à fonctionner, spécifiez la version de chaque librairie de dépendances. Avec les mécanismes d'intégration continue et de tests unitaires, on verra plus loin comment se prémunir d'un changement inattendu. +Prenez directement l'habitude de spécifier la version ou les versions compatibles: les librairies que vous utilisez comme dépendances évoluent, de la même manière que vos projets. Des fonctions sont cassées, certaines signatures sont modifiées, des comportements sont altérés, etc. + +Pour être sûr et certain le code que vous avez écrit continue à fonctionner, spécifiez la version de chaque librairie de dépendances. + +Avec les mécanismes d'intégration continue et de tests unitaires, on verra plus loin comment se prémunir d'un changement inattendu. + +=== Matrice de compatibilité + +Décrire un fichier tox.ini + +[source,bash] +---- +$ touch tox.ini +---- + +=== Licence + +Décrire une licence ? :-) + +[source,bash] +---- +$ touch LICENCE +---- + +=== Configuration globale + +Décrire le fichier setup.cfg + +[source,bash] +---- +$ touch setup.cfg +---- + +=== Makefile + +Décrire le makefile :) + +[source,bash] +---- +$ touch Makefile +---- === Structure finale de l'environnement @@ -142,16 +188,24 @@ Nous avons donc la strucutre finale pour notre environnement de travail: [source,bash] ---- -$ tree ~/gwift-project +$ (gwift) fred@aerys:~/Sources/gwift$ tree gwift gwift ├── docs │   └── README.md ├── gwift +│   ├── asgi.py │   ├── __init__.py │   ├── settings.py │   ├── urls.py │   └── wsgi.py -│   manage.py -└── requirements - └── base.txt +├── Makefile +├── manage.py +├── requirements +│   ├── base.txt +│   ├── dev.txt +│   └── prod.txt +├── setup.cfg +└── tox.ini + +3 directories, 13 files ---- diff --git a/source/toolchain/summary.adoc b/source/toolchain/summary.adoc deleted file mode 100644 index 614980c..0000000 --- a/source/toolchain/summary.adoc +++ /dev/null @@ -1,9 +0,0 @@ -== En résumé - -En résumé, la création d'un **nouveau** projet Django demande plus ou moins toujours les mêmes actions: - -. Configurer un environnement virtuel -. Installer les dépendances et les ajouter dans le fichier ``requirements.txt`` -. Configurer le fichier ``settings.py`` - -C'est ici que le projet http://cookiecutter.readthedocs.io/en/latest/readme.html[CookieCutter] va être intéressant: les X premières étapes peuvent être *bypassées* par une simple commande.