Skip to content

Commit 51f8c1d

Browse files
piotrooofmbenhassine
authored andcommitted
Introduce new command builder DSL
Signed-off-by: Piotr Olaszewski <[email protected]>
1 parent b59f9ac commit 51f8c1d

File tree

3 files changed

+130
-7
lines changed

3 files changed

+130
-7
lines changed

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

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,19 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
1716
package org.springframework.shell.core.command;
1817

18+
import java.util.ArrayList;
19+
import java.util.Arrays;
1920
import java.util.Collections;
2021
import java.util.List;
22+
import java.util.function.Consumer;
23+
import java.util.function.Function;
24+
25+
import org.springframework.shell.core.commands.AbstractCommand;
26+
import org.springframework.shell.core.commands.adapter.ConsumerCommandAdapter;
27+
import org.springframework.shell.core.commands.adapter.FunctionCommandAdapter;
28+
import org.springframework.util.Assert;
2129

2230
/**
2331
* @author Eric Bottard
@@ -74,4 +82,86 @@ default List<String> getAliases() {
7482
*/
7583
ExitStatus execute(CommandContext commandContext) throws Exception;
7684

85+
/**
86+
* Creates and returns a new instance of a {@code Builder} for defining and
87+
* constructing commands.
88+
* <p>
89+
* The builder allows customization of command properties such as name, description,
90+
* group, help text, aliases, and execution logic.
91+
* @return a new {@code Builder} instance for configuring and creating commands
92+
*/
93+
static Builder builder() {
94+
return new Builder();
95+
}
96+
97+
/**
98+
* Builder for creating command.
99+
*/
100+
final class Builder {
101+
102+
private String name = "";
103+
104+
private String description = "";
105+
106+
private String group = "";
107+
108+
private String help = "";
109+
110+
private List<String> aliases = new ArrayList<>();
111+
112+
public Builder name(String name) {
113+
this.name = name;
114+
return this;
115+
}
116+
117+
public Builder description(String description) {
118+
this.description = description;
119+
return this;
120+
}
121+
122+
public Builder help(String help) {
123+
this.help = help;
124+
return this;
125+
}
126+
127+
public Builder group(String group) {
128+
this.group = group;
129+
return this;
130+
}
131+
132+
public Builder aliases(String... aliases) {
133+
this.aliases = Arrays.asList(aliases);
134+
return this;
135+
}
136+
137+
public AbstractCommand execute(Consumer<CommandContext> commandExecutor) {
138+
Assert.hasText(name, "'name' must be specified");
139+
140+
ConsumerCommandAdapter command = new ConsumerCommandAdapter(name, description, group, help,
141+
commandExecutor);
142+
143+
initAliases(command);
144+
145+
return command;
146+
}
147+
148+
public AbstractCommand execute(Function<CommandContext, String> commandExecutor) {
149+
Assert.hasText(name, "'name' must be specified");
150+
151+
FunctionCommandAdapter command = new FunctionCommandAdapter(name, description, group, help,
152+
commandExecutor);
153+
154+
initAliases(command);
155+
156+
return command;
157+
}
158+
159+
private void initAliases(AbstractCommand command) {
160+
if (aliases != null) {
161+
command.setAliases(aliases);
162+
}
163+
}
164+
165+
}
166+
77167
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@NullMarked
2+
package org.springframework.shell.core.commands.adapter;
3+
4+
import org.jspecify.annotations.NullMarked;

spring-shell-samples/spring-shell-sample-hello-world/src/main/java/org/springframework/shell/samples/helloworld/SpringShellApplication.java

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,18 @@
33
import java.io.PrintWriter;
44
import java.util.List;
55

6+
import org.jline.utils.AttributedStringBuilder;
7+
68
import org.springframework.context.ApplicationContext;
79
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
810
import org.springframework.context.annotation.Bean;
911
import org.springframework.shell.core.ShellRunner;
1012
import org.springframework.shell.core.command.CommandContext;
11-
import org.springframework.shell.core.command.annotation.Argument;
12-
import org.springframework.shell.core.command.annotation.Arguments;
13-
import org.springframework.shell.core.command.annotation.Command;
14-
import org.springframework.shell.core.command.annotation.EnableCommand;
15-
import org.springframework.shell.core.command.annotation.Option;
13+
import org.springframework.shell.core.command.annotation.*;
14+
import org.springframework.shell.core.commands.AbstractCommand;
15+
16+
import static org.jline.utils.AttributedStyle.BOLD;
17+
import static org.jline.utils.AttributedStyle.GREEN;
1618

1719
@EnableCommand(SpringShellApplication.class)
1820
public class SpringShellApplication {
@@ -44,10 +46,37 @@ public void sayHeyToEveryone(@Arguments List<String> names, @Option(shortName =
4446
public void sayYo(CommandContext commandContext) {
4547
try (PrintWriter outputWriter = commandContext.outputWriter()) {
4648
outputWriter.println("Yo there! what's up?");
47-
outputWriter.flush();
4849
}
4950
}
5051

52+
@Bean
53+
public AbstractCommand sayGoodMorning() {
54+
return org.springframework.shell.core.command.Command.builder()
55+
.name("good-morning")
56+
.description("Say good morning")
57+
.group("greetings")
58+
.help("A command that greets the user with 'Good morning!'")
59+
.execute(commandContext -> {
60+
String ansiString = new AttributedStringBuilder().append("Good morning!", BOLD.foreground(GREEN))
61+
.append("!")
62+
.toAnsi();
63+
try (PrintWriter outputWriter = commandContext.outputWriter()) {
64+
outputWriter.println(ansiString);
65+
outputWriter.flush();
66+
}
67+
});
68+
}
69+
70+
@Bean
71+
public AbstractCommand sayGoodDay() {
72+
return org.springframework.shell.core.command.Command.builder()
73+
.name("good-day")
74+
.description("Say good day")
75+
.group("greetings")
76+
.help("A command that greets the user with 'Good day!'")
77+
.execute(commandContext -> "Good day!");
78+
}
79+
5180
@Bean
5281
public HelloCommand sayHello() {
5382
return new HelloCommand();

0 commit comments

Comments
 (0)