🔝 Retour au Sommaire
🎯 Niveau : Avancé
Ce module ne contient qu'un seul chapitre, mais c'est un chapitre à forte valeur professionnelle. La capacité à construire des outils en ligne de commande de qualité production — parsing d'arguments propre, sous-commandes, aide auto-générée, sortie formatée, détection TTY, codes de retour corrects — est ce qui distingue un binaire C++ jeté dans un répertoire d'un outil que les équipes adoptent. Dans un contexte DevOps/SRE, les outils CLI sont le livrable le plus courant en C++, et ils sont jugés sur la même exigence d'ergonomie que kubectl, git ou docker.
- Implémenter le parsing d'arguments avec CLI11 : options, flags, sous-commandes, validation, callbacks, génération d'aide automatique.
- Utiliser
fmtpour le formatage avancé de la sortie (syntaxe Python-like, couleurs, styles), et comprendre sa relation avecstd::print/std::format(C++23). - Gérer la détection TTY pour adapter la sortie (couleurs ANSI en terminal interactif, texte brut en pipe ou redirection).
- Concevoir l'architecture d'un outil CLI professionnel : structure en sous-commandes, séparation parsing/logique, codes de retour Unix, gestion des erreurs, documentation intégrée.
- Appliquer les conventions Unix : exit codes (
0= succès,1= erreur générale,2= usage incorrect),--help,--version, sortie structurée.
- Module 4, chapitre 12, section 12.7 :
std::printetstd::format(C++23) —fmtest la librairie originale dontstd::formatest dérivé. Comprendre l'un facilite l'utilisation de l'autre. - Module 6 : gestion d'erreurs — un outil CLI doit gérer les erreurs proprement (fichier introuvable, argument invalide, timeout réseau) et les traduire en messages lisibles et codes de retour appropriés.
- Module 7, chapitre 20 : signaux POSIX — un outil CLI doit gérer
SIGINT(Ctrl+C) etSIGPIPEcorrectement. - Module 8, chapitre 24 : parsing JSON/YAML — les outils CLI lisent souvent des fichiers de configuration dans ces formats.
De la librairie de parsing au design complet d'un outil CLI professionnel. Ce chapitre couvre CLI11 comme librairie principale, argparse comme alternative, fmt pour la sortie formatée, la gestion des couleurs et du TTY, et l'architecture d'ensemble.
- CLI11 : librairie header-only de parsing d'arguments. Installation (header-only ou via Conan/vcpkg), définition d'options (
app.add_option("-n,--name", name, "Description")), flags booléens, sous-commandes (app.add_subcommand("init", "Initialize project")), validation des entrées (CLI::ExistingFile,CLI::Range, validators personnalisés), callbacks sur les options, génération automatique de--helpavec description formatée. - argparse : alternative légère à CLI11, API plus simple, adaptée aux outils avec peu d'options et sans sous-commandes.
fmt: librairie de formatage dontstd::format(C++20/C++23) est issu. Syntaxe Python-like (fmt::print("Hello, {}!", name)), formatage numérique, alignement, padding. Couleurs et styles viafmt::color— texte coloré, gras, souligné pour les messages d'erreur, les warnings, et la mise en évidence.- Gestion des couleurs et du TTY : détection de terminal interactif (
isatty(STDOUT_FILENO)), désactivation des escape codes ANSI quand la sortie est redirigée vers un fichier ou pipée vers un autre programme. Respect de la variable d'environnementNO_COLOR(convention https://no-color.org/). - Architecture d'un outil CLI professionnel : structure en sous-commandes (à la
git commit,kubectl apply), séparation du parsing (couche CLI) et de la logique métier (couche library), gestion des codes de retour,--helpet--versioncohérents, sortie machine-readable optionnelle (--output json), documentation et exemples d'utilisation.
-
Codes de retour non conformes aux conventions Unix. Un outil CLI qui retourne
0en cas d'erreur ou un code arbitraire perd la composabilité avec le shell (set -e,&&,||,$?). Convention :0= succès,1= erreur générale,2= usage incorrect (mauvais arguments). Certains outils utilisent des codes spécifiques au-delà de2pour distinguer les types d'erreur (commegrepqui retourne1si aucune ligne ne matche). Définissez vos codes de retour, documentez-les dans--help, et ne retournez jamais0quand quelque chose a échoué. -
TTY detection absente — ANSI escape codes dans un pipe. Envoyer des escape codes ANSI (
\033[31mpour le rouge) quand la sortie est pipée versless,grep, ou un fichier produit des caractères parasites illisibles. Vérifiezisatty(STDOUT_FILENO)avant d'activer les couleurs, et respectezNO_COLORetFORCE_COLORcomme variables d'environnement. CLI11 etfmtne font pas cette vérification pour vous — c'est à votre code de la faire. -
SIGPIPEnon géré dans les outils qui écrivent sur stdout. Quand un outil CLI est pipé versheadoulesset que le consommateur ferme le pipe, l'écriture suivante déclencheSIGPIPEqui tue le programme avec un code de retour141. C'est un comportement normal pour les outils simples, mais gênant si votre outil doit faire du cleanup (fermer des fichiers, libérer des locks). Solution : ignorerSIGPIPE(signal(SIGPIPE, SIG_IGN)) et gérer l'erreurEPIPEretournée parwrite/std::cout. Ou accepter le comportement par défaut si le cleanup n'est pas nécessaire — mais faites-le consciemment. -
--helpet documentation incohérents. Un outil dont le--helpne correspond pas au comportement réel, ou qui n'a pas de--helpdu tout, perd la confiance de ses utilisateurs immédiatement. CLI11 génère le--helpautomatiquement à partir des descriptions passées àadd_optionetadd_subcommand— profitez-en pour écrire des descriptions précises dès la définition des options. Si vous maintenez une man page ou un README séparé, vérifiez la cohérence avec--helpà chaque release.
À l'issue de ce module, vous savez :
- Construire un outil CLI complet avec CLI11 : options, flags, sous-commandes, validation, aide auto-générée.
- Formater la sortie avec
fmt(couleurs, styles) en respectant la détection TTY etNO_COLOR. - Structurer un outil CLI professionnel avec séparation parsing/logique, codes de retour Unix corrects, et sortie machine-readable optionnelle.
- Gérer
SIGPIPEet les edge cases de la sortie pipée. - Produire un outil que d'autres développeurs et opérateurs peuvent adopter sans friction.