コマンド構文

オプションと引数

コマンドオプションと引数は、メソッドパラメーターを使用して定義できます。

@Component
class GreetingCommands {

	@Command(name = "hi", description = "Say hi to a given name", group = "greetings",
			help = "A command that greets the user with 'Hi ${name}!' with a configurable suffix. Example usage: hi -s=! John")
	public void sayHi(
			@Argument(index = 0, description = "the name of the person to greet",
					defaultValue = "world") String name,
			@Option(shortName = 's', longName = "suffix", description = "the suffix of the greeting message",
					defaultValue = "!") String suffix) {
		System.out.println("Hi " + name + suffix);
	}

}

オプションは @Option アノテーションを使用して定義され、引数は @Argument アノテーションを使用して定義されます。オプションは名前付きで、引数は位置指定です。オプションには、短い名前(1 文字)と長い名前(複数文字)があります。

オプションは、メソッドパラメーターに検証アノテーションを追加することで、Bean 検証 API を使用して検証できます。詳細については、コマンドオプションの検証セクションを参照してください。

複数値引数は、配列またはコレクション型(例: ListSet)に @Arguments アノテーションをメソッドパラメーター型として使用することで定義できます。この場合、残りのコマンドライントークンはすべてコレクションに収集されます。

@Component
class ArgumentsCommands {

	@Command(name = "hi", description = "Say hi to given names", group = "greetings",
			help = "A command that greets users with a configurable suffix. Example usage: hi -s=! Foo Bar")
	public void sayHi(@Option(shortName = 's', longName = "suffix",
			description = "the suffix of the greeting message", defaultValue = "!") String suffix,
			@Arguments String[] names) {
		System.out.println("Hi " + String.join(", ", names) + suffix);
	}

}

@Arguments アノテーションには、コレクションに収集する引数の数を指定できる arity という属性があります。デフォルトでは、引数の数は指定されていないため、残りのトークンはすべて収集されます。引数の数を特定の数に設定すると、その数だけトークンが収集され、残りは個別の引数またはオプションとして扱われます。arity 属性の使用例を以下に示します。

@Component
class ArgumentsWithArityCommands {

	/**
	 * Real part of (a + bi)(c + di) = ac − bd.
	 */
	@Command(name = "real-part", description = "Calculate the real part of the product of two complex numbers",
			group = "math",
			help = "Calculate the real part of the product of two complex numbers. Example usage: real-part 1 2 3 4")
	public double realPartOfComplexProduct(@Arguments(arity = 2) double[] realParts,
			@Arguments(arity = 2) double[] imaginaryParts) {
		return realParts[0] * realParts[1] - imaginaryParts[0] * imaginaryParts[1];
	}

}

解析ルール

Spring Shell は Spring Boot と同じ解析規則に従いますが、POSIX スタイルに準拠した拡張機能を備えています。オプションは、--key=value または --key value の長い形式だけでなく、-k=value または -k value の短い形式でも指定できます。オプションと引数は任意の順序で指定できます。引数は他の引数と 0 から始まるインデックスで示されます。

CommandSyntax  ::= CommandName [SubCommandName]* [Option | Argument]*
CommandName    ::= String
SubCommandName ::= String
Option         ::= ShortOption | LongOption
ShortOption    ::= '-' Char ['='|' ']? String
LongOption     ::= '--' String ['='|' ']? String
Argument       ::= String

例:

$>mycommand mysubcommand --optionA=value1 arg1 -b=value2 arg2 --optionC value3 -d value4
オプションが指定された場合、たとえそれがブール値であっても、常にそのオプションの値を持つことが想定されます。これは、オプションの値と引数を区別するために必要です。また、短いオプションはグループ化できません(例: -abc はサポートされていません)。
曖昧さを避けるために、特にサブコマンドが関係する場合は、可能な限り位置引数よりも名前付きオプションを優先する必要があります ( コマンドラインインターフェースガイドライン (英語) を参照)。

解析ルールのカスタマイズ

Spring Shell 4 は、コマンド解析ルールをカスタマイズできる CommandParser という新しい API を提供しています。デフォルトの解析ルールがニーズに合わない場合は、CommandParser インターフェースを実装することで独自のパーサーを実装できます。カスタムパーサーを実装したら、アプリケーションコンテキストに Bean として登録すると、Spring Shell はそれを使用してコマンドを解析します。