Skip to content

Commit 2decf04

Browse files
committed
finished cli: added doc + set command + dynamic version discover
1 parent 0bb75b9 commit 2decf04

File tree

13 files changed

+324
-56
lines changed

13 files changed

+324
-56
lines changed

docs/asciidoc/getting-started.adoc

Lines changed: 134 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
== Getting Started
22

3-
[id="getting-started-java"]
3+
Jooby comes with couple of options for getting started: manual, maven archetype and command line tool.
4+
45
=== Java
56

67
1) Add the dependency:
@@ -97,25 +98,143 @@ Alternative you can specify all these parameters inline:
9798
mvn archetype:generate -B -DgroupId=mypackage -DartifactId=my-app -Dversion=1.0.0 -DarchetypeArtifactId=jooby-archetype -DarchetypeGroupId=io.jooby -DarchetypeVersion={joobyVersion}
9899
----
99100

100-
=== Code Snippets
101+
=== CLI
102+
103+
The command line tool provides a dynamic way of generating Jooby applications.
104+
105+
**Features**
106+
107+
- Maven or Gradle build
108+
- Java or Kotlin language
109+
- Script or MVC routes
110+
- Choose server: Jetty, Netty or Undertow
111+
- Uber/Fat jar or https://github.com/fizzed/stork[Stork native launcher]
112+
- Dockerfile
101113

102-
For simplicity and brevity we are going to skip the `runApp` function and extending `Jooby`.
103-
A code example will looks like:
114+
**Install**
115+
116+
- Download https://repo1.maven.org/maven2/io/jooby/jooby-cli/{joobyVersion}/jooby-cli-{joobyVersion}.zip[jooby-cli.zip]
117+
- Unzip `jooby-cli.zip` in your user home directory (or any other directory you prefer to)
118+
- Find the native launchers in the `bin` directory
119+
120+
[NOTE]
121+
====
122+
To simplify documentation we use `jooby` as command. Windows users must use `jooby.bat`
123+
====
104124

105-
.Snippet
106-
[source, java, role = "primary"]
125+
.Setting workspace:
126+
[source, bash]
107127
----
108-
{
109-
get("/", ctx -> "Snippet");
110-
}
128+
jooby set -w ~/Source
111129
----
112130

