spring-shell icon indicating copy to clipboard operation
spring-shell copied to clipboard

required Boolean with non-default value

Open emileplas opened this issue 1 year ago • 2 comments
trafficstars

spring shell version: 3.1.6

In one of my commands, I want to make sure that the end-user specifically indicates whether they either want A or B by using a Boolean. I don't want to make the choice for the end user.

When I add the following @Option on my command:

@Option(required = true, description = "Description", longNames = "Some long name")  Boolean booleanOption

Spring Shell, automatically transforms the booleanOption to defaultValue false. The help menu of the command indicates that the booleanOption is optional.

When transforming into

@Option(required = true, description = "Description", longNames = "Some long name")  boolean booleanOption

Still, the help menu indicates the booleanOption as optional. I assume for 2 reasons that this should not be the case: (1) it is a boolean and not Boolean. (2) required is explicitly set to true. The defaultValue is again false.

Setting the defaultValue to 'true' explicitly seems to be working.

@Option(required = true, description = "Description", longNames = "Some long name", defaultValue = "true")boolean booleanOption

It will show that the boolean is optional, but the default value will be true.

But again, I didn't want to choose for the user. I want the end user to articulate their choice when doing a command specifically.

If I write:

@Option(required = true, description = "Description", longNames = "Some long name", defaultValue = "")Boolean booleanOption

Or

@Option(required = true, description = "Description", longNames = "Some long name", defaultValue = "null")Boolean booleanOption

The defaultValue still translates to false (while as a Boolean I would expect it to be able to be null).

Is this the intended behavior?

emileplas avatar Dec 14 '23 16:12 emileplas

Boolean/boolean values have a lot of baggage to keep backward compatibility for old versions. Essentially both boolean/Boolean are threaded same and I think it's Boolean.parseBoolean(String) where real value comes from.

At some point we did think if defaultValue should be Object and not a String as that would have then open a ways to possibly define "null" or effectively "null". But as we wanted to mimic what comes from terminal(which is always a string) we weren't sure of Object type would open a can of worms.

So essentially you'd like to have way for Boolean type to be null indicating that user didn't define an option?

jvalkeal avatar Dec 15 '23 16:12 jvalkeal

I understand. I am sure adapting the above-mentioned example to take a String, like:

@Option(required = true, description = "Description", longNames = "Some long name")  String booleanOption

could work as a solution. I do believe that using Boolean/boolean makes the code more readable, but that is an entirely other conversation.

I do think there are still 2 issues then:

  • when using a boolean (and not a Boolean), with the aforementioned @Option, if I remember correctly, Spring Shell still seems to indicate the boolean as optional. This seems, in the first place, to conflict with boolean, which can not or should not be null. Second it conflicts with the explicitly setting required to true (see the initial example).
  • Maybe the documentation could be elaborated further. Currently, it says: "Using boolean types is a bit more involved as there are boolean and Boolean where latter can be null. Boolean types are usually used as flags meaning argument value may not be needed.", which made me assume that Boolean values can be optional, and boolean values should never be optional.

Feel free to correct me at any point. I am sure there is a history behind all these decisions, that I am not aware of. Let me know if I can help with anything.

emileplas avatar Dec 20 '23 20:12 emileplas