Skip to content

Commit 8d1aa76

Browse files
committed
Work on the gradle/groovy quickstart, and infrastructure to test the quickstart snippets.
1 parent bd758f8 commit 8d1aa76

17 files changed

+154
-120
lines changed

ratpack-core/src/main/java/ratpack/func/NoArgAction.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,15 @@ static NoArgAction throwException(final Throwable throwable) {
4747
};
4848
}
4949

50+
/**
51+
* Converts this action to a runnable.
52+
* <p>
53+
* Any thrown exceptions will be {@link Exceptions#uncheck(NoArgAction) unchecked}.
54+
*
55+
* @return a runnable
56+
*/
57+
default Runnable toRunnable() {
58+
return () -> Exceptions.uncheck(this);
59+
}
60+
5061
}

ratpack-groovy/src/main/java/ratpack/groovy/internal/FullRatpackDslBacking.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import groovy.lang.Closure;
2020
import ratpack.groovy.Groovy;
2121

22-
class FullRatpackDslBacking implements Groovy.Ratpack {
22+
public class FullRatpackDslBacking implements Groovy.Ratpack {
2323

2424
Closure<?> bindingsConfigurer;
2525
Closure<?> handlersConfigurer;
@@ -37,7 +37,7 @@ public void serverConfig(Closure<?> configConfigurer) {
3737
this.serverConfigConfigurer = configConfigurer;
3838
}
3939

40-
RatpackDslClosures getClosures() {
40+
public RatpackDslClosures getClosures() {
4141
return new RatpackDslClosures(serverConfigConfigurer, handlersConfigurer, bindingsConfigurer);
4242
}
4343

ratpack-groovy/src/main/java/ratpack/groovy/internal/RatpackScriptBacking.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,6 @@ public static void withBacking(Action<Closure<?>> backing, Runnable runnable) {
5353
}
5454
}
5555

56-
public static Action<Closure<?>> swapBacking(Action<Closure<?>> backing) {
57-
LOCK_HOLDER.get().lock();
58-
try {
59-
Action<Closure<?>> previousBacking = BACKING_HOLDER.get();
60-
BACKING_HOLDER.set(backing);
61-
return previousBacking;
62-
} finally {
63-
LOCK_HOLDER.get().unlock();
64-
}
65-
}
66-
6756
public static void execute(Closure<?> closure) throws Exception {
6857
LOCK_HOLDER.get().lock();
6958
try {

ratpack-manual/src/content/chapters/02-quick-start.md

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ The Ratpack project provides two Gradle plugins:
1515
1. [io.ratpack.ratpack-java](http://plugins.gradle.org/plugin/io.ratpack.ratpack-java) - for Ratpack applications implemented in Java
1616
2. [io.ratpack.ratpack-groovy](http://plugins.gradle.org/plugin/io.ratpack.ratpack-groovy) - for Ratpack applications implemented in [Groovy](http://groovy-lang.org)
1717

18+
> For a more detailed explanation of the Gradle build support, please see the [dedicated chapter](gradle.html).
19+
1820
### Using the Gradle Java plugin
1921

2022
Create a `build.gradle` file with the following contents:
@@ -45,7 +47,7 @@ mainClassName = "my.app.Main"
4547

4648
Create the file `src/main/java/my/app/Main.java`, with the following content:
4749

48-
```language-java main
50+
```language-java hello-world
4951
package my.app;
5052
5153
import ratpack.server.RatpackServer;
@@ -55,7 +57,7 @@ public class Main {
5557
RatpackServer.start(server -> server
5658
.handlers(chain -> chain
5759
.get(ctx -> ctx.render("Hello World!"))
58-
.get(":name", ctx -> ctx.render("Hello " + ctx.getPathTokens().get("name")))
60+
.get(":name", ctx -> ctx.render("Hello " + ctx.getPathTokens().get("name") + "!"))
5961
)
6062
);
6163
}
@@ -65,7 +67,8 @@ public class Main {
6567
You can now start the application either by executing the `run` task with Gradle (i.e. `gradle run` on the command line),
6668
or by importing the project into your IDE and executing the `my.app.Main` class.
6769

68-
For further information on using Ratpack with Gradle, please the [Gradle chapter](gradle.html).
70+
The [`handlers()` method](api/ratpack/server/RatpackServerSpec.html#handlers-ratpack.func.Action-) takes a function that receives a [`Chain`](api/ratpack/handling/Chain.html) object.
71+
The “Handler Chain API” is used to build the response handling strategy.
6972

7073
### Using the Gradle Groovy plugin
7174

@@ -93,30 +96,33 @@ dependencies {
9396
}
9497
```
9598

96-
Create directories `src/ratpack` and `src/main/groovy`.
97-
98-
If desired, run `gradle idea` to generate project files for IntelliJ and open the project.
99-
100-
Create a `src/ratpack/ratpack.groovy` file with the following contents:
99+
Create the file `src/ratpack/ratpack.groovy`, with the following content:
101100

102-
```language-groovy
101+
```language-groovy hello-world
103102
import static ratpack.groovy.Groovy.ratpack
104103
105104
ratpack {
106105
handlers {
107-
get("foo") {
108-
render "from the foo handler"
106+
get {
107+
render "Hello World!"
109108
}
110-
get("bar") {
111-
render "from the bar handler"
109+
get(":name") {
110+
render "Hello $pathTokens.name!"
112111
}
113112
}
114113
}
115114
```
116115

117-
Run the project by running `gradle run`, or create a distribution archive by running `gradle distZip`.
116+
You can now start the application either by executing the `run` task with Gradle (i.e. `gradle run` on the command line),
117+
or by importing the project into your IDE and executing the [`ratpack.groovy.GroovyRatpackMain`](api/ratpack/groovy/GroovyRatpackMain.html) class.
118+
119+
The [`handlers()` method](api/ratpack/groovy/Groovy.Ratpack.html#handlers-groovy.lang.Closure-) takes a closure that delegates to a [`GroovyChain`](api/ratpack/groovy/handling/GroovyChain.html) object.
120+
The “Groovy Handler Chain DSL” is used to build the response handling strategy.
121+
122+
Changes to the `ratpack.groovy` file are live during development.
123+
You can edit the file, and the changes will take effect on the next request.
118124

119-
For further information on using Ratpack with Gradle and Groovy, please the [Gradle](gradle.html) and [Groovy](groovy.html) chapters.
125+
For further information on using Ratpack with Groovy, please the [Groovy](groovy.html) chapter.
120126

121127
## Using Lazybones project templates
122128

ratpack-manual/src/test/groovy/ratpack/manual/JavadocCodeSnippetTests.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class JavadocCodeSnippetTests extends CodeSnippetTestCase {
3030
"java-chain-dsl" : new JavaChainDslFixture(),
3131
"groovy-chain-dsl" : new GroovyChainDslFixture(),
3232
"groovy-ratpack-dsl": new GroovyRatpackDslFixture(),
33-
"java" : new JavaExampleClassFixture(),
33+
"java" : new JavaClassFixture(),
3434
]
3535

3636
@Override

ratpack-manual/src/test/groovy/ratpack/manual/ManualCodeSnippetTests.groovy

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,40 @@
1717
package ratpack.manual
1818

1919
import com.google.common.base.StandardSystemProperty
20+
import ratpack.func.NoArgAction
21+
import ratpack.groovy.Groovy
22+
import ratpack.groovy.internal.FullRatpackDslBacking
23+
import ratpack.groovy.internal.RatpackScriptBacking
2024
import ratpack.manual.snippets.CodeSnippetTestCase
2125
import ratpack.manual.snippets.CodeSnippetTests
26+
import ratpack.manual.snippets.executer.GroovySnippetExecuter
27+
import ratpack.manual.snippets.executer.JavaSnippetExecuter
2228
import ratpack.manual.snippets.extractor.ManualSnippetExtractor
2329
import ratpack.manual.snippets.fixture.*
30+
import ratpack.test.embed.EmbeddedApp
2431

2532
class ManualCodeSnippetTests extends CodeSnippetTestCase {
2633

34+
static delegate = new GroovyRatpackDslFixture()
35+
2736
public static final LinkedHashMap<String, SnippetFixture> FIXTURES = [
2837
"language-groovy groovy-chain-dsl": new GroovyChainDslFixture(),
2938
"language-groovy groovy-ratpack" : new GroovyRatpackDslFixture(),
3039
"language-groovy groovy-handlers" : new GroovyHandlersFixture(),
3140
"language-groovy gradle" : new GradleFixture(),
3241
"language-groovy tested" : new GroovyScriptFixture(),
33-
"language-java" : new JavaExampleClassFixture(),
34-
"language-java main" : new JavaMainClassFixture()
42+
"language-java" : new JavaClassFixture(),
43+
"language-java hello-world" : new HelloWorldAppSnippetFixture(new JavaSnippetExecuter()),
44+
"language-groovy hello-world" : new HelloWorldAppSnippetFixture(new GroovySnippetExecuter(true)) {
45+
@Override
46+
void around(NoArgAction action) throws Exception {
47+
RatpackScriptBacking.withBacking({
48+
def backing = new FullRatpackDslBacking()
49+
backing.with(it)
50+
EmbeddedApp.fromHandlers(Groovy.chain(backing.getClosures().handlers))
51+
}, action.toRunnable())
52+
}
53+
}
3554
]
3655

3756
@Override

ratpack-manual/src/test/groovy/ratpack/manual/snippets/executer/GroovySnippetExecuter.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public GroovySnippetExecuter(boolean compileStatic) {
4444
}
4545

4646
@Override
47-
public void execute(TestCodeSnippet snippet) {
47+
public void execute(TestCodeSnippet snippet) throws Exception {
4848
CompilerConfiguration config = new CompilerConfiguration();
4949
config.addCompilationCustomizers(new CompilationCustomizer(CompilePhase.CONVERSION) {
5050
@Override
@@ -82,12 +82,7 @@ public void call(SourceUnit source, GeneratorContext context, ClassNode classNod
8282
ClassLoader previousContextClassLoader = Thread.currentThread().getContextClassLoader();
8383
try {
8484
Thread.currentThread().setContextClassLoader(groovyShell.getClassLoader());
85-
fixture.setup();
86-
try {
87-
script.run();
88-
} finally {
89-
fixture.cleanup();
90-
}
85+
fixture.around(script::run);
9186
} finally {
9287
Thread.currentThread().setContextClassLoader(previousContextClassLoader);
9388
}

ratpack-manual/src/test/groovy/ratpack/manual/snippets/executer/JavaSnippetExecuter.groovy

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package ratpack.manual.snippets.executer
1818

1919
import groovy.transform.CompileStatic
2020
import groovy.util.logging.Slf4j
21+
import ratpack.func.NoArgAction
2122
import ratpack.manual.snippets.TestCodeSnippet
2223

2324
import javax.tools.*
@@ -70,7 +71,7 @@ public class JavaSnippetExecuter implements SnippetExecuter {
7071
try {
7172
Thread.currentThread().setContextClassLoader(classLoader)
7273
def mainMethod = exampleClass.getMethod("main", Class.forName("[Ljava.lang.String;"))
73-
mainMethod.invoke(null, [[] as String[]] as Object[])
74+
snippet.fixture.around({ mainMethod.invoke(null, [[] as String[]] as Object[]) } as NoArgAction)
7475
} catch (NoSuchMethodException ignore) {
7576
// Class has no test method
7677
} catch (InvocationTargetException e) {

ratpack-manual/src/test/groovy/ratpack/manual/snippets/fixture/GradleFixture.groovy

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,47 +16,49 @@
1616

1717
package ratpack.manual.snippets.fixture
1818

19+
import ratpack.func.NoArgAction
20+
1921
import java.util.concurrent.locks.Condition
2022
import java.util.concurrent.locks.Lock
2123
import java.util.concurrent.locks.ReentrantLock
2224

2325
class GradleFixture extends GroovyScriptFixture {
2426

25-
private final Lock lock = new ReentrantLock()
26-
private final Condition available = lock.newCondition()
27-
private volatile boolean busy
28-
29-
@Override
30-
void setup() {
31-
lock.lock()
32-
while (busy) {
33-
available.await()
34-
}
35-
busy = true
36-
}
27+
private final Lock lock = new ReentrantLock()
28+
private final Condition available = lock.newCondition()
29+
private volatile boolean busy
3730

38-
@Override
39-
void cleanup() {
40-
busy = false
41-
available.signal()
42-
lock.unlock()
43-
}
31+
@Override
32+
void around(NoArgAction action) throws Exception {
33+
try {
34+
lock.lock()
35+
while (busy) {
36+
available.await()
37+
}
38+
busy = true
39+
action.execute()
40+
} finally {
41+
busy = false
42+
available.signal()
43+
lock.unlock()
44+
}
45+
}
4446

45-
@Override
46-
String pre() {
47-
"""
47+
@Override
48+
String pre() {
49+
"""
4850
import org.gradle.tooling.GradleConnector
4951
import org.gradle.tooling.model.GradleProject
5052
5153
def script = '''
5254
"""
53-
}
55+
}
5456

55-
@Override
56-
String post() {
57-
String localRepo = System.getProperty("localRepo", "build/localrepo")
58-
def localRepoPath = new File(localRepo).canonicalPath?.replaceAll("\\\\", "/")
59-
"""
57+
@Override
58+
String post() {
59+
String localRepo = System.getProperty("localRepo", "build/localrepo")
60+
def localRepoPath = new File(localRepo).canonicalPath?.replaceAll("\\\\", "/")
61+
"""
6062
'''
6163
def projectDir = File.createTempDir()
6264
def buildFile = new File(projectDir, "build.gradle")
@@ -85,5 +87,5 @@ try {
8587
projectDir.deleteDir()
8688
}
8789
"""
88-
}
90+
}
8991
}

ratpack-manual/src/test/groovy/ratpack/manual/snippets/fixture/GroovyChainDslFixture.groovy

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,6 @@ package ratpack.manual.snippets.fixture
1818

1919
class GroovyChainDslFixture extends GroovyScriptFixture {
2020

21-
@Override
22-
public void setup() {
23-
}
24-
25-
@Override
26-
public void cleanup() {
27-
}
28-
2921
@Override
3022
public String pre() {
3123
"""

0 commit comments

Comments
 (0)