Replies: 4 comments 9 replies
-
@fmbenhassine yes, after your clarification, I totally agree. You're right.
Indeed, that's awkward... I was confused the first time I started using Spring Shell — why can I set the following set of parameters: spring.shell.interactive.enabled=true
spring.shell.noninteractive.enabled=true
spring.shell.script.enabled=trueThere should by only one runner at a time. The logic behind this works fine, but it's also reflected in the properties. For Spring Boot, we should introduce something like this: spring.shell.mode.type=interactive|noninteractive|script|custom(?)
spring.shell.mode.custom-runner=SomeClass.class # <- I'm not sure it's a good approach?That configuration would allow us to select only one runner, without any precedence logic as it is right now. And that should be the very first step. After that, we can start considering how to discover commands (or maybe even redesign the approach). |
Beta Was this translation helpful? Give feedback.
-
|
@fmbenhassine the second thing is how we should define and look up commands. New stereotypeI’m considering creating a @Component
public @interface Cli {}Analogy: @RestController
class SomeRestController {}Spring Shell Equivalent: @Cli
class SomeCli {}Class customizationsIf you want to customize CLI classes — for example, set them as parent commands, add aliases, or assign them to groups — you can use the Analogy: @RestController
@RequestMapping("/api")
class SomeRestController {}Spring Shell Equivalent: @Cli
@Command("parent")
class SomeCli {}@Cli
@Command("root", "parent")
class SomeCli {}@Cli
@Command("root parent")
class SomeCli {}Registering commandsTo register commands, we use the Analogy: @RestController
@RequestMapping("/api")
class SomeRestController {
@Get("/users")
List<User> getUsers() {}
}Spring Shell Equivalent: @Cli
@Command("parent")
class SomeCli {
@Command("child")
String child() {
return "this is child";
}
}Corner cases1. Only a single command in a
|
Beta Was this translation helpful? Give feedback.
-
|
Thank you for all these ideas! There is a lot going on here, so I will try to cover all your input. Regarding command registration: @Cli
@Command("parent")
class SomeCli {
@Command("child")
String child() {
return "this is child";
}
}This was the case before with I don't think we need a new class level annotation to mark a class as a source of command definitions, we already have the @Configuration
public class MyShellApplication {
@Bean
public Command hello() {
return new MyHelloCommand();
}
}That's similar to a batch app like: @Configuration
public class MyBatchApplication {
@Bean
public Job job() {
return new MyBatchJob();
}
}But unfortunately, that would require a redesign of the current Command interface to define options, aliases, business logic, etc and make it consistent with its annotation counterpart, So I guess the middle ground is to have the same programming model with a simpler approach to command registration/discovery by the framework: Without Spring BootNon boot users can enable command scanning with @EnableCommand(SpringShellApplication.class)
public class SpringShellApplication {
public static void main(String[] args) throws Exception {
ApplicationContext context = new AnnotationConfigApplicationContext(SpringShellApplication.class);
InteractiveShellRunner shellRunner = context.getBean(InteractiveShellRunner.class); // or another runner
shellRunner.run(args);
}
@Command
public String hello(@Option(defaultValue = "World") String name) {
return "Hello " + name + "!";
}
}More details in #1207 With Spring BootThe added value of Boot here would be to load the context and discover/register commands (same as @SpringBootApplication
public class SpringShellApplication {
public static void main(String[] args) {
SpringApplication.run(SpringShellApplication.class, args);
}
@Command
public String hello(@Option(defaultValue = "World") String name) {
return "Hello " + name + "!";
}
}More details in #1206 |
Beta Was this translation helpful? Give feedback.
-
|
Regarding the shell runner: First, I was also confused with all these properties and their precedence and I agree there should be only one runner active at a time. Probably a simpler way to configure this is to specify which runner to use: which would default to the All in all, I am just trying to keep things as simple as possible. What do you think? |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
@fmbenhassine said here:
Beta Was this translation helpful? Give feedback.
All reactions