delegate) {
355 | this.delegateCallable = delegate;
356 | }
357 |
358 | public DelegatePicocliCommand(Runnable delegate) {
359 | this.delegateRunnable = delegate;
360 | }
361 |
362 | @Override
363 | public ExitStatus call() throws Exception {
364 | if (delegateCallable == null) {
365 | return super.call();
366 | }
367 | return delegateCallable.call();
368 | }
369 |
370 | @Override
371 | public void run() {
372 | delegateRunnable.run();
373 | }
374 | }
375 |
376 | @Command(name = "main")
377 | private static class HelpCommand {
378 | @Option(names = {"-h", "--help"}, help = true, description = "Prints this help message and exits")
379 | private boolean helpRequested;
380 |
381 | HelpCommand(boolean helpRequested) {
382 | this.helpRequested = helpRequested;
383 | }
384 | }
385 |
386 | @Command(name = "subcommand")
387 | private static class HelpSubCommand extends HelpCommand {
388 | HelpSubCommand(boolean helpRequested) {
389 | super(helpRequested);
390 | }
391 | }
392 |
393 | @Command(name = "nested-subcommand")
394 | private static class HelpNestedSubCommand extends HelpCommand {
395 | HelpNestedSubCommand(boolean helpRequested) {
396 | super(helpRequested);
397 | }
398 | }
399 |
400 | @Command
401 | private static class EmptyCommand {}
402 | }
403 |
--------------------------------------------------------------------------------
/picocli-spring-boot-sample/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.kakawait
8 | picocli-spring-boot-sample
9 | 0.2.0
10 |
11 |
12 | UTF-8
13 | UTF-8
14 |
15 | 1.8
16 | 1.8
17 | 1.8
18 | 22.0
19 |
20 |
21 |
22 | org.springframework.boot
23 | spring-boot-starter-parent
24 | 1.5.4.RELEASE
25 |
26 |
27 |
28 |
29 |
30 | org.springframework.boot
31 | spring-boot-starter-web
32 |
33 |
34 | org.springframework.boot
35 | spring-boot-starter-jdbc
36 |
37 |
38 | org.springframework.boot
39 | spring-boot-starter-actuator
40 |
41 |
42 | com.kakawait
43 | picocli-spring-boot-starter
44 | ${project.version}
45 |
46 |
47 | com.google.guava
48 | guava
49 | ${guava.version}
50 |
51 |
52 |
53 |
54 | org.flywaydb
55 | flyway-core
56 |
57 |
58 |
59 |
60 | com.h2database
61 | h2
62 | runtime
63 |
64 |
65 |
66 |
67 |
68 |
69 | org.springframework.boot
70 | spring-boot-maven-plugin
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/picocli-spring-boot-sample/src/main/java/com/kakawait/PicocliSpringBootSampleApplication.java:
--------------------------------------------------------------------------------
1 | package com.kakawait;
2 |
3 | import com.google.common.base.CaseFormat;
4 | import com.kakawait.spring.boot.picocli.autoconfigure.ExitStatus;
5 | import com.kakawait.spring.boot.picocli.autoconfigure.HelpAwarePicocliCommand;
6 | import com.kakawait.spring.boot.picocli.autoconfigure.PicocliConfigurerAdapter;
7 | import org.flywaydb.core.Flyway;
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 | import org.springframework.boot.SpringApplication;
11 | import org.springframework.boot.actuate.health.HealthIndicator;
12 | import org.springframework.boot.autoconfigure.SpringBootApplication;
13 | import org.springframework.boot.autoconfigure.flyway.FlywayMigrationStrategy;
14 | import org.springframework.context.annotation.Bean;
15 | import org.springframework.context.annotation.Configuration;
16 | import org.springframework.stereotype.Component;
17 | import org.springframework.util.StringUtils;
18 | import picocli.CommandLine;
19 | import picocli.CommandLine.Help.Ansi;
20 | import picocli.CommandLine.Option;
21 | import picocli.CommandLine.Parameters;
22 |
23 | import java.util.Map;
24 | import java.util.regex.Matcher;
25 | import java.util.regex.Pattern;
26 |
27 | import static picocli.CommandLine.Command;
28 |
29 | /**
30 | * Picocli spring boot starter sample
31 | *
32 | * This sample will create following CLI
33 | *
34 | *
35 | * {@code
36 | * Usage: [-vh]
37 | * -v, --version display version info
38 | * -h, --help Prints this help message and exits
39 | * Commands:
40 | * flyway [-h, --help]
41 | * migrate
42 | * repair
43 | * greeting [-h, --help] [NAME]
44 | * health [-h, --help]
45 | * db
46 | * disk-space
47 | * }
48 | *
49 | * Thus running following commands should output following:
50 | *
51 | * {@code
52 | * $> java -jar .jar -v
53 | * 0.1.0
54 | *
55 | * $> java -jar .jar -h
56 | * Usage: [-vh]
57 | * -v, --version display version info
58 | * -h, --help Prints this help message and exits
59 | * Commands:
60 | * flyway
61 | * greeting
62 | * health
63 | *
64 | * $> java -jar .jar flyway
65 | * Usage: flyway [-h]
66 | * -h, --help Prints this help message and exits
67 | * Commands:
68 | * migrate
69 | * repair
70 | *
71 | * $> java -jar .jar flyway migrate
72 | * 2017-07-06 11:21:14.560 INFO 77637 --- [main] o.f.core.internal.util.VersionPrinter : Flyway 3.2.1 by Boxfuse
73 | * 2017-07-06 11:21:14.567 INFO 77637 --- [main] o.f.c.i.dbsupport.DbSupportFactory : Database: jdbc:h2:mem:testdb (H2 1.4)
74 | * 2017-07-06 11:21:14.601 INFO 77637 --- [main] o.f.core.internal.command.DbValidate : Validated 2 migrations (execution time 00:00.013s)
75 | * 2017-07-06 11:21:14.621 INFO 77637 --- [main] o.f.c.i.metadatatable.MetaDataTableImpl : Creating Metadata table: "PUBLIC"."schema_version"
76 | * 2017-07-06 11:21:14.638 INFO 77637 --- [main] o.f.core.internal.command.DbMigrate : Current version of schema "PUBLIC": << Empty Schema >>
77 | * 2017-07-06 11:21:14.638 INFO 77637 --- [main] o.f.core.internal.command.DbMigrate : Migrating schema "PUBLIC" to version 1 - init
78 | * 2017-07-06 11:21:14.666 INFO 77637 --- [main] o.f.core.internal.command.DbMigrate : Migrating schema "PUBLIC" to version 2 - add
79 | * 2017-07-06 11:21:14.672 INFO 77637 --- [main] o.f.core.internal.command.DbMigrate : Successfully applied 2 migrations to schema "PUBLIC" (execution time 00:00.053s).
80 | *
81 | * $> java -jar .jar health disk-space
82 | * UP {total=420143575040, free=41032192000, threshold=10485760}
83 | *
84 | * $> java -jar .jar health db
85 | * UP {database=H2, hello=1}
86 | * }
87 | *
88 | * @author Thibaud Leprêtre
89 | */
90 | @SpringBootApplication
91 | public class PicocliSpringBootSampleApplication {
92 |
93 | public static void main(String[] args) {
94 | SpringApplication.run(PicocliSpringBootSampleApplication.class, args);
95 | }
96 |
97 | /**
98 | * Disable flyway automatic migration on startup.
99 | * I will be piloted using CLI
100 | * @return No operation flyway migration strategy
101 | */
102 | @Bean
103 | FlywayMigrationStrategy flywayMigrationStrategy() {
104 | return flyway -> {};
105 | }
106 |
107 | @Configuration
108 | static class PicocliConfiguration extends PicocliConfigurerAdapter {
109 |
110 | private static final Logger logger = LoggerFactory.getLogger(PicocliConfiguration.class);
111 |
112 | private static final Pattern HEALTH_PATTERN = Pattern.compile("^(\\w+?)HealthIndicator$");
113 |
114 | private final Map healthIndicators;
115 |
116 | public PicocliConfiguration(Map healthIndicators) {
117 | this.healthIndicators = healthIndicators;
118 | }
119 |
120 | @Override
121 | public void configure(CommandLine cli) {
122 | CommandLine healthCli = new CommandLine(new HelpAwareContainerPicocliCommand() {});
123 | for (Map.Entry entry : healthIndicators.entrySet()) {
124 | Matcher matcher = HEALTH_PATTERN.matcher(entry.getKey());
125 | if (matcher.matches()) {
126 | String name = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, matcher.group(1));
127 | healthCli.addSubcommand(name, new PrintCommand(entry.getValue().health()));
128 | } else {
129 | logger.warn("Unable to determine a correct name for given indicator: \"{}\", skip it!",
130 | entry.getKey());
131 | }
132 | }
133 | cli.addSubcommand("health", healthCli);
134 | }
135 |
136 | @Command
137 | private static class PrintCommand implements Runnable {
138 | private final Object object;
139 |
140 | PrintCommand(Object object) {
141 | this.object = object;
142 | }
143 |
144 | @Override
145 | public void run() {
146 | System.out.println(object);
147 | }
148 | }
149 | }
150 |
151 | @Component
152 | @Command
153 | static class MainCommand extends HelpAwarePicocliCommand {
154 | @Option(names = {"-v", "--version"}, description = "display version info")
155 | boolean versionRequested;
156 |
157 | @Override
158 | public ExitStatus call() {
159 | if (versionRequested) {
160 | System.out.println("0.1.0");
161 | return ExitStatus.TERMINATION;
162 | }
163 | return ExitStatus.OK;
164 | }
165 | }
166 |
167 | @Component
168 | @Command(name = "greeting")
169 | static class GreetingCommand extends HelpAwarePicocliCommand {
170 |
171 | @Parameters(paramLabel = "NAME", description = "name", arity = "0..1")
172 | String name;
173 |
174 | @Override
175 | public void run() {
176 | if (StringUtils.hasText(name)) {
177 | System.out.println("Hello " + name + "!");
178 | } else {
179 | System.out.println("Hello world!");
180 | }
181 | }
182 | }
183 |
184 | @Component
185 | @Command(name = "flyway")
186 | static class FlywayCommand extends HelpAwareContainerPicocliCommand {
187 |
188 | @Component
189 | @Command(name = "migrate")
190 | static class MigrateCommand implements Runnable {
191 |
192 | private final Flyway flyway;
193 |
194 | public MigrateCommand(Flyway flyway) {
195 | this.flyway = flyway;
196 | }
197 |
198 | @Override
199 | public void run() {
200 | flyway.migrate();
201 | }
202 | }
203 |
204 | @Component
205 | @Command(name = "repair")
206 | static class RepairCommand implements Runnable {
207 | private final Flyway flyway;
208 |
209 | public RepairCommand(Flyway flyway) {
210 | this.flyway = flyway;
211 | }
212 |
213 | @Override
214 | public void run() {
215 | flyway.repair();
216 | }
217 | }
218 | }
219 |
220 | @Command
221 | private static abstract class HelpAwareContainerPicocliCommand extends HelpAwarePicocliCommand {
222 | @Override
223 | public ExitStatus call() {
224 | if (getParsedCommands().get(getParsedCommands().size() - 1).getCommand().equals(this)) {
225 | getContext().usage(System.out, Ansi.AUTO);
226 | return ExitStatus.TERMINATION;
227 | }
228 | return ExitStatus.OK;
229 | }
230 | }
231 |
232 | }
233 |
--------------------------------------------------------------------------------
/picocli-spring-boot-sample/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | main:
3 | web-environment: false
4 | logging:
5 | level:
6 | ROOT: off
7 | org.flywaydb: info
8 |
--------------------------------------------------------------------------------
/picocli-spring-boot-sample/src/main/resources/db/migration/V1__init.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE person (
2 | id BIGINT AUTO_INCREMENT,
3 | first_name VARCHAR(255) NOT NULL,
4 | last_name VARCHAR(255) NOT NULL,
5 | PRIMARY KEY(id)
6 | );
7 |
8 | insert into person (first_name, last_name) values ('Thibaud', 'Lepretre');
9 |
--------------------------------------------------------------------------------
/picocli-spring-boot-sample/src/main/resources/db/migration/V2__add.sql:
--------------------------------------------------------------------------------
1 | insert into person (first_name, last_name) values ('Remko', 'Popma');
2 |
--------------------------------------------------------------------------------
/picocli-spring-boot-starter/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 | com.kakawait
7 | picocli-spring-boot-starter
8 | 0.2.0
9 | jar
10 |
11 | Picocli spring boot starter
12 | Spring boot starter for Picocli command line tools. Let you easily write CLI!
13 | https://github.com/kakawait/picocli-spring-boot-starter
14 |
15 |
16 |
17 | MIT License
18 | http://www.opensource.org/licenses/mit-license.php
19 | repo
20 |
21 |
22 |
23 |
24 |
25 | Thibaud Leprêtre
26 | thibaud.lepretre@gmail.com
27 |
28 |
29 |
30 |
31 | https://github.com/kakawait/picocli-spring-boot-starter
32 | scm:git:git@github.com:kakawait/picocli-spring-boot-starter.git
33 | scm:git:git@github.com:kakawait/picocli-spring-boot-starter.git
34 |
35 |
36 |
37 | UTF-8
38 | UTF-8
39 |
40 | 1.8
41 | 1.8
42 | 1.8
43 |
44 | 3.0.1
45 | 2.10.4
46 | 1.6
47 | 1.6.8
48 |
49 |
50 |
51 |
52 |
53 | org.springframework.boot
54 | spring-boot-dependencies
55 | 1.5.4.RELEASE
56 | pom
57 | import
58 |
59 |
60 |
61 |
62 |
63 |
64 | org.springframework.boot
65 | spring-boot-starter
66 |
67 |
68 | com.kakawait
69 | picocli-spring-boot-autoconfigure
70 | ${project.version}
71 |
72 |
73 |
74 |
75 |
76 | oss.sonatype.org
77 | Sonatype OSS Staging
78 | https://oss.sonatype.org/service/local/staging/deploy/maven2
79 | default
80 |
81 |
82 | oss.sonatype.org
83 | Sonatype OSS Snapshots
84 | https://oss.sonatype.org/content/repositories/snapshots
85 | default
86 |
87 |
88 |
89 |
90 |
91 | release
92 |
93 | gpg2
94 |
95 |
96 |
97 |
98 | org.apache.maven.plugins
99 | maven-source-plugin
100 | ${maven-source-plugin.version}
101 |
102 |
103 | attach-sources
104 | verify
105 |
106 | jar-no-fork
107 |
108 |
109 |
110 |
111 |
112 | org.apache.maven.plugins
113 | maven-javadoc-plugin
114 | ${maven-javadoc-plugin.version}
115 |
116 |
117 | attach-javadocs
118 | verify
119 |
120 | jar
121 |
122 |
123 |
124 |
125 |
126 | org.apache.maven.plugins
127 | maven-gpg-plugin
128 | ${maven-gpg-plugin.version}
129 |
130 |
131 | sign-artifacts
132 | verify
133 |
134 | sign
135 |
136 |
137 |
138 |
139 |
140 | org.sonatype.plugins
141 | nexus-staging-maven-plugin
142 | ${nexus-staging-maven-plugin.version}
143 | true
144 |
145 | oss.sonatype.org
146 | https://oss.sonatype.org/
147 | true
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
--------------------------------------------------------------------------------
/picocli-spring-boot-starter/src/main/resources/META-INF/spring.provides:
--------------------------------------------------------------------------------
1 | provides: picocli
2 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.kakawait
8 | picocli-spring-boot-starter-parent
9 | pom
10 | 0.2.0
11 |
12 | Picocli spring boot starter parent
13 | Spring boot starter for Picocli command line parser that will simplify your CommandLineRunner
14 | https://github.com/kakawait/picocli-spring-boot-starter
15 |
16 |
17 |
18 | MIT License
19 | http://www.opensource.org/licenses/mit-license.php
20 | repo
21 |
22 |
23 |
24 |
25 |
26 | Thibaud Leprêtre
27 | thibaud.lepretre@gmail.com
28 |
29 |
30 |
31 |
32 | https://github.com/kakawait/picocli-spring-boot-starter
33 | scm:git:git@github.com:kakawait/picocli-spring-boot-starter.git
34 | scm:git:git@github.com:kakawait/picocli-spring-boot-starter.git
35 |
36 |
37 |
38 | true
39 |
40 |
41 |
42 | picocli-spring-boot-starter
43 | picocli-spring-boot-autoconfigure
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------