Skip to content

Commit 8bed75a

Browse files
committed
Support plain boolean without option annotations
- Fix so that we can have `boolean arg` without using `@Option` or `@ShellOption` defaulting to false. - Fixes #744
1 parent 96402a7 commit 8bed75a

File tree

5 files changed

+43
-27
lines changed

5 files changed

+43
-27
lines changed

spring-shell-core/src/main/java/org/springframework/shell/command/annotation/support/CommandRegistrationFactoryBean.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,8 @@ else if (ClassUtils.isAssignable(boolean.class, parameterType)){
331331
optionSpec.position(mp.getParameterIndex());
332332
if (ClassUtils.isAssignable(boolean.class, parameterType)) {
333333
optionSpec.arity(OptionArity.ZERO_OR_ONE);
334+
optionSpec.required(false);
335+
optionSpec.defaultValue("false");
334336
}
335337
else if (ClassUtils.isAssignable(Boolean.class, parameterType)) {
336338
optionSpec.arity(OptionArity.ZERO_OR_ONE);

spring-shell-core/src/test/java/org/springframework/shell/command/annotation/support/CommandRegistrationFactoryBeanTests.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.springframework.context.annotation.Bean;
2424
import org.springframework.shell.Availability;
2525
import org.springframework.shell.AvailabilityProvider;
26+
import org.springframework.shell.command.CommandOption;
2627
import org.springframework.shell.command.CommandRegistration;
2728
import org.springframework.shell.command.CommandRegistration.OptionArity;
2829
import org.springframework.shell.command.annotation.Command;
@@ -192,6 +193,18 @@ void setsOptionValuesWithBoolean() {
192193
assertThat(registration.getOptions().get(0).getArityMin()).isEqualTo(0);
193194
assertThat(registration.getOptions().get(0).getArityMax()).isEqualTo(1);
194195
});
196+
configCommon(OptionValuesWithBoolean.class, new OptionValuesWithBoolean(), "command5", new Class[] { boolean.class })
197+
.run((context) -> {
198+
CommandRegistrationFactoryBean fb = context.getBean(FACTORYBEANREF,
199+
CommandRegistrationFactoryBean.class);
200+
assertThat(fb).isNotNull();
201+
CommandRegistration registration = fb.getObject();
202+
assertThat(registration).isNotNull();
203+
assertThat(registration.getOptions().get(0).getArityMin()).isEqualTo(0);
204+
assertThat(registration.getOptions().get(0).getArityMax()).isEqualTo(1);
205+
assertThat(registration.getOptions().get(0).isRequired()).isFalse();
206+
assertThat(registration.getOptions().get(0).getDefaultValue()).isEqualTo("false");
207+
});
195208
}
196209

197210
@Command
@@ -212,6 +225,10 @@ void command3(@Option Boolean arg) {
212225
@Command
213226
void command4(Boolean arg) {
214227
}
228+
229+
@Command
230+
void command5(boolean arg) {
231+
}
215232
}
216233

217234
@Test

spring-shell-samples/src/main/java/org/springframework/shell/samples/e2e/OptionTypeCommands.java

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,11 @@ public String optionTypeBooleanAnnotation(
5252
@ShellOption(defaultValue = "false") boolean arg3,
5353
@ShellOption() Boolean arg4,
5454
@ShellOption(defaultValue = "true") Boolean arg5,
55-
@ShellOption(defaultValue = "false") Boolean arg6
55+
@ShellOption(defaultValue = "false") Boolean arg6,
56+
boolean arg7
5657
) {
57-
return String.format("Hello arg1=%s arg2=%s arg3=%s arg4=%s arg5=%s arg6=%s", arg1, arg2, arg3, arg4, arg5,
58-
arg6);
58+
return String.format("Hello arg1=%s arg2=%s arg3=%s arg4=%s arg5=%s arg6=%s arg7=%s", arg1, arg2, arg3,
59+
arg4, arg5, arg6, arg7);
5960
}
6061

