JCommanderの@Parametersのメモ。
|
JCommanderでは、コマンドラインパラメーターを解析
した結果の値を入れるクラスを、ユーザープログラマーが用意する。
そのクラスでは、フィールドに@Parameterアノテーションを付けてコマンドラインパラメーターを定義するが、
全フィールドに影響する設定は、クラスに@Parametersアノテーションを付けて行う。
import com.beust.jcommander.Parameters;
@Parameters(separators = "=") public class MyArgument { 〜 }
設定名 | デフォルト値 | 例 | 説明 | |
---|---|---|---|---|
resourceBundle |
String |
|||
separators |
String |
空白文字 |
separators = "=" |
「--name=hishidama 」のような指定を行うための区切り文字を設定する。→区切り文字の例 |
commandDescription |
String |
サブコマンドで使用する。 | ||
commandDescriptionKey |
String |
|||
commandNames |
String[] |
サブコマンドで使用する。 | ||
hidden |
boolean |
false |
trueにすると、そのサブコマンドをusage()で表示しない。 |
デフォルトでは、「--name
」のパラメーターを定義してあるときに「--name=hishidama
」のようなパラメーターを渡すと、--nameとしては解釈されない。
Parametersのseparatorsで区切り文字を設定すると、その文字でパラメーターが区切られるようになる。
@Parameters(separators = "=") public class MyArgument { @Parameter(names = { "-n", "--name" }, description = "user name") private String name; }
「git add」「git commit」や「aws ec2」「aws emr」のような、サブコマンドを解析する例。[2022-09-12]
(自分は「サブコマンド」と呼んでいるが、JCommanderのドキュメントでは「command」)
サブコマンド用の引数クラスを用意し、JCommanderインスタンスに追加するだけ。
addCommandでコマンド名を指定する方法 | @Parametersでコマンド名を指定する方法 | |
---|---|---|
共通引数 |
class CommonArgument { @Parameter(names = "-v", description = "verbose") Boolean verbose; @Override public String toString() { 〜 } } |
class CommonArgument { @Parameter(names = "-v", description = "verbose") Boolean verbose; @Override public String toString() { 〜 } } |
add用引数 |
@Parameters( commandDescription = "add command" ) class AddArgument { @Parameter(names = "-i", description = "interactive") Boolean interactive; @Override public String toString() { 〜 } } |
@Parameters(
commandNames = "add",
commandDescription = "add command"
)
class AddArgument {
@Parameter(names = "-i", description = "interactive")
Boolean interactive;
@Override
public String toString() {
〜
}
}
|
commit用引数 |
@Parameters( commandDescription = "commit command" ) class CommitArgument { @Parameter(names = "--amend", description = "amend") Boolean amend; @Override public String toString() { 〜 } } |
@Parameters(
commandNames = "commit",
commandDescription = "commit command"
)
class CommitArgument {
@Parameter(names = "--amend", description = "amend")
Boolean amend;
@Override
public String toString() {
〜
}
}
|
生成 |
var argument = new CommonArgument(); var commit = new CommitArgument(); var add = new AddArgument(); JCommander commander = JCommander.newBuilder() .addObject(argument) .addCommand("commit", commit) .addCommand("add", add) .build(); |
var argument = new CommonArgument(); var commit = new CommitArgument(); var add = new AddArgument(); JCommander commander = JCommander.newBuilder() .addObject(argument) .addCommand(commit) .addCommand(add) .build(); |
commander.usage()でサブコマンドのパラメーターも表示される。
Usage: <main class> [options] [command] [command options] Options: -v verbose Commands: commit commit command Usage: commit [options] Options: --amend amend add add command Usage: add [options] Options: -i interactive
commander.getCommands()でサブコマンド毎のJCommanderインスタンスが取得できる。
これのusage()は、そのサブコマンドのみの使用方法となる。
Map<String, JCommander> map = commander.getCommands(); map.get("commit").usage();
↓
Usage: commit [options] Options: --amend amend
定義されていないサブコマンドが指定された場合はMissingCommandExceptionが発生する。
import com.beust.jcommander.MissingCommandException;
try { commander.parse(args); } catch (MissingCommandException e) { System.err.printf("unknown sub command: %s%n", e.getUnknownCommand()); JCommander commander = e.getJCommander(); Map<String, JCommander> map = commander.getCommands(); System.out.printf("sub commands=%s%n", map.keySet()); return; }
unknown sub command: hoge sub commands=[commit, add]
どのサブコマンドが指定されたかは、commander.getParsedCommand()で取得できる。
そして、指定されたサブコマンドの引数クラスに値がセットされる。
var argument = new CommonArgument(); var commit = new CommitArgument(); var add = new AddArgument();
String command = commander.getParsedCommand(); switch (command) { case "commit": executeCommit(argument, commit); break; case "add": executeAdd(argument, add); break; default: throw new AssertionError(command); }
サブコマンド用引数クラスが、共通クラスを継承することも可能。
class CommonCommandArgument { @Parameter(names = "-v", description = "verbose") Boolean verbose; }
@Parameters(commandNames = "commit", commandDescription = "commit command") class CommitArgument extends CommonCommandArgument { @Parameter(names = "--amend", description = "amend") Boolean amend; }