Analyse des paramètres de ligne de commande avec la compagnie aérienne

1. Introduction

Dans ce didacticiel, nous présenterons Airline - une bibliothèque Java basée sur les annotations pour la création d'interfaces de ligne de commande (CLI).

2. Scénario

Lors de la création d'une application de ligne de commande, il est naturel de créer une interface simple pour permettre à l'utilisateur de modeler la sortie selon ses besoins. Presque tout le monde a joué avec Git CLI et peut comprendre à quel point il est puissant, mais simple. Hélas, peu d'outils sont utiles pour créer une telle interface.

La compagnie aérienne vise à réduire le code standard généralement associé aux CLI en Java , car la plupart des comportements courants peuvent être obtenus avec des annotations et un code utilisateur nul.

Nous allons implémenter un petit programme Java qui exploitera les fonctionnalités d'Airline pour imiter une CLI commune. Il exposera les commandes utilisateur pour configurer la configuration de notre programme, comme la définition de l'URL de la base de données, des informations d'identification et de la verbosité de l'enregistreur. Nous allons également plonger sous la surface de notre bibliothèque et utiliser plus que ses bases pour déterminer si elle peut gérer une certaine complexité.

3. Configuration

Pour commencer, ajoutons la dépendance Airline à notre pom.xm l:

 com.github.rvesse airline 2.7.2  

4. Une CLI simple

Créons notre point d'entrée pour l'application - la classe CommandLine :

@Cli(name = "baeldung-cli", description = "Baeldung Airline Tutorial", defaultCommand = Help.class) public class CommandLine { public static void main(String[] args) { Cli cli = new Cli(CommandLine.class); Runnable cmd = cli.parse(args); cmd.run(); } }

Grâce à une simple annotation @Cli , nous avons défini la commande par défaut qui s'exécutera sur notre application - la commande Help .

La classe Help fait partie de la bibliothèque Airline et expose une commande d'aide par défaut à l'aide des options -h ou –help .

Juste comme ça, la configuration de base est terminée.

5. Notre premier commandement

Implémentons notre première commande, une simple classe LoggingCommand qui contrôlera la verbosité de nos logs. Nous annotons la classe avec @Command pour nous assurer que la commande correcte est appliquée lorsque l'utilisateur appelle setup-log :

@Command(name = "setup-log", description = "Setup our log") public class LoggingCommand implements Runnable { @Inject private HelpOption help; @Option(name = { "-v", "--verbose" }, description = "Set log verbosity on/off") private boolean verbose = false; @Override public void run() { if (!help.showHelpIfRequested()) System.out.println("Verbosity: " + verbose); } } }

Examinons de plus près notre exemple de commande.

Tout d'abord, nous avons défini une description pour que notre assistant, grâce à l'injection, affiche nos options de commande à la demande.

Ensuite, nous avons déclaré une variable booléenne , verbeuse , et l' avons annotée avec @Option pour lui donner un nom, une description, ainsi qu'un alias -v / –verbose pour représenter notre option de ligne de commande pour contrôler la verbosité.

Enfin, dans la méthode run , nous avons demandé à notre commande de s'arrêter chaque fois que l'utilisateur demande de l'aide.

Jusqu'ici tout va bien. Maintenant, nous devons ajouter notre nouvelle commande à l'interface principale en modifiant l' annotation @ Cli :

@Cli(name = "baeldung-cli", description = "Baeldung Airline Tutorial", defaultCommand = Help.class, commands = { LoggingCommand.class, Help.class }) public class CommandLine { public static void main(String[] args) { Cli cli = new Cli(CommandLine.class); Runnable cmd = cli.parse(args); cmd.run(); } } 

Maintenant, si nous transmettons setup-log -v à notre programme, il exécutera notre logique.

6. Contraintes et plus

Nous avons vu comment Airline génère parfaitement CLI, mais… il y a plus!

Nous pouvons spécifier des contraintes (ou restrictions) pour nos paramètres afin de gérer les valeurs autorisées, les exigences ou les dépendances, etc.

Nous allons créer une classe DatabaseSetupCommand , qui répondra à la commande setup-db ; comme nous l'avons fait plus tôt, mais nous ajouterons du piquant.

Tout d'abord, nous allons demander le type de base de données, en n'acceptant que 3 valeurs valides via @AllowedRawValues :

