Meilleures pratiques pour les applications CLI Dart
1. Quand utiliser cette compétence
Utilisez cette compétence quand :
- Vous créez une nouvelle application CLI Dart.
- Vous refactorisez un point d'entrée CLI existant (
bin/). - Vous examinez le code CLI pour la qualité et les normes.
- Vous configurez des scripts exécutables pour Linux/Mac.
2. Meilleures pratiques
Structure du point d'entrée (bin/)
Gardez le contenu de votre fichier de point d'entrée (par exemple, bin/my_app.dart) minimal.
Cela améliore la testabilité en découplant la logique du gestionnaire de processus.
À FAIRE :
// bin/my_app.dart
import 'package:my_app/src/entry_point.dart';
Future<void> main(List<String> arguments) async {
await runApp(arguments);
}
À NE PAS FAIRE :
- Mettez une logique complexe directement dans
bin/my_app.dart. - Définissez des classes ou des fonctions lourdes au point d'entrée.
Mettez une entrée executable dans pubspec.yaml
Listez vos exécutables dans pubspec.yaml pour les rendre disponibles pour l'activation globale et une invocation propre via dart run.
À FAIRE :
Ajoutez une section executables mappant le nom de la commande au fichier Dart dans bin/ (en excluant l'extension .dart).
executables:
my_app: # Mappe à bin/my_app.dart
custom_name: main # Mappe à bin/main.dart
Ensuite, exécutez via dart run my_app ou dart run custom_name.
ENVISAGEZ #! pour d'autres scripts sur les systèmes *nix
Ce n'est PAS une règle stricte, mais c'est quelque chose à envisager.
Pour les outils CLI destinés à être exécutés directement sur Linux et Mac, ajoutez un shebang et assurez-vous que le fichier est exécutable.
À FAIRE :
- Ajoutez
#!/usr/bin/env dartà la première ligne. - Exécutez
chmod +x bin/my_script.dartpour le rendre exécutable.
#!/usr/bin/env dart
void main() => print('Ready to run!');
Terminaison de processus (exitCode)
Gérez correctement la terminaison du processus pour permettre le débogage et l'établissement correct des rapports de statut.
À FAIRE :
- Utilisez le setter
exitCodepour signaler un échec. - Laissez
mainse terminer naturellement. - Utilisez des codes de sortie standards (sysexits) pour plus de clarté (par exemple,
64pour une mauvaise utilisation,78pour les erreurs de configuration).- Consultez la classe
ExitCodedepackage:ioou la page de manuel sysexits de FreeBSD.
- Consultez la classe
import 'dart:io';
void main() {
if (someFailure) {
exitCode = 64; // À FAIRE !
return;
}
}
À ÉVITER :
- Appeler
exit(code)directement, car cela termine la VM immédiatement, empêchant le débogage « pause on exit » et les blocsfinallyde s'exécuter.
Gestion des exceptions
Les exceptions non capturées définissent automatiquement un code de sortie non nul, mais vous devez gérer les erreurs attendues avec élégance.
Exemple :
Future<void> main(List<String> arguments) async {
try {
await runApp(arguments);
} catch (e, stack) {
print('App crashed!');
print(e);
print(stack);
exitCode = 1; // Échouer explicitement
}
}
Compatibilité multiplateforme (support Windows)
Lors de l'écriture d'applications CLI et de tests, assurez la compatibilité avec Windows :
- Chemins : Évitez de coder en dur les séparateurs de chemin comme
/car Windows utilise\. Utilisezp.joinoup.normalizedepackage:pathpour construire les chemins de manière portable. - Permissions de fichiers : Lors du test des erreurs de permissions de fichiers, rappelez-vous que
chmodn'est pas disponible sur Windows. Utilisezicaclssur Windows ou les bibliothèques de simulation appropriées pour simuler les erreurs de permissions. Ne sautez jamais les tests sur Windows simplement en raison des commandes de permissions si un équivalent Windows existe.
Découverte
Pour trouver des domaines où appliquer ces meilleures pratiques :
Points d'entrée lourd
Inspectez les fichiers dans bin/ pour voir s'ils contiennent une logique qui devrait être dans lib/ :
- Cible : Fichiers correspondant à
bin/*.dart.
Terminaison directe du processus
Recherchez les appels à exit() au lieu de définir exitCode :
- Regex :
\bexit\(
Séparateurs de chemin codés en dur
Recherchez / codés en dur dans les chaînes qui semblent être des chemins de fichiers :
- Regex :
['"][^'"]+/[^'"]+['"](Vérifiez le contexte car cela peut correspondre à des URLs).
3. Paquets recommandés
Utilisez ces paquets standards communautaires possédés par l'équipe Dart pour résoudre les problèmes CLI courants :
| Catégorie | Paquet recommandé | Utilisation |
|---|---|---|
| Stack Traces | package:stack_trace |
traces de pile détaillées et plus propres |
| Analyse d'arguments | package:args |
analyse standard des drapeaux/options |
| Tests | package:test_process |
tests d'intégration pour les applications CLI |
| Tests | package:test_descriptor |
fixtures de système de fichiers pour les tests |
| Mise en réseau | package:http |
client HTTP standard (n'oubliez pas le User-Agent !) |
| Sortie ANSI | package:io |
gestion des couleurs et styles ANSI |
4. Paquets intéressants de la communauté
| Catégorie | Paquet recommandé | Utilisation |
|---|---|---|
| Configuration | package:json_serializable |
objets de configuration fortement typés |
| Génération CLI | package:build_cli |
générer des analyseurs d'arguments à partir de classes |
| Informations de version | package:build_version |
injection de version automatique |
| Configuration | package:checked_yaml |
analyse YAML précise avec numéros de ligne |
5. Conventions
- Mise en cache de fichiers : Écrivez les fichiers en cache dans
.dart_tool/[pkg_name]/. - User-Agent : Définissez toujours un en-tête User-Agent dans les requêtes HTTP, y compris les informations de version.