Skip to content

Commit fa65a23

Browse files
committed
Support option label
- This adds `label` to `CommandOption` which is then used in a Help instead of type. - Fixes #424
1 parent 8548828 commit fa65a23

File tree

6 files changed

+113
-9
lines changed

6 files changed

+113
-9
lines changed

spring-shell-core/src/main/java/org/springframework/shell/command/CommandOption.java

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,13 @@ public interface CommandOption {
8787
*/
8888
int getArityMax();
8989

90+
/**
91+
* Gets a label.
92+
*
93+
* @return the label
94+
*/
95+
String getLabel();
96+
9097
/**
9198
* Gets an instance of a default {@link CommandOption}.
9299
*
@@ -96,7 +103,7 @@ public interface CommandOption {
96103
* @return default command option
97104
*/
98105
public static CommandOption of(String[] longNames, Character[] shortNames, String description) {
99-
return of(longNames, shortNames, description, null, false, null, null, null, null);
106+
return of(longNames, shortNames, description, null, false, null, null, null, null, null);
100107
}
101108

102109
/**
@@ -110,7 +117,7 @@ public static CommandOption of(String[] longNames, Character[] shortNames, Strin
110117
*/
111118
public static CommandOption of(String[] longNames, Character[] shortNames, String description,
112119
ResolvableType type) {
113-
return of(longNames, shortNames, description, type, false, null, null, null, null);
120+
return of(longNames, shortNames, description, type, false, null, null, null, null, null);
114121
}
115122

116123
/**
@@ -125,12 +132,14 @@ public static CommandOption of(String[] longNames, Character[] shortNames, Strin
125132
* @param position the position value
126133
* @param arityMin the min arity
127134
* @param arityMax the max arity
135+
* @param label the label
128136
* @return default command option
129137
*/
130138
public static CommandOption of(String[] longNames, Character[] shortNames, String description,
131-
ResolvableType type, boolean required, String defaultValue, Integer position, Integer arityMin, Integer arityMax) {
139+
ResolvableType type, boolean required, String defaultValue, Integer position, Integer arityMin,
140+
Integer arityMax, String label) {
132141
return new DefaultCommandOption(longNames, shortNames, description, type, required, defaultValue, position,
133-
arityMin, arityMax);
142+
arityMin, arityMax, label);
134143
}
135144

136145
/**
@@ -147,10 +156,11 @@ public static class DefaultCommandOption implements CommandOption {
147156
private int position;
148157
private int arityMin;
149158
private int arityMax;
159+
private String label;
150160

151161
public DefaultCommandOption(String[] longNames, Character[] shortNames, String description,
152162
ResolvableType type, boolean required, String defaultValue, Integer position,
153-
Integer arityMin, Integer arityMax) {
163+
Integer arityMin, Integer arityMax, String label) {
154164
this.longNames = longNames != null ? longNames : new String[0];
155165
this.shortNames = shortNames != null ? shortNames : new Character[0];
156166
this.description = description;
@@ -160,6 +170,7 @@ public DefaultCommandOption(String[] longNames, Character[] shortNames, String d
160170
this.position = position != null && position > -1 ? position : -1 ;
161171
this.arityMin = arityMin != null ? arityMin : -1;
162172
this.arityMax = arityMax != null ? arityMax : -1;
173+
this.label = label;
163174
}
164175

165176
@Override
@@ -206,5 +217,10 @@ public int getArityMin() {
206217
public int getArityMax() {
207218
return arityMax;
208219
}
220+
221+
@Override
222+
public String getLabel() {
223+
return label;
224+
}
209225
}
210226
}

spring-shell-core/src/main/java/org/springframework/shell/command/CommandRegistration.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,14 @@ public interface OptionSpec {
200200
*/
201201
OptionSpec arity(OptionArity arity);
202202

