So che questa domanda è stata già posta, ma sto cercando un pars parser Java con una funzionalità specifica. Voglio che sia in grado di definire l'albero della riga di comando, quindi utilizzando i sottocomandi (e più di una profondità di livello). Quindi posso avere 3-4 livelli di comandi prima di arrivare alle opzioni. E questi sottocomandi si escludono a vicenda. GrazieJava CLI Parser
risposta
Può essere eseguito con JCommander. Ogni oggetto JCommander
è, nella sua essenza, un comando con numero arbitrario di parametri e/o numero arbitrario di sottocomandi nidificati, dove l'oggetto top JCommander
è il comando radice radice. I parametri di comando sono sempre specifici del comando per cui sono stati dichiarati e non interferiscono con i parametri di altri comandi. L'interfaccia per l'aggiunta di un sub-comando non è molto intuitivo, ma è possibile (vedere il metodo addCommand
())
Ecco una classe di test proof-of-concept:
public class Test{
@Test
public void nestedSubCommandTest() {
GeneralOptions generalOpts = new GeneralOptions();
JCommander jc = new JCommander(generalOpts);
Command command = new Command();
JCommander jc_command = addCommand(jc, "command", command);
SubCommand1 subcommand1 = new SubCommand1();
JCommander jc_subcommand1 = addCommand(jc_command, "subcommand1",
subcommand1);
SubCommand2 subcommand2 = new SubCommand2();
JCommander jc_subcommand2 = addCommand(jc_subcommand1, "subcommand2",
subcommand2);
SubCommand3 subcommand3 = new SubCommand3();
addCommand(jc_subcommand2, "subcommand3", subcommand3);
jc.parse("--general-opt",
"command", "--opt",
"subcommand1",
"subcommand2", "--sub-opt2",
"subcommand3", "--sub-opt3");
assertTrue(generalOpts.opt);// --general-opt was set
assertTrue(command.opt);// command --opt was set
assertFalse(subcommand1.opt);// subcommand1 --sub-opt1 was not set
assertTrue(subcommand2.opt);// subcommand2 --sub-opt2 was set
assertTrue(subcommand3.opt);// subcommand3 --sub-opt3 was set
}
private static JCommander addCommand(JCommander parentCommand,
String commandName, Object commandObject) {
parentCommand.addCommand(commandName, commandObject);
return parentCommand.getCommands().get(commandName);
}
public static class GeneralOptions {
@Parameter(names = "--general-opt")
public boolean opt;
}
@Parameters
public static class Command {
@Parameter(names = "--opt")
public boolean opt;
}
@Parameters
public static class SubCommand1 {
@Parameter(names = "--sub-opt1")
public boolean opt;
}
@Parameters
public static class SubCommand2 {
@Parameter(names = "--sub-opt2")
public boolean opt;
}
@Parameters
public static class SubCommand3 {
@Parameter(names = "--sub-opt3")
public boolean opt;
}
}
Edit: Come riutilizzare i comandi.
Soluzione 1, utilizzare l'ereditarietà:
public class CommonArgs{
@Parameter(names="--common-opt")
public boolean isCommonOpt;
}
@Parameters(description = "my command 1")
public class MyCommand1 extends CommonArgs{}
@Parameters(description = "my command 2")
public class MyCommand2 extends CommonArgs{}
penso che l'utilizzo e il comportamento è faily ovvia per questo. L'unico inconveniente è che è possibile estendere solo da una classe, che potrebbe limitare la riutilizzabilità in futuro.
Soluzione 2, usando il modello della composizione (vedere la doc here):
public class CommonArgs{
@Parameter(names="--common-opt")
public boolean isCommonOpt;
}
@Parameters(description = "my command 1")
public class MyCommand1{
@ParametersDelegate
public CommonArgs commonArgs = new CommonArgs();
}
@Parameters(description = "my command 2")
public class MyCommand2{
@ParametersDelegate
public CommonArgs commonArgs = new CommonArgs();
}
Qui, i parametri annidati commonArgs
classi verranno trattati come se fossero parametri diretti della classe comando. Puoi aggiungere tutti i delegati che desideri o persino annidare i delegati all'interno di altri delegati e così via. Per ottenere il valore dell'opzione delegata dopo l'analisi, è sufficiente fare myCommand1.commonArgs.isCommonOpt
, ecc.
Ciao. In realtà gioco con JCommander tutto il giorno. Ho pochi problemi con esso. Le eccezioni del parser non sono chiare, non posso introdurle all'utente. Un'altra cosa è che ho bisogno di creare una command class per comando (e ne ho molti), non posso riutilizzarli perché le annotazioni non sono generiche. Oh e l'uso() non stampa realmente tutti i sottocomandi e le opzioni. – Sophie
Probabilmente JCommander non è stato progettato con i sottocomandi come priorità assoluta, è più di una funzione * nascosta *, se lo si desidera. Non ci sono molti casi eccezionali, quindi puoi probabilmente racchiuderli in qualcosa di più utile. Per quanto riguarda 'usage()' sembra che non ci sia il supporto ufficiale dei sottocomandi, quindi dovrete fare un po 'di hacking, o semplicemente scrivere a mano. Non posso essere d'accordo sul riutilizzo, però, la riusabilità è l'unica cosa che amo di JCommander. Potrei essere in grado di aiutarti se mi fornisci un esempio concreto. – rodion
Ok. Grazie! Quindi, per esempio, ho 2 comandi con nomi diversi e descrizioni diverse, ma entrambi ottengono gli stessi parametri. quindi, per impostare la descrizione, devo avere diverse istanze di classe di comando anche se i pararetri all'interno della classe saranno uguali. – Sophie
Penso che sarebbe meglio suddividere questi comandi a più livelli in diversi strumenti CLI.
Invece di:
program cmd sub-cmd sub-sub-cmd -option1 argument -option2 argument
Aggiunge uno o due livelli di programmare nome:
program-cmd-sub-cmd sub-sub-cmd -option1 argument -option2 argument
parola esempio reale:
svn-add -q -N foo.c
Si potrebbe mantenere tutte le classi richieste a singolo JAR (e riutilizzali quanto vuoi), aggiungi solo alcuni punti di accesso "principali". Per l'analisi CLI di base, raccomando anche JCommander
.
picocli supporta sottocomandi nidificati a profondità arbitraria.
CommandLine commandLine = new CommandLine(new MainCommand())
.addSubcommand("cmd1", new ChildCommand1()) // 1st level
.addSubcommand("cmd2", new ChildCommand2())
.addSubcommand("cmd3", new CommandLine(new ChildCommand3()) // 2nd level
.addSubcommand("cmd3sub1", new GrandChild3Command1())
.addSubcommand("cmd3sub2", new GrandChild3Command2())
.addSubcommand("cmd3sub3", new CommandLine(new GrandChild3Command3()) // 3rd
.addSubcommand("cmd3sub3sub1", new GreatGrandChild3Command3_1())
.addSubcommand("cmd3sub3sub2", new GreatGrandChild3Command3_2())
// etc
)
);
Potrebbe piacerti anche il suo utilizzo come aiuto con stili e colori ANSI.
Si noti che la guida all'utilizzo elenca i sottocomandi registrati oltre alle opzioni e ai parametri posizionali.
L'aiuto utilizzo è facilmente personalizzabile con annotazioni.
- annotazione basata
- sottocomandi git in stile
- annidati sotto-sottocomandi
- opzione parametri fortemente tipizzati
- fortemente tipizzati parametri posizionali
- tipo di conversione personalizzabile
- opzioni multi-valore
- modello intuitivo per quanti argomenti un campo consuma
- API fluente
- POSIX-style cluster opzioni brevi opzioni lunghe
- stile GNU
- permette qualsiasi prefisso opzione
- colori ANSI in help d'uso
- aiuto d'uso personalizzabile
- unico file sorgente: include come sorgente per mantenere l'applicazione un singolo jar
- 1. parser robots.txt java
- 2. Parser RTF Java
- 3. parser Java scritto in JavaScript
- 4. Java SAX progresso parser monitoraggio
- 5. PDF Parser API in Java
- 6. parser SPARQL per Java Codice
- 7. parser completo LaTeX in Java
- 8. Java UI-design CLI: framework o librerie?
- 9. C'è un semplice linter CLI Java?
- 10. parser di espressioni booleane in java
- 11. Esiste un parser Java per BER-TLV?
- 12. Un parser di schema MySQL in Java?
- 13. Parser XML Java per file enormi
- 14. Rimozione del nodo XML utilizzando parser java
- 15. Ricerca di un parser CSS in java
- 16. C'è qualche buon parser X12 in Java?
- 17. Java. Parser Sax. Come interrompere manualmente l'analisi?
- 18. Quali parser Java standalone sono disponibili?
- 19. parser Java Jsoup Java: esecuzione di eventi javascript
- 20. Esiste un parser Java per il linguaggio Java?
- 21. Generatore di parser/parser combinato
- 22. Benchmark per parser JSON?
- 23. Problema di parser Spirit e Lex parser
- 24. Commons Gruppi richiesti CLI
- 25. Stanford Parser utilizzo multithread
- 26. Java comuni-CLI, opzioni con elenco di valori possibili
- 27. Ricerca di un parser di stringa User Agent Java
- 28. C'è un parser Java che può analizzare indirizzi come questo
- 29. Un parser Java SAX recupera effettivamente la DTD da Internet?
- 30. qual è il miglior parser html per java?
Puoi pubblicare alcuni esempi di comandi che intendi analizzare? – dash1e
comando secondario sub-comando secondario -opzione1 argomento -opzione2 argomento – Sophie