シンプルな CLI アプリを作る機会があり、ちょうど Micronaut を試してみたかったので Micronaut で作ってみました。備忘録。
Standalone Command Line Applications - Micronaut
準備
Micronaut は Scoop でインストール。
> scoop search micronaut 'main' bucket: micronaut (1.2.6) > scoop install micronaut Installing 'micronaut' (1.2.6) [64bit] micronaut-1.2.6.zip (12.3 MB) [=================================================================================================] 100% Checking hash of micronaut-1.2.6.zip ... ok. Extracting micronaut-1.2.6.zip ... done. Linking ~\scoop\apps\micronaut\current => ~\scoop\apps\micronaut\1.2.6 Creating shim for 'mn'. 'micronaut' (1.2.6) was installed successfully! > mn --version | Micronaut Version: 1.2.6 | JVM Version: 1.8.0_212
Scoop についてはこちら。
今回試したサンプルのプロジェクトはこちら。
kntmr/playground/micronaut-cli-examples - GitHub
プロジェクト作成
--features
にコンポーネントを指定すると依存関係に追加してくれる。
> mn create-cli-app com.example.app --features http-client
Picocli
Micronaut では Picocli を使って CLI アプリを作る。この Picocli がとても便利。
Micronaut Picocli Configuration - Micronaut
コマンドライン引数は @Option
アノテーションを付与したフィールドにバインドされる。さらに、カンマ区切りの値を配列にしてくれたり、ファイルパスを File
オブジェクトにしてくれたり。
@Option(names = {"-a"}, split = ",") String[] array = {}; // 初期値 @Option(names = {"-f"}) File file;
@Mixin
はコマンドライン引数を1つのオブジェクトにまとめてくれるものかと思ってたけどそうではない。ドキュメントには共通のオプションとパラメータを再利用するためにあると書いてある。
@Mixin private Options options; static class Options { @Option(names = {"-v", "--verbose"}, description = "...") boolean verbose; @Option(names = {"-a"}, split = ",") String[] array = {}; @Option(names = {"-f"}) File file; }
IDE 上からコマンドライン引数を渡す場合は Gradle Tasks で --args="-v"
で実行する。ただ、2つ目以降の引数を正しく認識してくれない...。要調査。
run --args="-v -a=foo,bar" #=> Unknown command-line option '-a'.
CLI アプリ終了時に任意のステータスコードを返したい場合は Callable<Integer>
を実装して call()
の中でステータスコードを返す。もう少しいい書き方があるかもしれない。
@Command(name = "app") public class AppCommand implements Callable<Integer> { public static void main(String[] args) throws Exception { int exitStatus = PicocliRunner.execute(AppCommand.class, args); System.exit(exitStatus); } @Override public Integer call() throws Exception { return 0; } }
その他
Maven を使う場合、mvnw compile exec:exec
や mvnw package
でコケることがある。以下の通り、pom.xml を修正する。
CLI generates a non working pom.xml for cli apps (1.2.0) #2031 - GitHub
あと、先日の JJUG CCC 2019 Fall で Picocli のひとが来てたらしい。(家庭の事情で CCC には参加できず...)