diff --git a/spring-shell-core/src/main/java/org/springframework/shell/command/annotation/support/CommandRegistrationFactoryBean.java b/spring-shell-core/src/main/java/org/springframework/shell/command/annotation/support/CommandRegistrationFactoryBean.java index 679ceb47..741acda6 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/command/annotation/support/CommandRegistrationFactoryBean.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/command/annotation/support/CommandRegistrationFactoryBean.java @@ -331,6 +331,8 @@ class CommandRegistrationFactoryBean implements FactoryBean optionSpec.position(mp.getParameterIndex()); if (ClassUtils.isAssignable(boolean.class, parameterType)) { optionSpec.arity(OptionArity.ZERO_OR_ONE); + optionSpec.required(false); + optionSpec.defaultValue("false"); } else if (ClassUtils.isAssignable(Boolean.class, parameterType)) { optionSpec.arity(OptionArity.ZERO_OR_ONE); diff --git a/spring-shell-core/src/test/java/org/springframework/shell/command/annotation/support/CommandRegistrationFactoryBeanTests.java b/spring-shell-core/src/test/java/org/springframework/shell/command/annotation/support/CommandRegistrationFactoryBeanTests.java index db40529b..d6045747 100644 --- a/spring-shell-core/src/test/java/org/springframework/shell/command/annotation/support/CommandRegistrationFactoryBeanTests.java +++ b/spring-shell-core/src/test/java/org/springframework/shell/command/annotation/support/CommandRegistrationFactoryBeanTests.java @@ -23,6 +23,7 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.shell.Availability; import org.springframework.shell.AvailabilityProvider; +import org.springframework.shell.command.CommandOption; import org.springframework.shell.command.CommandRegistration; import org.springframework.shell.command.CommandRegistration.OptionArity; import org.springframework.shell.command.annotation.Command; @@ -192,6 +193,18 @@ class CommandRegistrationFactoryBeanTests { assertThat(registration.getOptions().get(0).getArityMin()).isEqualTo(0); assertThat(registration.getOptions().get(0).getArityMax()).isEqualTo(1); }); + configCommon(OptionValuesWithBoolean.class, new OptionValuesWithBoolean(), "command5", new Class[] { boolean.class }) + .run((context) -> { + CommandRegistrationFactoryBean fb = context.getBean(FACTORYBEANREF, + CommandRegistrationFactoryBean.class); + assertThat(fb).isNotNull(); + CommandRegistration registration = fb.getObject(); + assertThat(registration).isNotNull(); + assertThat(registration.getOptions().get(0).getArityMin()).isEqualTo(0); + assertThat(registration.getOptions().get(0).getArityMax()).isEqualTo(1); + assertThat(registration.getOptions().get(0).isRequired()).isFalse(); + assertThat(registration.getOptions().get(0).getDefaultValue()).isEqualTo("false"); + }); } @Command @@ -212,6 +225,10 @@ class CommandRegistrationFactoryBeanTests { @Command void command4(Boolean arg) { } + + @Command + void command5(boolean arg) { + } } @Test diff --git a/spring-shell-samples/src/main/java/org/springframework/shell/samples/e2e/OptionTypeCommands.java b/spring-shell-samples/src/main/java/org/springframework/shell/samples/e2e/OptionTypeCommands.java index 68dd11dc..fa5eecb7 100644 --- a/spring-shell-samples/src/main/java/org/springframework/shell/samples/e2e/OptionTypeCommands.java +++ b/spring-shell-samples/src/main/java/org/springframework/shell/samples/e2e/OptionTypeCommands.java @@ -52,10 +52,11 @@ public class OptionTypeCommands { @ShellOption(defaultValue = "false") boolean arg3, @ShellOption() Boolean arg4, @ShellOption(defaultValue = "true") Boolean arg5, - @ShellOption(defaultValue = "false") Boolean arg6 + @ShellOption(defaultValue = "false") Boolean arg6, + boolean arg7 ) { - return String.format("Hello arg1=%s arg2=%s arg3=%s arg4=%s arg5=%s arg6=%s", arg1, arg2, arg3, arg4, arg5, - arg6); + return String.format("Hello arg1=%s arg2=%s arg3=%s arg4=%s arg5=%s arg6=%s arg7=%s", arg1, arg2, arg3, + arg4, arg5, arg6, arg7); } @ShellMethod(key = LEGACY_ANNO + "option-type-integer", group = GROUP) @@ -122,27 +123,16 @@ public class OptionTypeCommands { @Command(command = "option-type-boolean") public String optionTypeBooleanAnnotation( - @ShellOption() - @Option(longNames = "arg1") - boolean arg1, - @ShellOption(defaultValue = "true") - @Option(longNames = "arg2", defaultValue = "true") - boolean arg2, - @ShellOption(defaultValue = "false") - @Option(longNames = "arg3", defaultValue = "false") - boolean arg3, - @ShellOption() - @Option(longNames = "arg4") - Boolean arg4, - @ShellOption(defaultValue = "true") - @Option(longNames = "arg5", defaultValue = "true") - Boolean arg5, - @ShellOption(defaultValue = "false") - @Option(longNames = "arg6", defaultValue = "false") - Boolean arg6 + @Option(longNames = "arg1") boolean arg1, + @Option(longNames = "arg2", defaultValue = "true") boolean arg2, + @Option(longNames = "arg3", defaultValue = "false") boolean arg3, + @Option(longNames = "arg4") Boolean arg4, + @Option(longNames = "arg5", defaultValue = "true") Boolean arg5, + @Option(longNames = "arg6", defaultValue = "false") Boolean arg6, + boolean arg7 ) { - return String.format("Hello arg1=%s arg2=%s arg3=%s arg4=%s arg5=%s arg6=%s", arg1, arg2, arg3, arg4, arg5, - arg6); + return String.format("Hello arg1=%s arg2=%s arg3=%s arg4=%s arg5=%s arg6=%s arg7=%s", arg1, arg2, arg3, + arg4, arg5, arg6, arg7); } @Command(command = "option-type-integer") @@ -261,6 +251,10 @@ public class OptionTypeCommands { .type(Boolean.class) .defaultValue("false") .and() + .withOption() + .longNames("arg7") + .type(boolean.class) + .and() .withTarget() .function(ctx -> { boolean arg1 = ctx.hasMappedOption("arg1") ? ctx.getOptionValue("arg1") : false; @@ -269,8 +263,9 @@ public class OptionTypeCommands { Boolean arg4 = ctx.getOptionValue("arg4"); Boolean arg5 = ctx.getOptionValue("arg5"); Boolean arg6 = ctx.getOptionValue("arg6"); - return String.format("Hello arg1=%s arg2=%s arg3=%s arg4=%s arg5=%s arg6=%s", arg1, arg2, arg3, - arg4, arg5, arg6); + boolean arg7 = ctx.hasMappedOption("arg7") ? ctx.getOptionValue("arg7") : false; + return String.format("Hello arg1=%s arg2=%s arg3=%s arg4=%s arg5=%s arg6=%s arg7=%s", arg1, + arg2, arg3, arg4, arg5, arg6, arg7); }) .and() .build(); diff --git a/spring-shell-standard/src/main/java/org/springframework/shell/standard/StandardMethodTargetRegistrar.java b/spring-shell-standard/src/main/java/org/springframework/shell/standard/StandardMethodTargetRegistrar.java index 67958e20..87c7fc54 100644 --- a/spring-shell-standard/src/main/java/org/springframework/shell/standard/StandardMethodTargetRegistrar.java +++ b/spring-shell-standard/src/main/java/org/springframework/shell/standard/StandardMethodTargetRegistrar.java @@ -201,6 +201,8 @@ public class StandardMethodTargetRegistrar implements MethodTargetRegistrar { .position(mp.getParameterIndex()); if (ClassUtils.isAssignable(boolean.class, parameterType)) { optionSpec.arity(OptionArity.ZERO_OR_ONE); + optionSpec.required(false); + optionSpec.defaultValue("false"); } else if (ClassUtils.isAssignable(Boolean.class, parameterType)) { optionSpec.arity(OptionArity.ZERO_OR_ONE); diff --git a/spring-shell-standard/src/test/java/org/springframework/shell/standard/StandardMethodTargetRegistrarTests.java b/spring-shell-standard/src/test/java/org/springframework/shell/standard/StandardMethodTargetRegistrarTests.java index c1dd2a52..d6fb4fef 100644 --- a/spring-shell-standard/src/test/java/org/springframework/shell/standard/StandardMethodTargetRegistrarTests.java +++ b/spring-shell-standard/src/test/java/org/springframework/shell/standard/StandardMethodTargetRegistrarTests.java @@ -437,8 +437,8 @@ public class StandardMethodTargetRegistrarTests { assertThat(catalog.getRegistrations().get("foo4")).isNotNull(); assertThat(catalog.getRegistrations().get("foo4").getOptions()).hasSize(1); - assertThat(catalog.getRegistrations().get("foo4").getOptions().get(0).isRequired()).isTrue(); - assertThat(catalog.getRegistrations().get("foo4").getOptions().get(0).getDefaultValue()).isNull(); + assertThat(catalog.getRegistrations().get("foo4").getOptions().get(0).isRequired()).isFalse(); + assertThat(catalog.getRegistrations().get("foo4").getOptions().get(0).getDefaultValue()).isEqualTo("false"); assertThat(catalog.getRegistrations().get("foo4").getOptions().get(0).getArityMin()).isEqualTo(0); assertThat(catalog.getRegistrations().get("foo4").getOptions().get(0).getArityMax()).isEqualTo(1); }