Outils de Développement de Logiciels: Une Vue d'Ensemble

Outils de Développement de Logiciels: Une Vue d'Ensemble

Table des matières

Lorsque j’apprends un langage de programmation, l’une des premières choses que j’essaie de comprendre est comment transformer le code écrit en un artefact déployable (installable) et exécutable. Je commence par déterminer le type de langage de programmation, spécifiquement s’il nécessite une étape de compilation et si un interpréteur est requis à l’exécution. Ensuite, je me penche sur les outils de programmation ou la chaîne d’outils nécessaires pour faire le build et empaqueter toute application que je développe.

Cet article traite des différents types d’outils nécessaires pour gérer le build et l’empaquetage de logiciels. Tout d’abord, nous expliquons les méthodes courantes pour configurer la chaîne d’outils. Ensuite, nous décrivons les outils de la chaîne d’outils.

Préparer la Chaîne d’Outils

Avant de faire le build du code, vous devez disposer des outils de programmation nécessaires. Vous pouvez y parvenir de l’une des manières suivantes :

  • Installation manuelle: Les installer à l’aide du gestionnaire de paquets du système ou à partir des sources.
  • Installation automatisée: Utiliser un outil de gestion de la chaîne d’outils ou un script d’installation pour une installation automatisée, si disponible.
  • Conteneurs de développement: Utiliser un conteneur d’environnement virtuel pré-construit (par exemple, Docker), appelé conteneur de développement, basé sur une image, si disponible.

Pour les langages de programmation qui nécessitent un interpréteur, celui-ci sera également mis à disposition de cette manière, à la fois pour l’étape de construction et pour le temps d’exécution.

Vous pouvez généralement utiliser toute la chaîne d’outils à travers l’Environnement de Développement Intégré (IDE) du langage de programmation ou un pipeline d’Intégration Continue (CI).

Composants de la Chaîne d’Outils

Examinons les différents types d’outils et la manière dont ils sont généralement organisés au sein d’un pipeline de développement de logiciels.

Schéma général des chaînes d'outils
Schéma général des chaînes d’outils

Outils Primaires

Cette catégorie d’outils traite directement le code. Ils sont utilisés pour vérifier le code source, générer la documentation du code, générer automatiquement du code source à partir du Langage de Description d’Interface (IDL) et des langages de macro, compiler le code (si nécessaire), tester le code, empaqueter le logiciel et le télécharger dans le dépôt de packages (si nécessaire).

1. Édition de Code

De nombreux outils peuvent aider les développeurs à écrire du code plus efficacement. Il s’agit notamment d’outils d’autocomplétion, de navigation (dans et entre les fichiers sources) et de mise en évidence de la syntaxe. Ces outils utilisent une analyse légère et sont souvent intégrés dans des éditeurs de texte conçus pour des langages de programmation spécifiques.

De nombreux éditeurs de code modernes utilisent le “Language Server Protocol” (LSP) pour interagir avec ces outils de productivité pour l’écriture de code. Ils l’utilisent également pour interagir avec les outils d’analyse de conformité de code source.

2. Analyse de Conformité des Sources

Les outils d’analyse de la conformité des sources sont principalement utilisés pour:

  • Vérifier que les artefacts sources respectent les meilleures pratiques et sont exempts d’erreurs triviales. Ces outils spécifiques sont généralement appelés linters.

  • S’assurer que les artefacts sources respectent les normes de formatage du projet. Ces outils spécifiques sont généralement appelés formateurs.

Certains outils de conformité des sources remplissent à la fois les fonctions de linters et de formateurs.

Note

Il existe également des linters et des formateurs pour les fichiers de configuration, tels que JSON (par exemple, jsonlint), YAML (par exemple, yamllint), TOML (par exemple, tomlv), XML (par exemple, xmllint disponible dans le package libxml2), etc.

Linter