6162
@ShellMethod(key = LEGACY_ANNO + "option-type-integer", group = GROUP)
@@ -122,27 +123,16 @@ public String optionTypeStringAnnotation(
122123

123124
@Command(command = "option-type-boolean")
124125
public String optionTypeBooleanAnnotation(
125-
@ShellOption()
126-
@Option(longNames = "arg1")
127-
boolean arg1,
128-
@ShellOption(defaultValue = "true")
129-
@Option(longNames = "arg2", defaultValue = "true")
130-
boolean arg2,
131-
@ShellOption(defaultValue = "false")
132-
@Option(longNames = "arg3", defaultValue = "false")
133-
boolean arg3,
134-
@ShellOption()
135-
@Option(longNames = "arg4")
136-
Boolean arg4,
137-
@ShellOption(defaultValue = "true")
138-
@Option(longNames = "arg5", defaultValue = "true")
139-
Boolean arg5,
140-
@ShellOption(defaultValue = "false")
141-
@Option(longNames = "arg6", defaultValue = "false")
142-
Boolean arg6
126+
@Option(longNames = "arg1") boolean arg1,
127+
@Option(longNames = "arg2", defaultValue = "true") boolean arg2,
128+
@Option(longNames = "arg3", defaultValue = "false") boolean arg3,
129+
@Option(longNames = "arg4") Boolean arg4,
130+
@Option(longNames = "arg5", defaultValue = "true") Boolean arg5,
131+
@Option(longNames = "arg6", defaultValue = "false") Boolean arg6,
132+
boolean arg7
143133
) {
144-
return String.format("Hello arg1=%s arg2=%s arg3=%s arg4=%s arg5=%s arg6=%s", arg1, arg2, arg3, arg4, arg5,
145-
arg6);
134+
return String.format("Hello arg1=%s arg2=%s arg3=%s arg4=%s arg5=%s arg6=%s arg7=%s", arg1, arg2, arg3,
135+
arg4, arg5, arg6, arg7);
146136
}
147137

148138
@Command(command = "option-type-integer")
@@ -261,6 +251,10 @@ public CommandRegistration optionTypeBooleanRegistration() {
261251
.type(Boolean.class)
262252
.defaultValue("false")
263253
.and()
254+
.withOption()
255+
.longNames("arg7")
256+
.type(boolean.class)
257+
.and()
264258
.withTarget()
265259
.function(ctx -> {
266260
boolean arg1 = ctx.hasMappedOption("arg1") ? ctx.getOptionValue("arg1") : false;
@@ -269,8 +263,9 @@ public CommandRegistration optionTypeBooleanRegistration() {
269263
Boolean arg4 = ctx.getOptionValue("arg4");
270264
Boolean arg5 = ctx.getOptionValue("arg5");
271265
Boolean arg6 = ctx.getOptionValue("arg6");
272-
return String.format("Hello arg1=%s arg2=%s arg3=%s arg4=%s arg5=%s arg6=%s", arg1, arg2, arg3,
273-
arg4, arg5, arg6);
266+
boolean arg7 = ctx.hasMappedOption("arg7") ? ctx.getOptionValue("arg7") : false;
267+
return String.format("Hello arg1=%s arg2=%s arg3=%s arg4=%s arg5=%s arg6=%s arg7=%s", arg1,
268+
arg2, arg3, arg4, arg5, arg6, arg7);
274269
})
275270
.and()
276271
.build();

spring-shell-standard/src/main/java/org/springframework/shell/standard/StandardMethodTargetRegistrar.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ else if (ClassUtils.isAssignable(Boolean.class, parameterType)) {
201201
.position(mp.getParameterIndex());
202202
if (ClassUtils.isAssignable(boolean.class, parameterType)) {
203203
optionSpec.arity(OptionArity.ZERO_OR_ONE);
204+
optionSpec.required(false);
205+
optionSpec.defaultValue("false");
204206
}
205207
else if (ClassUtils.isAssignable(Boolean.class, parameterType)) {
206208
optionSpec.arity(OptionArity.ZERO_OR_ONE);

spring-shell-standard/src/test/java/org/springframework/shell/standard/StandardMethodTargetRegistrarTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -437,8 +437,8 @@ public void testOptionValuesWithBoolean() {
437437

438438
assertThat(catalog.getRegistrations().get("foo4")).isNotNull();
439439
assertThat(catalog.getRegistrations().get("foo4").getOptions()).hasSize(1);
440-
assertThat(catalog.getRegistrations().get("foo4").getOptions().get(0).isRequired()).isTrue();
441-
assertThat(catalog.getRegistrations().get("foo4").getOptions().get(0).getDefaultValue()).isNull();
440+
assertThat(catalog.getRegistrations().get("foo4").getOptions().get(0).isRequired()).isFalse();
441+
assertThat(catalog.getRegistrations().get("foo4").getOptions().get(0).getDefaultValue()).isEqualTo("false");
442442
assertThat(catalog.getRegistrations().get("foo4").getOptions().get(0).getArityMin()).isEqualTo(0);
443443
assertThat(catalog.getRegistrations().get("foo4").getOptions().get(0).getArityMax()).isEqualTo(1);
444444
}

0 commit comments

Comments
 (0)