113-
.Kotlin
114-
[source, kotlin, role = "secondary"]
131+
All code will be placed inside the `~/Source` directory.
132+
133+
[TIP]
134+
====
135+
You might want to add the native launcher `bin/jooby` or `bin/jooby.bat` to system path variable.
136+
So its globally accessible from any location.
137+
====
138+
139+
Workspace directory is ready! Let's generate some code!! This time just run the `jooby` command.
140+
After prompt type `help create`:
141+
142+
.jooby
143+
[source, bash]
115144
----
116-
{
117-
get("/") { "Snippet" }
118-
}
145+
jooby> help create
146+
----
147+
148+
Output:
149+
150+
[source, bash]
151+
----
152+
jooby> help create
153+
Missing required parameter: <name>
154+
Usage: jooby create [-dgikms] [--server=<server>] <name>
155+
Creates a new application
156+
<name> Application name or coordinates (groupId:artifactId:
157+
version)
158+
-d, --docker Generates a Dockerfile
159+
-g, --gradle Generates a Gradle project
160+
-i Start interactive mode
161+
-k, --kotlin Generates a Kotlin application
162+
-m, --mvc Generates a MVC application
163+
-s, --stork Add Stork Maven plugin to build (Maven only)
164+
--server=<server> Choose one of the available servers: jetty, netty or
165+
undertow
166+
jooby>
167+
----
168+
169+
The `create` command generates a Jooby application. Some examples:
170+
171+
.Creates `myapp` as Java Maven project:
172+
[source, bash]
173+
----
174+
jooby> create myapp
175+
----
176+
177+
.Creates `myapp` as Kotlin Maven project:
178+
[source, bash]
179+
----
180+
jooby> create myapp -k
181+
----
182+
183+
.Creates `myapp` as Java Gradle project:
184+
[source, bash]
185+
----
186+
jooby> create myapp -g
187+
----
188+
189+
.Creates `myapp` as Kotlin Gradle project:
190+
[source, bash]
191+
----
192+
jooby> create myapp -gk
193+
----
194+
195+
Maven and Java are the default options but you can easily override those with `-g -k` or `-gk` (order doesn't matter).
196+
Along with the build and language the `create` command adds two test classes: `UnitTest` and `IntegrationTest`.
197+
198+
Passing the `-m` or `--mvc` generates a MVC application:
199+
200+
.Creates `myapp` as MVC application:
201+
[source, bash]
202+
----
203+
jooby> create myapp -m
204+
----
205+
206+
The `--server` option, allow you to choose between: (J)etty, (N)etty or (U)ndertow:
207+
208+
.Creates `myapp` as MVC application:
209+
[source, bash]
210+
----
211+
jooby> create myapp --server undertow
212+
----
213+
214+
Maven/Gradle configuration generates an `uber/fat` jar at package time. Maven builds supports
215+
generation of https://github.com/fizzed/stork[Stork launchers].
216+
217+
.Creates `myapp` and generates stork launchers:
218+
[source, bash]
219+
----
220+
jooby> create myapp --stork
221+
----
222+
223+
There is a `-d` or `--docker` option which generates a `Dockerfile`
224+
225+
.Creates `myapp` with docker:
226+
[source, bash]
227+
----
228+
jooby> create myapp --docker
229+
----
230+
231+
The default package in all these examples is set to `app`, to get fully control of groupId, package, version, etc... Use the interactive mode:
232+
233+
.Fully customize `myapp`:
234+
[source, bash]
235+
----
236+
jooby> create myapp -i
119237
----
120238

121-
The use of `runApp` will be included only when is strictly necessary.
239+
The jooby cli application is a small program that simplifies creation of project and provides options
240+
to fully customize your application.

docs/asciidoc/index.adoc

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,28 @@ fun main(args: Array<String>) {
206206

207207
More about MVC and JAX-RS support in the <<mvc-api, MVC API>> chapter.
208208

209-
include::support.adoc[]
209+
=== Code Snippets
210+
211+
For simplicity and brevity we are going to skip the `runApp` function and extending `Jooby`.
212+
A code example will looks like:
213+
214+
.Snippet
215+
[source, java, role = "primary"]
216+
----
217+
{
218+
get("/", ctx -> "Snippet");
219+
}
220+
----
221+
222+
.Kotlin
223+
[source, kotlin, role = "secondary"]
224+
----
225+
{
226+
get("/") { "Snippet" }
227+
}
228+
----
229+
230+
The use of `application class` or `runApp function` will be included when is strictly necessary.
210231

211232
include::getting-started.adoc[]
212233

docs/asciidoc/static-files.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ SPAs mode never generates a `NOT FOUND (404)` response, unresolved assets fallba
127127

128128
=== Options
129129

130-
The javadoc:AssetHandler[] automatically handle `E-Tag` and `Las-Modified` headers. You can turn
130+
The javadoc:AssetHandler[] automatically handles `E-Tag` and `Las-Modified` headers. You can turn
131131
control these headers programmatically:
132132

133133
.Asset handler options:

modules/jooby-cli/pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@
4545
<version>3.12.1</version>
4646
</dependency>
4747

48+
<!-- https://mvnrepository.com/artifact/org.json/json -->
49+
<dependency>
50+
<groupId>org.json</groupId>
51+
<artifactId>json</artifactId>
52+
<version>20190722</version>
53+
</dependency>
54+
4855
<dependency>
4956
<groupId>org.junit.jupiter</groupId>
5057
<artifactId>junit-jupiter-engine</artifactId>

modules/jooby-cli/src/main/java/io/jooby/cli/Cli.java

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,20 @@
1616
import org.jline.reader.impl.DefaultParser;
1717
import org.jline.terminal.Terminal;
1818
import org.jline.terminal.TerminalBuilder;
19+
import org.json.JSONArray;
20+
import org.json.JSONObject;
21+
import org.json.JSONTokener;
1922
import picocli.CommandLine;
2023

2124
import javax.annotation.Nonnull;
2225
import java.io.IOException;
26+
import java.io.InputStream;
27+
import java.net.URI;
28+
import java.net.URL;
29+
import java.net.URLConnection;
2330
import java.util.List;
2431
import java.util.Objects;
32+
import java.util.Optional;
2533
import java.util.stream.Collectors;
2634

2735
/**
@@ -46,14 +54,16 @@
4654
mixinStandardHelpOptions = true,
4755
version = "Print version information"
4856
)
49-
public class Cli extends Command {
57+
public class Cli extends Cmd {
58+
public static String version;
59+
5060
/** Command line specification. */
5161
private @CommandLine.Spec CommandLine.Model.CommandSpec spec;
5262

5363
/** Unmatched command line arguments. */
5464
private @CommandLine.Unmatched List<String> args;
5565

56-
@Override public void run(@Nonnull CommandContext ctx) {
66+
@Override public void run(@Nonnull Context ctx) {
5767
List<String> args = this.args.stream()
5868
.filter(Objects::nonNull)
5969
.map(String::trim)
@@ -64,7 +74,7 @@ public class Cli extends Command {
6474
if ("-h".equals(arg) || "--help".equals(arg)) {
6575
ctx.println(spec.commandLine().getUsageMessage());
6676
} else if ("-V".equalsIgnoreCase(arg) || "--version".equals(arg)) {
67-
ctx.println(VersionProvider.version());
77+
ctx.println(ctx.getVersion());
6878
} else {
6979
ctx.println("Unknown command or option(s): " + args.stream().collect(Collectors.joining(" ")));
7080
}
@@ -78,11 +88,13 @@ public class Cli extends Command {
7888
* @throws IOException If something goes wrong.
7989
*/
8090
public static void main(String[] args) throws IOException {
91+
version = checkVersion();
8192
// set up the completion
8293
Cli jooby = new Cli();
8394
CommandLine cmd = new CommandLine(jooby)
84-
.addSubcommand(new CreateApp())
85-
.addSubcommand(new Exit());
95+
.addSubcommand(new CreateCmd())
96+
.addSubcommand(new ExitCmd())
97+
.addSubcommand(new SetCmd());
8698

8799
Terminal terminal = TerminalBuilder.builder().build();
88100
LineReader reader = LineReaderBuilder.builder()
@@ -91,12 +103,12 @@ public static void main(String[] args) throws IOException {
91103
.parser(new DefaultParser())
92104
.build();
93105

94-
CommandContextImpl context = new CommandContextImpl(reader);
106+
CommandContextImpl context = new CommandContextImpl(reader, version);
95107
jooby.setContext(context);
96108
cmd.getSubcommands().values().stream()
97109
.map(CommandLine::getCommand)
98-
.filter(Command.class::isInstance)
99-
.map(Command.class::cast)
110+
.filter(Cmd.class::isInstance)
111+
.map(Cmd.class::cast)
100112
.forEach(command -> command.setContext(context));
101113

102114
if (args.length > 0) {
@@ -119,4 +131,25 @@ public static void main(String[] args) throws IOException {
119131
}
120132
}
121133
}
134+
135+
private static String checkVersion() {
136+
try {
137+
URL url = URI
138+
.create("http://search.maven.org/solrsearch/select?q=+g:io.jooby+a:jooby&start=0&rows=1")
139+
.toURL();
140+
URLConnection connection = url.openConnection();
141+
try(InputStream in = connection.getInputStream()) {
142+
JSONObject json = new JSONObject(new JSONTokener(in));
143+
JSONObject response = json.getJSONObject("response");
144+
JSONArray docs = response.getJSONArray("docs");
145+
JSONObject jooby = docs.getJSONObject(0);
146+
return jooby.getString("latestVersion");
147+
}
148+
} catch (Exception x) {
149+
return Optional.ofNullable(VersionProvider.class.getPackage())
150+
.map(Package::getImplementationVersion)
151+
.filter(Objects::nonNull)
152+
.orElse("2.0.5");
153+
}
154+
}
122155
}

modules/jooby-cli/src/main/java/io/jooby/cli/Command.java renamed to modules/jooby-cli/src/main/java/io/jooby/cli/Cmd.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
*
1313
* @since 2.0.5
1414
*/
15-
public abstract class Command implements Runnable {
16-
private CommandContext context;
15+
public abstract class Cmd implements Runnable {
16+
private Context context;
1717

1818
@Override public void run() {
1919
try {
@@ -29,14 +29,14 @@ public abstract class Command implements Runnable {
2929
* @param context Command context.
3030
* @throws Exception If something goes wrong.
3131
*/
32-
public abstract void run(@Nonnull CommandContext context) throws Exception;
32+
public abstract void run(@Nonnull Context context) throws Exception;
3333

3434
/**
3535
* Set command context.
3636
*
3737
* @param context Command context.
3838
*/
39-
public void setContext(@Nonnull CommandContext context) {
39+
public void setContext(@Nonnull Context context) {
4040
this.context = context;
4141
}
4242

modules/jooby-cli/src/main/java/io/jooby/cli/CommandContext.java renamed to modules/jooby-cli/src/main/java/io/jooby/cli/Context.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package io.jooby.cli;
77

88
import javax.annotation.Nonnull;
9+
import java.io.FileNotFoundException;
910
import java.io.IOException;
1011
import java.nio.file.Path;
1112
import java.nio.file.attribute.PosixFilePermission;
@@ -17,7 +18,7 @@
1718
*
1819
* @since 2.0.6
1920
*/
20-
public interface CommandContext {
21+
public interface Context {
2122
/**
2223
* Exit application.
2324
*
@@ -70,4 +71,25 @@ void copyResource(@Nonnull String source, @Nonnull Path dest,
7071
* @param message Message.
7172
*/
7273
void println(@Nonnull String message);
74+
75+
/**
76+
* Jooby version to use.
77+
*
78+
* @return Jooby version to use.
79+
*/
80+
@Nonnull String getVersion();
81+
82+
/**
83+
* Working directory (where the projects are created).
84+
*
85+
* @return Working directory (where the projects are created).
86+
*/
87+
@Nonnull Path getWorkspace();
88+
89+
/**
90+
* Set workspace/working directory.
91+
*
92+
* @param workspace Workspace/working directory.
93+
*/
94+
void setWorkspace(@Nonnull Path workspace) throws IOException;
7395
}

0 commit comments

Comments
 (0)