Les linters analysent le code source, effectuent diverses vérifications et signalent les problèmes aux développeurs pour qu’ils les corrigent. La détection précoce des erreurs permet d’éviter les problèmes lors de la compilation (le cas échéant), des tests ou de l’exécution, améliorant ainsi le cycle de vie du développement logiciel (SDLC). Voici quelques types de contrôles couramment effectués par les linters:

  • Vérifications de l’exactitude de la syntaxe: S’assurer qu’il n’y a pas d’erreurs de syntaxe dans l’artefact source. Ceci est particulièrement utile pour les langages de programmation qui n’ont pas d’étape de compilation au moment du build. C’est également essentiel pour les fichiers de configuration.

  • Vérifications de conformité aux conventions: Vérifier le respect des lignes directrices du projet concernant le style de codage, le nommage des variables, les exigences en matière de commentaires, la complexité du code, la syntaxe préférée, les code smells, etc. Elles jouent un rôle crucial dans le maintien de la cohérence au sein d’un projet et rendent le logiciel plus facile à maintenir. Les exigences de convention n’affectent pas la sémantique mais seulement la syntaxe, et potentiellement les performances du programme.

  • Contrôles des erreurs sémantiques courantes et de sécurité: Il s’agit de vérifier les erreurs sémantiques potentielles et les vulnérabilités telles que les variables non initialisées, les fuites de mémoire, les déréférences de pointeurs nuls, etc.

Certains linters peuvent fournir des correctifs générés automatiquement pour les problèmes qu’ils détectent.

Formateur

Les formateurs transforment automatiquement les artefacts source pour qu’ils respectent les directives de style du projet. Les exigences de style mises en œuvre par les formateurs comprennent : la taille et le type d’indentation (tabulations ou espaces), les sauts de ligne, la longueur maximale des lignes de code, l’utilisation d’accolades et leur placement (si pris en charge), l’espacement avant les parenthèses (si pris en charge), et plus encore.

Les formateurs vérifient le style des sources et les transforment pour qu’elles suivent les directives de style. Cette transformation n’affecte pas la sémantique du code.

Tip

Étant donné que les formateurs modifient automatiquement le code sans affecter la sémantique, il est plus naturel d’utiliser les linters avant les formateurs.

3. Génération Automatisée de Documentation

Particulièrement utiles pour la documentation des interfaces de programmation d’applications (API), les outils de génération automatisée de documentation créent une documentation visuellement attrayante en extrayant la documentation des artefacts sources. La documentation extraite est souvent rendue au format HTML ou d’autres formats de documentation tels que reStructuredText ou Markdown.

Les outils de documentation des sources sont souvent spécifiques à un langage, ce qui signifie qu’ils prennent généralement en charge un ou quelques langages de programmation ou langages dédié (DSL).

Ces outils utilisent également des fichiers de documentation dédiés pour générer la documentation du projet. En fait, certains outils de génération de documentation n’utilisent que des fichiers de documentation dédiés (tels que reStructuredText ou Markdown) pour générer une page web de documentation. Ce type d’outil de génération de documentation doit être utilisé après avoir généré les fichiers de documentation à partir des artefacts sources à l’aide d’outils de génération de documentation spécifiques à un langage. Mkdocs est un exemple de ce type d’outil.

Les outils de génération de documentation sont configurables, ce qui permet à un fichier de configuration de définir la manière dont la documentation doit être générée. Voici quelques exemples d’options de configuration:

  • Code source ou fichiers de documentation dédiés à exclure lors de la génération.
  • Format final de la documentation.
  • Style et thème à utiliser pour la documentation HTML.

4. Génération Automatisée de Code Source

Il existe des scénarios dans le génie logiciel où le code source est généré automatiquement et utilisé pour le build ou l’exécution d’un programme. Les scénarios les plus courants impliquent l’utilisation de macros et de langages de description d’interface (IDL).

Un exemple d’utilisation de macros est un outil système avec un composant qui effectue des appels système qui varient selon les différentes plateformes. Un processeur de macros tel que M4 peut générer les appels corrects au moment du build en fonction de la plateforme sélectionnée. Dans ce cas, les divers appels spécifiques à la plateforme sont développés en utilisant des macros.

