1
votes

Définissez une option qui a à la fois un argument obligatoire et facultatif

J'essaie actuellement de trouver un moyen de créer une option de ligne de commande qui, lorsqu'elle est fournie, peut prendre un argument requis ou un deuxième argument facultatif (en plus de celui requis). J'essaie d'y parvenir en utilisant apache commons cli.

i.e. monProgramme -a [entier]

myProgram -a "test" --> isValid
myProgram -a "test" 2 --> also isValid

J'ai essayé: Option.builder("a").hasArg().numberOfArgs(2).optionalArg(true).build();

&

Option.builder ("a"). hasArg (). numberOfArgs (2) .build ();

Aucun des deux ne fonctionne comme vous le souhaitez. Le premier exemple rend les deux arguments facultatifs et permet de passer des arguments vides, ce qui va à l'encontre des exigences.

Le deuxième exemple rend les deux paramètres obligatoires et échoue lorsque seul le type de chaîne arg est fourni.

J'ai regardé la documentation de commons cli mais les cas d'utilisation qu'ils ont fournis n'ont pas touché des cas complexes comme celui-ci, et de même, je n'ai pas obtenu beaucoup de détails dans la documentation de l'API.

Je m'attends à ce que le programme échoue quand -a est fourni sans valeur, mais pour réussir lorsqu'il est fourni avec 1 ou 2 arguments comme indiqué précédemment.


0 commentaires

3 Réponses :


0
votes

D'après ma compréhension de la documentation pour appache-commons-cli (et je me trompe peut-être), il ne semble pas y avoir de moyen de définir "optionalArg" par argument.

De plus, le Comme je le vois utilisé dans les exemples, il semble prendre des arguments avec des séparateurs entre les deux, comme dans -D= au lieu d'espaces? Je n'en suis pas sûr.

Mais oui, pour ce que vous voulez, vous pouvez le faire sale et autoriser des arguments optionnels, puis le rejeter lorsque l'option n'a pas l'argument requis (ce qui va à l'encontre du but de l'utilisation de commons-cli je sais).

EDIT: Avez-vous essayé d'utiliser PatternOptionBuilder ? Cet exemple m'intrigue:

Par exemple, ce qui suit autorise les indicateurs de ligne de commande '-v -p string-value -f / dir / file '. Le point d'exclamation précède un option.

 Options options = PatternOptionBuilder.parsePattern("vp:!f/");

Il dit que le point d'exclamation peut être utilisé avant les options obligatoires, mais je ne suis pas sûr qu'il puisse être utilisé avec des arguments obligatoires? Je n'ai cependant pas essayé.


4 commentaires

Sale, c'est ce que j'essaye en ce moment, mais ce n'est pas assez pour autant hehe je pense que la méthode avec séparateurs casse également les exigences de l'application que j'écris.


J'ai regardé PatternOptionBuilder. Semblait plus approprié pour spécifier quels devraient être les arguments de la ligne de commande (et l'ordre) plutôt que de me permettre de spécifier des combinaisons plus complexes autres que l'option-valeur standard. Je suis allé très loin et j'ai fait ce que j'ai suggéré. Rendez les deux arguments facultatifs, puis vérifiez leur existence et agissez en conséquence. Merci pour la paire d'yeux supplémentaire, je l'apprécie.


De rien. Si cela ne vous dérange pas d'accepter la réponse si elle vous a réellement été utile.


Si vous suivez ce chemin, notez que la longue description d'un argument peut être définie. Ainsi, il peut toujours être décrit à l'utilisateur dans l'aide.



0
votes

Dans le passé, dans ces circonstances, j'ai ajouté une deuxième option. Donc, dans votre exemple, -b.

-b [bvalue]   If -a is enabled, ensure that it uses bvalue to thinginate.

Si votre deuxième valeur (facultative) agit comme un indicateur, il peut simplement s'agir d'un indicateur booléen.

Si votre deuxième ( optionnel) est une entrée plus arbitraire, cette deuxième option peut prendre un seul argument obligatoire.

Bien que je sois sûr que vous avez des raisons d'organiser vos arguments comme -a reqdval optval , il en résultera souvent une ligne de commande plus utilisable pour ne pas avoir ces multiples couches d'options de toute façon (c'est-à-dire l'existence d'une deuxième valeur facultative dans une option). Vous pourriez le considérer comme la différence UX entre un menu imbriqué à deux niveaux et un menu imbriqué à trois niveaux. Avec un nombre limité d'éléments, le menu à deux niveaux est souvent plus utilisable. (Et sans détails plus spécifiques sur votre cas d'utilisation, les réponses doivent être d'ordre général.)


0 commentaires

0
votes

Vous avez donc une option qui peut être fournie zéro ou une fois, et peut avoir une ou deux valeurs?

DEBUG :: [-a, b] : [b]
DEBUG :: [-a, b, c] : [b, c]
final Options options = new Options()
            .addOption(Option.builder("a").hasArg().hasArgs().build());
CommandLine cmd = new DefaultParser().parse(options, args);
LOG.debug(Arrays.asList(args).toString() + " : " + Arrays.asList(cmd.getOptionValues("a")).toString());

Vous voudrez peut-être augmenter votre propres exceptions d'analyse lorsque trop ou trop peu d'arguments sont fournis.

Regardez cette réponse si vous voulez fournir -a plusieurs fois: https://stackoverflow.com/a/64611857/8656281


0 commentaires