gwift-book/chapters/tools.tex

305 lines
16 KiB
TeX
Executable File

\chapter{Outils de développement}
\section{Environnement de développement intégré \index{IDE}}
Concrètement, nous pourrions tout à fait nous limiter à Notepad ou Notepad++.
Mais à moins d'aimer se fouetter avec un câble USB, nous apprécions la complétion du code, la coloration syntaxique, l'intégration des tests unitaires et d'un debugger, ainsi que deux-trois sucreries qui feront plaisir à n'importe quel développeur.
Si vous manquez d'idées ou si vous ne savez pas par où commencer:
\begin{itemize}
\item
\href{https://vscodium.com/}{VSCodium}, avec les plugins
\href{https://marketplace.visualstudio.com/items?itemName=ms-python.python}{Python}et
\href{https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens}{GitLens}
\item
\href{https://www.jetbrains.com/pycharm/}{PyCharm}
\item
\href{https://www.vim.org/}{Vim} avec les plugins
\href{https://github.com/davidhalter/jedi-vim}{Jedi-Vim} et
\href{https://github.com/preservim/nerdtree}{nerdtree}
\end{itemize}
Si vous hésitez, et même si Codium n'est pas le plus léger (la faute à \href{https://www.electronjs.org/}{Electron}\ldots\hspace{0pt}), il fera correctement son travail (à savoir : faciliter le vôtre), en intégrant suffisament de fonctionnalités qui gâteront les papilles émoustillées du développeur impatient.
\begin{figure}[H]
\centering
\scalebox{1.0}{\includegraphics[max size={\textwidth}{\textheight}]{images/environment/codium.png}}
\caption{Codium en action}
\end{figure}
\subsection{Configuration}
VSCodium permet également de définir certaines clés de configuration globalement ou au niveau d'un projet.
Celle qui nous semble critique, indispensable et primordial est la suppression automatique des espaces en fin de ligne, qui facilite énormément la relecture de \textit{commits} et la collaboration entre intervenants.
\begin{minted}{js}
/* fichier placé habituellement dans ~/.config/code/User/settings.json */
{
[...]
"files.trimTrailingWhitespace": true,
}
\end{minted}
Nous pouvons également noter la possibilité d'installer des greffons (dont un gestionnaire d'interpréteur Python), l'intégration poussée de Git \index{git} ou l'énorme support de plein de langages de programmation ou de mise en forme: Go, XML, HTML, Java, C\#, PHP, LaTeX, \ldots, ainsi que tout l'atirail d'aides à l'utilisation de Docker.
\subsection{Mode debug}
Le débugger intégré vous permettra de spécifier le point d'entrée à utiliser, de placer des points d'arrêt (éventuellement conditionnés par certaines valeurs attribuées à des variables), de lancer une analyse sur les variables et contextes, sur la pile d'appels, ...
Bref: de savoir où vous en êtes et pourquoi vous êtes là.
Ce débugger fonctionne soit sur le fichier courant (déconseillé), soit \textit{via} un fichier \texttt{launch.json} que vous pourrez placer dans le répertoire \texttt{.vscode} placé à la racine de votre projet.
Pour une application Django, ce fichier contiendra par exemple la configuration suivante:
\begin{minted}{js}
{
"version": "0.2.0",
"configurations": [
{
"name": "Python Django",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/manage.py",
"args": [
"runserver"
],
"django": true,
"justMyCode": true
}
]
}
\end{minted}
Les \textit{configurations} peuvent être multiples, et nous pouvons voir que l'objectif de cette configuration-ci est de démarrer la commande \texttt{\$\{workspaceFolder\}/manage.py}, avec le paramètre \texttt{runserver}, ce qui aura pour effet de démarrer l'exécution du code dans une enveloppe sécurisée et plombée de capteurs en tout genre qui faciliteront énormément votre travail de recherche et d'introspection du code.
\section{Terminal}
\emph{A priori}, les IDE proposés ci-dessus fournissent par défaut ou \emph{via} des greffons un terminal intégré.
Ceci dit, disposer d'un terminal séparé facilite parfois certaines tâches.
A nouveau, si vous manquez d'idées :
\begin{enumerate}
\item
Soit vous utilisez celui qui intégré à VSCodium et qui fera suffisament bien son travail
\item
Si vous êtes sous Windows, téléchargez une copie de \href{https://cmder.net/}{Cmder}.
Il n'est pas le plus rapide, mais propose une intégration des outils Unix communs (\texttt{ls}, \texttt{pwd}, \texttt{grep}, \texttt{ssh}, \texttt{git}, \ldots\hspace{0pt}) sans trop se fouler.
\item
Pour tout autre système, vous devriez disposer en natif de ce qu'il faut.
\end{enumerate}
\begin{figure}[H]
\centering
\scalebox{1.0}{\includegraphics[max size={\textwidth}{\textheight}]{images/environment/terminal.png}}
\end{figure}
\section{Un gestionnaire de mots de passe}
Nous en auront besoin pour gé()rer des phrases secrètes pour nos applications.
Si vous n'en utilisez pas déjà un, partez sur \href{https://keepassxc.org/}{KeepassXC}: il est multi-plateformes, suivi et s'intègre correctement aux différents environnements, tout en restant accessible.
\begin{figure}[H]
\centering
\scalebox{1.0}{\includegraphics[max size={\textwidth}{\textheight}]{images/environment/keepass.png}}
\end{figure}
La finalité de cette application va être de centraliser la gestion de vos phrases de passe, pour les accès aux bases de données, services en ligne, etc.
Il existe des alternatives, comme Bitwarden, qui proposent des services libres, gratuits ou payants.
\section{Un système de gestion de versions}
Il existe plusieurs systèmes de gestion de versions.
Le plus connu/utilisé à l'heure actuelle est \href{https://git-scm.com/}{Git}, notamment pour sa (très) grande flexibilité et sa rapidité d'exécution.\footnote{L'adoption massive de Git a rendu la coopération beaucoup facile sur de nombreux projets: avant Git (et Github, qui a popularisé Git), chaque projet utilisait un système de contrôle de version différent. A présent, savoir contribuer à un projet permet de contribuer à tous les projets \cite[p.69]{roads_and_bridges}}
Il est une aide précieuse pour développer rapidement des preuves de concept, switcher vers une nouvelle fonctionnalité, un bogue à réparer ou une nouvelle release à proposer au téléchargement.
Ses deux plus gros défauts concernent sa courbe d'apprentissage pour les nouveaux venus et la complexité des actions qu'il permet de réaliser.
\begin{figure}[H]
\centering
\scalebox{1.0}{\includegraphics[max size={\textwidth}{\textheight}]{images/xkcd-1597-git.png}}
\caption{\url{https://xkcd.com/1597/}}
\end{figure}
Même pour un développeur solitaire, un système de gestion de versions (quel qu'il soit) reste indispensable, car il permet d'isoler un ensemble de modifications dans une \textit{unité de travail}, jusqu'à ce que celles-ci forment un tout cohérent:
\begin{enumerate}
\item
Chaque "\textbf{branche}" correspond à une tâche à réaliser: un bogue à corriger (\emph{Hotfix A}), une nouvelle fonctionnalité à ajouter ou un "\emph{truc à essayer}" \footnote{Oui, comme dans "Attends, j'essaie vite un truc, si ça marche, c'est beau."} (\emph{Feature A} et \emph{Feature B}).
\item
Chaque "\textbf{commit}" correspond à une sauvegarde atomique d'un état ou d'un ensemble de modifications cohérentes entre elles.\footnote{Il convient donc de s'abstenir de modifier le CSS d'une application et la couche d'accès à la base de données, sous peine de se faire huer par ses relecteurs au prochain stand-up.}
De cette manière, il est beaucoup plus facile pour le développeur de se concenter sur un sujet en particulier, dans la mesure où celui-ci ne doit pas obligatoirement être clôturé pour appliquer un changement de contexte.
\end{enumerate}
L'historique d'un module est ainsi disponible, sauvé et traçable: qui a réalisé quelle modification à quel moment.
Ceci permet notamment de dessiner l'évolution du code et de mettre un surbrillance que certains modules distincts évoluent un peu trop main dans la main (et devraient donc être refactoriser, selon les principes de développement énumérés plus tôt).
\begin{figure}[H]
\centering
\scalebox{1.0}{\includegraphics[max size={\textwidth}{\textheight}]{images/diagrams/git-workflow.png}}
\caption{Git en action}
\end{figure}
Cas pratique: vous développez une nouvelle fonctionnalité qui va révolutionner le monde de demain et d'après-demain, quand, tout à coup (!), vous vous rendez compte que vous avez perdu votre conformité aux normes PCI parce les données des titulaires de cartes ne sont pas isolées correctement.
Il suffit alors de:
\begin{enumerate}
\item
Sauver le travail en cours (\texttt{git\ add\ .\ \&\&\ git\ commit\ -m\ {[}WIP{]}})
\item
Revenir sur la branche principale (\texttt{git\ checkout\ main})
\item
Créer un "hotfix" (\texttt{git\ checkout\ -b\ hotfix/pci-compliance})
\item
Solutionner le problème (sans doute un \texttt{;} en trop ?)
\item
Sauver le correctif sur cette branche (\texttt{git\ add\ .\ \&\&\ git\ commit\ -m\ "Did\ it!"})
\item
Récupérer ce correctif sur la branche principal (\texttt{git\ checkout\ main\ \&\&\ git\ merge\ hotfix/pci-compliance})
\item
Et revenir tranquillou sur votre branche de développement pour fignoler ce générateur de noms de dinosaures rigolos que l'univers vous réclame à cor et à a cri (\texttt{git\ checkout\ features/dinolol})
\end{enumerate}
Il existe plusieurs méthodes pour gérer ces flux d'informations.
Les plus connues sont Gitflow \footnote{\url{https://www.gitflow.com/}} et Threeflow \footnote{\url{https://www.reddit.com/r/programming/comments/7mfxo6/a_branching_strategy_simpler_than_gitflow/}}.
La gestion de versions de fichiers permet de conserver un historique de toutes les modifications enregistrées, associées à un horodatage et une description.
\begin{advicebox}
Il existe (à nouveau) énormément de tutoriels.
Pour aller un peu plus loin, Carl Chenet\footnote{\url{https://carlchenet.com/}} a ainsi écrit sept articles pour débuter avec Git:
\begin{enumerate}
\item
\href{https://carlchenet.com/debuter-avec-git-creer-un-depot/}{Créer un dépôt}
\item
\href{https://carlchenet.com/debuter-avec-git-premier-ajout-de-code/}{Premier ajout de code}
\item
\href{https://carlchenet.com/debuter-avec-git-partie-3-un-commit-plus-complexe/}{Un commit plus complexe}
\item
\href{https://carlchenet.com/debuter-avec-git-partie-4-les-commits-et-les-branches/}{Les commits et les branches}
\item
\href{https://carlchenet.com/debuter-avec-git-partie-5-fusionner-des-branches/}{Fusionner des branches}
\item
\href{https://carlchenet.com/debuter-avec-git-partie-6-une-fusion-de-branches-echoue/}{Si une fusion de branche échoute}
\item
\href{https://carlchenet.com/debuter-avec-git-partie-7-git-rebase-pour-re-ecrire-son-historique/}{Rebase pour réécrire son historique}
\end{enumerate}
\end{advicebox}
\subsection{Décrire ses changements}
La description d'un changement se fait \emph{via} la commande \texttt{git\ commit}.
Il est possible de lui passer directement le message associé à ce changement grâce à l'attribut \texttt{-m}, mais c'est une pratique relativement déconseillée: un \emph{commit} ne doit effectivement pas obligatoirement être décrit sur une seule ligne.
Une description plus complète, accompagnée des éventuels tickets ou références de tâches, sera plus complète, plus agréable à lire, et plus facile à revoir pour vos éventuels relecteurs.
De plus, la plupart des plateformes de dépôts présenteront ces informations de manière ergonomique. Par exemple:
\begin{figure}[H]
\centering
\scalebox{1.0}{\includegraphics[max size={\textwidth}{\textheight}]{images/environment/gitea-commit-message.png}}
\caption{Un exemple de commit affiché dans Gitea}
\end{figure}
La première ligne est reprise comme étant le titre (normalement, sur 50 caractères maximum); le reste est repris comme une description (optionnelle).
\begin{minted}{text}
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
\end{minted}
Il est possible de suivre les recommandations de \textit{Conventional Commits} \footnote{\url{https://www.conventionalcommits.org/en/v1.0.0/}}, qui ont pour objectifs de:
\begin{enumerate}
\item
Générer automatiquement un \textit{CHANGELOG}
\item
Déterminer automatiquement des sauts de versions (en se basant sur les types de commits)
\item
Communiquer la nature des changements appliqués au code
\item
Déclencher (automatiquement, toujours) des processus de construction ou de publication
\item
Rendre l'accès au code plus lisible, en facilitant l'exploration du code au travers de commits mieux structurés.
\end{enumerate}
\subsubsection{<type>}
\subsubsection{<scope>}
\subsubsection{<description>}
\subsubsection{<body>}
\subsubsection{<footer(s)>}
\subsubsection{CHANGELOG}
Une fois les changements décrits en suivant ces conventions, et sous réserve qu'elles soient bien respectées, permet de générer un CHANGELOG \footnote{\url{https://github.com/conventional-changelog/standard-version}}.
\subsection{Nommer ses branches}
\section{Bases de données}
\begin{quote}
The database is really nothing more than a big bucket of bits where we store our data on a long term basis
\cite[p. 281]{clean_architecture}
\end{quote}
Django gère plusieurs moteurs de base de données.
Certains sont gérés nativement (PostgreSQL, MariaDB, SQLite); et \emph{a priori}, ces trois-là sont disponibles pour tous les systèmes d'exploitation.
D'autres moteurs nécessitent des librairies tierces (Oracle, Microsoft SQL Server).
\subsection{SQLite}
Parfois, SQLite peut être une bonne option:
\begin{quote}
Write througput is the area where SQLite struggles the most, but there's not a ton of compelling data online about how it fares, so I got some of my own: I spun up a Equinix m3.large.x86 instance, and ran a slightly modified1 version of the SQLite kvtest2 program on it.
Writing 512 byte blobs as separate transactions, in WAL mode with synchronous=normal3, temp\_store=memory, and mmap enabled, I got 13.78$\mu$s per write, or \textasciitilde72,568 writes per second. Going a bit larger, at 32kb writes, I got 303.74$\mu$s per write, or \textasciitilde3,292 writes per second.
That's not astronomical, but it's certainly way more than most websites being used by humans need.
If you had 10 million daily active users, each one could get more than 600 writes per day with that.
\end{quote}
\begin{quote}
Looking at read throughput, SQLite can go pretty far: with the same test above, I got a read throughput of \textasciitilde496,770 reads/sec (2.013$\mu$s/read) for the 512 byte blob.
Other people also report similar results
--- Expensify reports that you can get 4M QPS if you're willing to make some slightly more involved changes and use a beefier server.
Four million QPS is enough that every internet user in the world could make \textasciitilde70 queries per day, with a little headroom left over.
Most websites don't need that kind of throughput. \cite{consider_sqlite}
\end{quote}
\subsection{MySQL/MariaDB}
\subsection{PostgreSQL}
\subsection{Gestionnaires}
Il n'est pas obligatoire de disposer d'une application de gestion pour ces moteurs: pour les cas d'utilisation simples, le shell Django pourra largement suffire (nous y reviendrons).
Mais pour faciliter la gestion des bases de données elles-même, et si vous n'êtes pas à l'aise avec la ligne de commande, choisissez l'une des applications d'administration ci-dessous en fonction du moteur de base de données que vous souhaitez utiliser.
\begin{itemize}
\item
Pour \textbf{PostgreSQL}, il existe \href{https://www.pgadmin.org/}{pgAdmin}
\item
Pour \textbf{MariaDB} ou \textbf{MySQL}, partez sur \href{https://www.phpmyadmin.net/}{PHPMyAdmin}
\item
Pour \textbf{SQLite}, il existe \href{https://sqlitebrowser.org/}{SQLiteBrowser} PHPMyAdmin ou PgAdmin.
\end{itemize}
\section{Intégration continue}
\subsection{Qualité du code}
Code climate, SonarQube.
\section{Insomnia}