Un exemple d’utilisation des IDL est celui d’un microservice qui accède à un serveur via gRPC, où les services du serveur sont définis en utilisant l’IDL Protocol Buffers. Le code du microservice accède aux services du serveur via le code de stub généré à partir des fichiers Protocol Buffers.

5. Compilation (si nécessaire)

Certains langages de programmation exigent que le code source soit compilé en code machine ou en code interprété avant d’être exécuté. C’est le cas des langages natifs tels que C, C++, Rust, Go, ainsi que certains langages interprétés tels que Java et Typescript. Le processus de compilation implique plusieurs outils, en fonction de la sortie cible :

  • Compilation en code machine: Le compilateur transforme les fichiers de code source en code assembleur. L’assembleur convertit ensuite le code assembleur en code machine. Pour une bibliothèque, l’archiveur regroupe les fichiers de code machine en une seule archive. Pour un exécutable autonome, l’éditeur de liens combine les fichiers de code machine en un seul, résolvant les références et liant les éléments externes.

  • Compilation en code interprété: Le compilateur convertit les fichiers de code source en code interprété. L’archiveur regroupe ensuite ces fichiers de code interprété en une seule archive.

Pour les langages de programmation qui ne nécessitent pas de compilation, les fichiers de code source eux-mêmes sont exécutables.

6. Tests

Il est important de vérifier qu’un programme fonctionne comme prévu, c’est-à-dire qu’il produit les sorties correctes pour des entrées données. Prenons l’exemple d’un programme qui:

  • Lit un nombre entier à partir de l’entrée standard.
  • Affiche “Est premier” si le nombre est premier ; sinon, affiche “N’est pas premier”.

Si nous exécutons le programme avec l’entrée 3 et qu’il affiche “N’est pas premier”, nous savons qu’il y a une erreur à corriger.

Les outils de test aident à automatiser ce processus en nous permettant de spécifier facilement les entrées et les sorties attendues, d’exécuter le programme et de signaler toute anomalie. Si la sortie du programme ne correspond pas au résultat attendu, cela indique qu’il y a un bug qui doit être corrigé.

Après avoir identifié les erreurs à l’aide des outils de test, il peut être nécessaire de modifier le programme pour les corriger, et le processus de développement revient à la phase d’édition du code.

7. Empaquetage des Artéfacts

Lorsque nous sommes satisfaits du code executable obtenu, nous pouvons l’empaqueter pour faciliter son déploiement ou le rendre disponible dans un dépôt de packages.

Note

Les sources DSL peuvent être utilisées directement au moment de l’exécution sans génération de code source. Dans ce cas, les sources DSL doivent être empaquetées avec le code exécutable. Un exemple est le framework d’interface utilisateur graphique (GUI) GTK builder, où les modèles GUI d’un programme sont définis dans des fichiers XML appelé fichiers glade. Ces fichiers glade sont chargés comme ressources du programme au moment de l’exécution.

Les packages peuvent être créés sous la forme native du gestionnaire de packages du langage de programmation ou sous forme d’images de conteneurs du programme, telles que celles créées avec Docker. Ces dernières sont très courantes dans le cadre de l’architecture microservices.

En ce qui concerne les images Docker, l’outil Docker CLI peut être utilisé pour créer des images en utilisant la commande docker build ....

Tip

Les packages système peuvent être créés en utilisant l’outil CPack. Cependant, lorsque cela est possible, il est préférable d’utiliser des gestionnaires de packages non système pour gérer facilement les versions, surtout lorsque divers programmes exécutés sur le même système nécessitent différentes versions d’une même bibliothèque.

8. Téléchargement des Packages

Une fois les paquets créés, ils doivent souvent être téléchargés dans un dépôt de paquets public ou privé. Ces référentiels fournissent des outils, appelés “publieur de paquets”, pour télécharger les packages.

