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;
}