@AllowedRawValues(allowedValues = { "mysql", "postgresql", "mongodb" }) @Option(type = OptionType.COMMAND, name = {"-d", "--database"}, description = "Type of RDBMS.", title = "RDBMS type: mysql|postgresql|mongodb") protected String rdbmsMode;

Lors de l'utilisation d'une connexion à une base de données, sans aucun doute, les utilisateurs doivent fournir un point de terminaison et des informations d'identification pour y accéder. Nous laisserons la CLI gérer cela via un ( mode URL) ou plusieurs paramètres ( mode hôte ). Pour cela, nous utiliserons l' annotation @MutuallyExclusiveWith , marquant chaque paramètre avec la même balise:

@Option(type = OptionType.COMMAND, name = {"--rdbms:url", "--url"}, description = "URL to use for connection to RDBMS.", title = "RDBMS URL") @MutuallyExclusiveWith(tag="mode") @Pattern(pattern="^(//.*):(d*)(.*)u=(.*)&p=(.*)") protected String rdbmsUrl = ""; @Option(type = OptionType.COMMAND, name = {"--rdbms:host", "--host"}, description = "Host to use for connection to RDBMS.", title = "RDBMS host") @MutuallyExclusiveWith(tag="mode") protected String rdbmsHost = ""; 

Notez que nous avons utilisé le décorateur @Pattern , qui nous aide à définir le format de la chaîne URL.

Si nous regardons la documentation du projet, nous trouverons d'autres outils précieux pour gérer les exigences, les occurrences, les valeurs autorisées, les cas spécifiques, etc., nous permettant de définir nos règles personnalisées .

Enfin, si l'utilisateur a sélectionné le mode hôte, nous devrions lui demander de fournir ses informations d'identification. De cette manière, une option dépend d'une autre. Nous pouvons obtenir ce comportement avec l' annotation @RequiredOnlyIf :

@RequiredOnlyIf(names={"--rdbms:host", "--host"}) @Option(type = OptionType.COMMAND, name = {"--rdbms:user", "-u", "--user"}, description = "User for login to RDBMS.", title = "RDBMS user") protected String rdbmsUser; @RequiredOnlyIf(names={"--rdbms:host", "--host"}) @Option(type = OptionType.COMMAND, name = {"--rdbms:password", "--password"}, description = "Password for login to RDBMS.", title = "RDBMS password") protected String rdbmsPassword; 

Que faire si nous devons utiliser certains pilotes pour gérer la connexion DB? Et aussi, supposons que nous ayons besoin de recevoir plus d'une valeur dans un seul paramètre. Nous pouvons simplement changer le type d'option en OptionType.ARGUMENTS ou - encore mieux - accepter une liste de valeurs:

@Option(type = OptionType.COMMAND, name = {"--driver", "--jars"}, description = "List of drivers", title = "--driver  --driver ") protected List jars = new ArrayList();

Maintenant, n'oublions pas d'ajouter la commande de configuration de la base de données à notre classe principale. Sinon, il ne sera pas disponible sur CLI.

7. Exécuter

Nous l'avons fait! Nous avons terminé notre projet et maintenant nous pouvons l'exécuter.

Comme prévu, sans passer de paramètres, l' aide est appelée:

$ baeldung-cli usage: baeldung-cli  [  ] Commands are: help Display help information setup-db Setup our database setup-log Setup our log See 'baeldung-cli help ' for more information on a specific command.

Si nous exécutons à la place setup-log –help , nous obtenons:

$ baeldung-cli setup-log --help NAME baeldung-cli setup-log - Setup our log SYNOPSIS baeldung-cli setup-log [ -h  ] [ -v  ] OPTIONS -h, --help Display help information -v, --verbose Set log verbosity on/off

Enfin, la fourniture de paramètres à ces commandes exécutera la logique métier correcte.

8. Conclusion

Dans cet article, nous avons construit une interface de ligne de commande simple mais puissante avec très peu de codage.

La bibliothèque Airline, avec ses puissantes fonctionnalités, simplifie la CLI en nous fournissant une infrastructure générale, propre et réutilisable . Cela nous permet, développeurs, de nous concentrer sur notre logique métier plutôt que de passer du temps à concevoir ce qui devrait être trivial.

Comme toujours, le code peut être trouvé sur GitHub.