S-JIS[2022-09-07/2022-09-12] 変更履歴

JCommander Parameters

JCommanderの@Parametersのメモ。


概要

JCommanderでは、コマンドラインパラメーターを解析 した結果の値を入れるクラスを、ユーザープログラマーが用意する。
そのクラスでは、フィールドに@Parameterアノテーションを付けてコマンドラインパラメーターを定義するが、
全フィールドに影響する設定は、クラスに@Parametersアノテーションを付けて行う。


import com.beust.jcommander.Parameters;
@Parameters(separators = "=")
public class MyArgument {
    〜
}

Parametersの設定内容

設定名 デフォルト値 説明
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;
}

JCommander目次へ戻る / Javaへ戻る / 技術メモへ戻る
メールの送信先:ひしだま