コマンド登録

コマンド登録の定義は、コマンドの構造とそのオプションおよびパラメーターを導入するための最初のステップです。これは、コマンドライン入力の解析や実際のターゲットコードの実行など、後で行われることから大まかに切り離されます。基本的に、これはユーザーに表示されるコマンド API の定義です。

コマンド

spring-shell 構造体のコマンドは、コマンドの配列として定義されます。これにより、次の例のような構造が得られます。

command1 sub1
command2 sub1 subsub1
command2 sub2 subsub1
command2 sub2 subsub2
サブコマンドが定義されている場合、コマンドを明示的な親にマッピングすることは現在サポートされていません。例: command1 sub1 と command1 sub1 subsub1 の両方を登録することはできません。

インタラクションモード

Spring Shell は 2 つのモードで動作するように設計されています: 対話型 (基本的に、一連のコマンド全体でアクティブなシェルインスタンスを持つ REPL ) と非対話型 (コマンドラインからコマンドが 1 つずつ実行される)。

これらのモードの主な違いは、各モードで実行できることに関する制限です。例: シェルがアクティブでなくなった場合、コマンドの以前のスタックトレースを表示することはできません。一般に、シェルがまだアクティブであるかどうかによって、利用可能な情報が決まります。

また、アクティブな REPL セッションにいると、アクティブなセッション内でユーザーが何をしてきたかについて、より多くの情報が得られる場合があります。

オプション

オプションは long と short として定義でき、プレフィックスはそれぞれ -- と - です。次の例は、長いオプションと短いオプションを示しています。

CommandRegistration.builder()
	.withOption()
		.longNames("myopt")
		.and()
	.build();
CommandRegistration.builder()
	.withOption()
		.shortNames('s')
		.and()
	.build();

ターゲット

target は、コマンドの実行対象を定義します。POJO、Consumer、または Function のメソッドにすることができます。

メソッド

既存の POJO で Method を使用することは、ターゲットを定義する 1 つの方法です。次のクラスを検討してください。

public static class CommandPojo {

	String command(String arg) {
		return arg;
	}
}

前のリストに示されている既存のクラスを指定すると、そのメソッドを登録できます。

CommandPojo pojo = new CommandPojo();
CommandRegistration.builder()
	.command("command")
	.withTarget()
		.method(pojo, "command")
		.and()
	.withOption()
		.longNames("arg")
		.and()
	.build();

関数

Function をターゲットとして使用すると、Function に指定された CommandContext を使用して多くのことを手動で処理できるため、コマンド実行で発生する処理を柔軟に処理できます。Function からの戻り値の型は、結果としてシェルに出力されるものです。次の例を検討してください。

CommandRegistration.builder()
	.command("command")
	.withTarget()
		.function(ctx -> {
			String arg = ctx.getOptionValue("arg");
			return String.format("hi, arg value is '%s'", arg);
		})
		.and()
	.withOption()
		.longNames("arg")
		.and()
	.build();

コンシューマー

Consumer を使用することは基本的に Function を使用することと同じですが、違いは戻り値の型がないことです。何かをシェルに出力する必要がある場合は、コンテキストから Terminal への参照を取得し、それを介して何かを出力できます。次の例を検討してください。

CommandRegistration.builder()
	.command("command")
	.withTarget()
		.consumer(ctx -> {
			String arg = ctx.getOptionValue("arg");
			ctx.getTerminal().writer()
				.println(String.format("hi, arg value is '%s'", arg));
		})
	.and()
	.withOption()
		.longNames("arg")
		.and()
	.build();