203+
/**
204+
* Define a {@code label} for an option.
205+
*
206+
* @param label the label
207+
* @return option spec for chaining
208+
*/
209+
OptionSpec label(String label);
210+
203211
/**
204212
* Return a builder for chaining.
205213
*
@@ -519,6 +527,7 @@ static class DefaultOptionSpec implements OptionSpec {
519527
private Integer position;
520528
private Integer arityMin;
521529
private Integer arityMax;
530+
private String label;
522531

523532
DefaultOptionSpec(BaseBuilder builder) {
524533
this.builder = builder;
@@ -611,6 +620,12 @@ public OptionSpec arity(OptionArity arity) {
611620
return this;
612621
}
613622

623+
@Override
624+
public OptionSpec label(String label) {
625+
this.label = label;
626+
return this;
627+
}
628+
614629
@Override
615630
public Builder and() {
616631
return builder;
@@ -651,6 +666,10 @@ public Integer getArityMin() {
651666
public Integer getArityMax() {
652667
return arityMax;
653668
}
669+
670+
public String getLabel() {
671+
return label;
672+
}
654673
}
655674

656675
static class DefaultTargetSpec implements TargetSpec {
@@ -820,7 +839,8 @@ public Availability getAvailability() {
820839
public List<CommandOption> getOptions() {
821840
return optionSpecs.stream()
822841
.map(o -> CommandOption.of(o.getLongNames(), o.getShortNames(), o.getDescription(), o.getType(),
823-
o.isRequired(), o.getDefaultValue(), o.getPosition(), o.getArityMin(), o.getArityMax()))
842+
o.isRequired(), o.getDefaultValue(), o.getPosition(), o.getArityMin(), o.getArityMax(),
843+
o.getLabel()))
824844
.collect(Collectors.toList());
825845
}
826846

spring-shell-core/src/test/java/org/springframework/shell/command/CommandParserTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ public void testMapPositionalArgs2() {
327327
public void testBooleanWithDefault() {
328328
ResolvableType type = ResolvableType.forType(boolean.class);
329329
CommandOption option1 = CommandOption.of(new String[] { "arg1" }, new Character[0], "description", type, false,
330-
"true", null, null, null);
330+
"true", null, null, null, null);
331331

332332
List<CommandOption> options = Arrays.asList(option1);
333333
String[] args = new String[]{};
@@ -359,7 +359,7 @@ private static CommandOption longOption(String name, ResolvableType type, boolea
359359

360360
private static CommandOption longOption(String name, ResolvableType type, boolean required, Integer position, Integer arityMin, Integer arityMax) {
361361
return CommandOption.of(new String[] { name }, new Character[0], "desc", type, required, null, position,
362-
arityMin, arityMax);
362+
arityMin, arityMax, null);
363363
}
364364

365365
private static CommandOption shortOption(char name) {

spring-shell-core/src/test/java/org/springframework/shell/command/CommandRegistrationTests.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ public void testOptionWithType() {
195195
.shortNames('v')
196196
.type(boolean.class)
197197
.description("some arg1")
198+
.label("mylabel")
198199
.and()
199200
.withTarget()
200201
.function(function1)
@@ -205,6 +206,7 @@ public void testOptionWithType() {
205206
assertThat(registration.getOptions()).hasSize(1);
206207
assertThat(registration.getOptions().get(0).getShortNames()).containsExactly('v');
207208
assertThat(registration.getOptions().get(0).getType()).isEqualTo(ResolvableType.forType(boolean.class));
209+
assertThat(registration.getOptions().get(0).getLabel()).isEqualTo("mylabel");
208210
}
209211

210212
@Test
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.shell.samples.e2e;
17+
18+
import org.springframework.context.annotation.Bean;
19+
import org.springframework.shell.command.CommandRegistration;
20+
import org.springframework.shell.standard.ShellComponent;
21+
22+
/**
23+
* Commands used for e2e test.
24+
*
25+
* @author Janne Valkealahti
26+
*/
27+
@ShellComponent
28+
public class OptionTypeCommands extends BaseE2ECommands {
29+
30+
@Bean
31+
public CommandRegistration testOptionTypeRegistration() {
32+
return CommandRegistration.builder()
33+
.command(REG, "option-type")
34+
.group(GROUP)
35+
.withOption()
36+
.longNames("arg1")
37+
.and()
38+
.withOption()
39+
.longNames("arg2")
40+
.type(String.class)
41+
.and()
42+
.withOption()
43+
.longNames("arg3")
44+
.type(int.class)
45+
.and()
46+
.withOption()
47+
.longNames("arg4")
48+
.label("MYLABEL")
49+
.and()
50+
.withTarget()
51+
.consumer(ctx -> {})
52+
.and()
53+
.build();
54+
}
55+
56+
}

spring-shell-standard-commands/src/main/java/org/springframework/shell/standard/commands/CommandInfoModel.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.springframework.shell.command.CommandOption;
2323
import org.springframework.shell.command.CommandRegistration;
2424
import org.springframework.util.ClassUtils;
25+
import org.springframework.util.StringUtils;
2526

2627
/**
2728
* Model encapsulating info about {@code command}.
@@ -51,7 +52,7 @@ static CommandInfoModel of(String name, CommandRegistration registration) {
5152
List<CommandOption> options = registration.getOptions();
5253
List<CommandParameterInfoModel> parameters = options.stream()
5354
.map(o -> {
54-
String type = o.getType() == null ? "String" : ClassUtils.getShortName(o.getType().getRawClass());
55+
String type = commandOptionType(o);
5556
List<String> arguments = Stream.concat(
5657
Stream.of(o.getLongNames()).map(a -> "--" + a),
5758
Stream.of(o.getShortNames()).map(s -> "-" + s))
@@ -67,6 +68,15 @@ static CommandInfoModel of(String name, CommandRegistration registration) {
6768
return new CommandInfoModel(name, description, parameters);
6869
}
6970

71+
private static String commandOptionType(CommandOption o) {
72+
if (StringUtils.hasText(o.getLabel())) {
73+
return o.getLabel();
74+
}
75+
else {
76+
return o.getType() == null ? "String" : ClassUtils.getShortName(o.getType().getRawClass());
77+
}
78+
}
79+
7080
public String getName() {
7181
return name;
7282
}

0 commit comments

Comments
 (0)