Par exemple, avec les images Docker, l’outil CLI de Docker peut être utilisé pour publier des images en utilisant la commande docker push ....

Outils Intermédiaires

La catégorie “outils intermédiaires” comprend les outils qui ne sont pas directement liés à l’édition et au build du code. Il s’agit notamment d’outils de gestion des dépendances, d’orchestration du build et de systèmes de gestion du code source (contrôle de version).

1. Gestion des Dépendances

Les ingénieurs logiciels utilisent souvent des programmes existants, appelés dépendances, pour éviter de “réinventer la roue”. Il est essentiel de garder une trace des dépendances utilisées par un projet et leurs versions. Il est également important de les rendre disponibles rapidement et automatiquement.

Cette tâche de gestion des dépendances est souvent prise en charge par des outils appelés gestionnaires de paquets ou gestionnaires de dépendances. Les gestionnaires de paquets modernes utilisent des fichiers de configuration, souvent stockés dans le référentiel du projet, pour s’assurer que les dépendances sont disponibles lors du build.

Note

Bien que les gestionnaires de paquets soient utilisés pour rendre les dépendances disponibles lors du build, ils peuvent également rendre les dépendances d’exécution disponibles au moment de l’exécution.

2. Orchestration du Build

Le processus de build implique plusieurs étapes et outils. Pour simplifier et automatiser ce processus, un orchestrateur de build ou outil de build est utilisé. Cet outil est contrôlé par des fichiers de configuration qui décrivent, de manière déclarative ou impérative, les étapes du processus de build.

Note

Un outil de build peut également remplir la fonction de gestionnaire de paquets.

3. Gestionnaires de Code Source

L’utilisation de gestionnaires de code source, également appelés outils de contrôle de version, tels que git, est essentielle pour gérer les dépôts de code source des logiciels. Les outils de gestion de code source permettent aux développeurs de:

  • Stocker le code source de leurs logiciels dans des référentiels distants
  • Conserver un historique des versions du logiciel et passer de l’une à l’autre.
  • Développer différentes fonctionnalités du logiciel en parallèle et les fusionner une fois terminées.
  • Et bien d’autres choses encore.

Note

Les fichiers de code source ne sont pas les seuls fichiers suivis par les outils de contrôle de version. Les fichiers source de DSL, les fichiers de configuration de build, les fichiers de documentation dédiés et bien d’autres encore sont également suivis.

Ce qu’il Faut Rechercher dans un Dépôt de Code

Un dépôt de code source contient souvent les éléments suivants:

  • Fichiers de code source développés
  • Fichiers source de DSL
  • Fichiers de code et de données de test
  • Fichiers de documentation dédiés
  • (Optionnel) Fichiers de configuration de l’exécution du logiciel
  • Fichiers de configuration du gestionnaire de code source (par exemple, .gitignore pour Git)
  • Fichiers de configuration de l’outil d’orchestration de build (par exemple, Makefile)
  • Fichiers de configuration du gestionnaire de paquets
  • Fichiers de configuration de l’éditeur de texte
  • Fichiers de configuration du linter
  • Fichiers de configuration du formateur de code
  • Fichiers de configuration de l’outil de test
  • Fichiers de configuration du générateur de documentation
  • Fichiers de configuration du générateur de code basé sur les DSL
  • Fichiers de configuration de l’infrastructure du compilateur
  • Fichiers de configuration du générateur et du publieur de paquets

Articles Connexes

Mise en Place et Utilisation de Rust Hors Ligne pour un Développement Sans Faille : Un Tutoriel Étape par Étape

Mise en Place et Utilisation de Rust Hors Ligne pour un Développement Sans Faille : Un Tutoriel Étape par Étape

[Dernière mise à jour: 17 avril 2024]

C’est un processus simple de mettre en place Rust lorsque vous avez accès à Internet, mais que se passe-t-il si vous êtes hors ligne?

Lire la suite