mirror of
https://github.com/ethauvin/rife2-hello.git
synced 2025-04-25 07:27:12 -07:00
Merge pull request #5 from melix/cc/fix-template-reloading
Fix template reloading
This commit is contained in:
commit
d8c41b45d9
22 changed files with 565 additions and 110 deletions
|
@ -3,15 +3,19 @@ import org.gradle.api.tasks.testing.logging.TestLogEvent
|
|||
import com.uwyn.rife2.gradle.TemplateType.*
|
||||
|
||||
plugins {
|
||||
application
|
||||
id("com.uwyn.rife2")
|
||||
`maven-publish`
|
||||
}
|
||||
|
||||
version = 1.0
|
||||
group = "com.example"
|
||||
|
||||
base {
|
||||
archivesName.set("hello")
|
||||
version = 1.0
|
||||
group = "com.example"
|
||||
}
|
||||
|
||||
application {
|
||||
mainClass.set("hello.App")
|
||||
}
|
||||
|
||||
java {
|
||||
|
@ -27,19 +31,16 @@ repositories {
|
|||
}
|
||||
|
||||
rife2 {
|
||||
mainClass.set("hello.App")
|
||||
version.set("1.4.0")
|
||||
useAgent.set(true)
|
||||
precompiledTemplateTypes.addAll(HTML)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
runtimeOnly("org.eclipse.jetty:jetty-server:11.0.13")
|
||||
runtimeOnly("org.eclipse.jetty:jetty-servlet:11.0.13")
|
||||
runtimeOnly("org.slf4j:slf4j-simple:2.0.5")
|
||||
runtimeOnly(libs.bundles.jetty)
|
||||
runtimeOnly(libs.slf4j.simple)
|
||||
|
||||
testImplementation("org.jsoup:jsoup:1.15.3")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter:5.9.1")
|
||||
testImplementation(libs.jsoup)
|
||||
testImplementation(libs.junit.jupiter)
|
||||
}
|
||||
|
||||
tasks {
|
||||
|
|
|
@ -8,4 +8,4 @@
|
|||
<body>
|
||||
<p>Hello World</p>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
plugins {
|
||||
`java-gradle-plugin`
|
||||
groovy
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
@ -8,13 +9,8 @@ repositories {
|
|||
|
||||
dependencies {
|
||||
gradleApi()
|
||||
}
|
||||
|
||||
tasks {
|
||||
withType<JavaCompile> {
|
||||
options.isDeprecation = true
|
||||
options.compilerArgs.add("-Xlint:unchecked")
|
||||
}
|
||||
testImplementation(libs.spock.core)
|
||||
testImplementation(gradleTestKit())
|
||||
}
|
||||
|
||||
gradlePlugin {
|
||||
|
@ -25,3 +21,11 @@ gradlePlugin {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<Test>().configureEach {
|
||||
useJUnitPlatform()
|
||||
testLogging {
|
||||
exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
|
||||
events = setOf(org.gradle.api.tasks.testing.logging.TestLogEvent.PASSED, org.gradle.api.tasks.testing.logging.TestLogEvent.SKIPPED, org.gradle.api.tasks.testing.logging.TestLogEvent.FAILED)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1,9 @@
|
|||
rootProject.name = "build-logic"
|
||||
|
||||
dependencyResolutionManagement {
|
||||
versionCatalogs {
|
||||
create("libs") {
|
||||
from(files("../gradle/libs.versions.toml"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,10 +18,7 @@ package com.uwyn.rife2.gradle;
|
|||
import org.gradle.api.provider.ListProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public abstract class Rife2Extension {
|
||||
public abstract Property<String> getMainClass();
|
||||
|
||||
public abstract Property<String> getVersion();
|
||||
|
||||
public abstract Property<Boolean> getUseAgent();
|
||||
|
|
|
@ -25,10 +25,14 @@ import org.gradle.api.component.AdhocComponentWithVariants;
|
|||
import org.gradle.api.component.ConfigurationVariantDetails;
|
||||
import org.gradle.api.file.DuplicatesStrategy;
|
||||
import org.gradle.api.plugins.BasePluginExtension;
|
||||
import org.gradle.api.plugins.JavaApplication;
|
||||
import org.gradle.api.plugins.JavaPlugin;
|
||||
import org.gradle.api.plugins.JavaPluginExtension;
|
||||
import org.gradle.api.plugins.PluginContainer;
|
||||
import org.gradle.api.tasks.*;
|
||||
import org.gradle.api.tasks.JavaExec;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.gradle.api.tasks.TaskContainer;
|
||||
import org.gradle.api.tasks.TaskProvider;
|
||||
import org.gradle.api.tasks.bundling.Jar;
|
||||
import org.gradle.api.tasks.testing.Test;
|
||||
import org.gradle.process.CommandLineArgumentProvider;
|
||||
|
@ -36,12 +40,12 @@ import org.gradle.process.CommandLineArgumentProvider;
|
|||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
|
||||
@SuppressWarnings({"ALL", "unused"})
|
||||
public class Rife2Plugin implements Plugin<Project> {
|
||||
public static final String DEFAULT_TEMPLATES_DIR = "src/main/templates";
|
||||
public static final String DEFAULT_GENERATED_RIFE2_CLASSES_DIR = "generated/classes/rife2";
|
||||
public static final String RIFE2_GROUP = "rife2";
|
||||
public static final String WEBAPP_SRCDIR = "src/main/webapp";
|
||||
public static final String PRECOMPILE_TEMPLATES_TASK_NAME = "precompileTemplates";
|
||||
|
||||
@Override
|
||||
public void apply(Project project) {
|
||||
|
@ -59,12 +63,10 @@ public class Rife2Plugin implements Plugin<Project> {
|
|||
configurations.getByName(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME).extendsFrom(rife2Configuration);
|
||||
|
||||
var precompileTemplates = registerPrecompileTemplateTask(project, rife2CompilerClasspath, rife2Extension);
|
||||
createRife2DevelopmentOnlyConfiguration(project, configurations, dependencyHandler, precompileTemplates);
|
||||
createRife2DevelopmentOnlyConfiguration(project, configurations, dependencyHandler);
|
||||
exposePrecompiledTemplatesToTestTask(project, configurations, dependencyHandler, precompileTemplates);
|
||||
configureAgent(project, plugins, rife2Extension, rife2AgentClasspath);
|
||||
registerRunTask(project, rife2Extension, rife2AgentClasspath);
|
||||
var uberJarTask = registerUberJarTask(project, plugins, javaPluginExtension, rife2Extension, tasks, precompileTemplates);
|
||||
|
||||
TaskProvider<Jar> uberJarTask = registerUberJarTask(project, plugins, javaPluginExtension, rife2Extension, tasks, precompileTemplates);
|
||||
bundlePrecompiledTemplatesIntoJarFile(tasks, precompileTemplates);
|
||||
|
||||
configureMavenPublishing(project, plugins, configurations, uberJarTask);
|
||||
|
@ -86,13 +88,11 @@ public class Rife2Plugin implements Plugin<Project> {
|
|||
conf.attributes(attrs -> {
|
||||
for (Attribute<?> attribute : runtimeAttributes.keySet()) {
|
||||
Object value = runtimeAttributes.getAttribute(attribute);
|
||||
if (value != null) {
|
||||
if (Bundling.class.equals(attribute.getType())) {
|
||||
attrs.attribute(Bundling.BUNDLING_ATTRIBUTE, project.getObjects().named(Bundling.class, Bundling.SHADOWED));
|
||||
} else {
|
||||
//noinspection unchecked
|
||||
attrs.attribute((Attribute<Object>) attribute, value);
|
||||
}
|
||||
//noinspection unchecked
|
||||
if (Bundling.class.equals(attribute.getType())) {
|
||||
attrs.attribute(Bundling.BUNDLING_ATTRIBUTE, project.getObjects().named(Bundling.class, Bundling.SHADOWED));
|
||||
} else {
|
||||
attrs.attribute((Attribute<Object>) attribute, value);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -119,14 +119,13 @@ public class Rife2Plugin implements Plugin<Project> {
|
|||
|
||||
private void createRife2DevelopmentOnlyConfiguration(Project project,
|
||||
ConfigurationContainer configurations,
|
||||
DependencyHandler dependencies,
|
||||
TaskProvider<PrecompileTemplates> precompileTemplatesTask) {
|
||||
DependencyHandler dependencies) {
|
||||
var rife2DevelopmentOnly = configurations.create("rife2DevelopmentOnly", conf -> {
|
||||
conf.setDescription("Dependencies which should only be visible when running the application in development mode (and not in tests).");
|
||||
conf.setCanBeConsumed(false);
|
||||
conf.setCanBeResolved(false);
|
||||
});
|
||||
rife2DevelopmentOnly.getDependencies().add(dependencies.create(project.files(precompileTemplatesTask)));
|
||||
rife2DevelopmentOnly.getDependencies().add(dependencies.create(project.files(DEFAULT_TEMPLATES_DIR)));
|
||||
configurations.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME).extendsFrom(rife2DevelopmentOnly);
|
||||
}
|
||||
|
||||
|
@ -173,7 +172,9 @@ public class Rife2Plugin implements Plugin<Project> {
|
|||
private static Rife2Extension createRife2Extension(Project project) {
|
||||
var rife2 = project.getExtensions().create("rife2", Rife2Extension.class);
|
||||
rife2.getUseAgent().convention(false);
|
||||
rife2.getUberMainClass().set(rife2.getMainClass() + "Uber");
|
||||
rife2.getUberMainClass().convention(project.getExtensions().getByType(JavaApplication.class).getMainClass()
|
||||
.map(mainClass -> mainClass + "Uber"));
|
||||
rife2.getPrecompiledTemplateTypes().convention(Collections.singletonList(TemplateType.HTML));
|
||||
return rife2;
|
||||
}
|
||||
|
||||
|
@ -216,7 +217,7 @@ public class Rife2Plugin implements Plugin<Project> {
|
|||
private static TaskProvider<PrecompileTemplates> registerPrecompileTemplateTask(Project project,
|
||||
Configuration rife2CompilerClasspath,
|
||||
Rife2Extension rife2Extension) {
|
||||
return project.getTasks().register("precompileTemplates", PrecompileTemplates.class, task -> {
|
||||
return project.getTasks().register(PRECOMPILE_TEMPLATES_TASK_NAME, PrecompileTemplates.class, task -> {
|
||||
task.setGroup(RIFE2_GROUP);
|
||||
task.setDescription("Pre-compiles the templates.");
|
||||
task.getVerbose().convention(true);
|
||||
|
@ -226,18 +227,4 @@ public class Rife2Plugin implements Plugin<Project> {
|
|||
task.getOutputDirectory().set(project.getLayout().getBuildDirectory().dir(DEFAULT_GENERATED_RIFE2_CLASSES_DIR));
|
||||
});
|
||||
}
|
||||
|
||||
private static void registerRunTask(Project project,
|
||||
Rife2Extension rife2Extension,
|
||||
Configuration rife2CompilerClasspath) {
|
||||
project.getTasks().register("run", RunTask.class, task -> {
|
||||
task.setGroup(RIFE2_GROUP);
|
||||
task.setDescription("Runs this project as a web application.");
|
||||
task.getAgentClassPath().set(rife2CompilerClasspath.getAsPath());
|
||||
task.getClasspath().from(project.getExtensions().getByType(SourceSetContainer.class)
|
||||
.getByName(SourceSet.MAIN_SOURCE_SET_NAME).getRuntimeClasspath());
|
||||
task.getMainClass().set(rife2Extension.getMainClass());
|
||||
task.getTemplatesDirectory().set(project.getLayout().getProjectDirectory().dir(DEFAULT_TEMPLATES_DIR));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
* Copyright 2003-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.uwyn.rife2.gradle;
|
||||
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.file.ConfigurableFileCollection;
|
||||
import org.gradle.api.file.DirectoryProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.tasks.*;
|
||||
import org.gradle.process.ExecOperations;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
@CacheableTask
|
||||
public abstract class RunTask extends DefaultTask {
|
||||
@Input
|
||||
public abstract Property<String> getAgentClassPath();
|
||||
|
||||
@Classpath
|
||||
public abstract ConfigurableFileCollection getClasspath();
|
||||
|
||||
@Inject
|
||||
protected abstract ExecOperations getExecOperations();
|
||||
|
||||
@Input
|
||||
public abstract Property<String> getMainClass();
|
||||
|
||||
@InputDirectory
|
||||
@PathSensitive(PathSensitivity.RELATIVE)
|
||||
public abstract DirectoryProperty getTemplatesDirectory();
|
||||
|
||||
@TaskAction
|
||||
public void run() {
|
||||
getExecOperations().javaexec(run -> {
|
||||
run.setClasspath(getProject().getObjects().fileCollection().from(getTemplatesDirectory()).plus(getClasspath()));
|
||||
run.getMainClass().set(getMainClass());
|
||||
run.args(List.of("-javaagent:" + getAgentClassPath().get()));
|
||||
});
|
||||
}
|
||||
}
|
40
build-logic/src/test-projects/minimal/build.gradle
Normal file
40
build-logic/src/test-projects/minimal/build.gradle
Normal file
|
@ -0,0 +1,40 @@
|
|||
import com.uwyn.rife2.gradle.TemplateType.*
|
||||
|
||||
plugins {
|
||||
id("application")
|
||||
id("com.uwyn.rife2")
|
||||
}
|
||||
|
||||
base {
|
||||
archivesName = "hello"
|
||||
version = 1.0
|
||||
group = "com.example"
|
||||
}
|
||||
|
||||
application {
|
||||
mainClass = "hello.App"
|
||||
}
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(17)
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
rife2 {
|
||||
version = "1.4.0"
|
||||
useAgent = true
|
||||
}
|
||||
|
||||
dependencies {
|
||||
runtimeOnly("org.eclipse.jetty:jetty-server:11.0.13")
|
||||
runtimeOnly("org.eclipse.jetty:jetty-servlet:11.0.13")
|
||||
runtimeOnly("org.slf4j:slf4j-simple:2.0.5")
|
||||
|
||||
testImplementation("org.jsoup:jsoup:1.15.3")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter:5.9.1")
|
||||
}
|
1
build-logic/src/test-projects/minimal/settings.gradle
Normal file
1
build-logic/src/test-projects/minimal/settings.gradle
Normal file
|
@ -0,0 +1 @@
|
|||
rootProject.name = 'minimal'
|
|
@ -0,0 +1,16 @@
|
|||
package hello;
|
||||
|
||||
import rife.engine.*;
|
||||
|
||||
public class App extends Site {
|
||||
public void setup() {
|
||||
var hello = get("/hello", c -> c.print(c.template("hello")));
|
||||
get("/", c -> c.redirect(hello));
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new Server()
|
||||
.staticResourceBase("src/main/webapp")
|
||||
.start(new App());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package hello;
|
||||
|
||||
import rife.engine.Server;
|
||||
|
||||
public class AppUber extends App {
|
||||
public static void main(String[] args) {
|
||||
new Server()
|
||||
.staticUberJarResourceBase("webapp")
|
||||
.start(new AppUber());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
[
|
||||
{
|
||||
"name":"rife.template.html.hello",
|
||||
"methods":[{"name":"<init>","parameterTypes":[] }]
|
||||
}
|
||||
]
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"resources":{
|
||||
"includes":[
|
||||
{"pattern":"^webapp/.*$"}
|
||||
]
|
||||
},
|
||||
"bundles":[]
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title><!--v title-->Hello<!--/v--></title>
|
||||
<link rel="stylesheet" href="{{v webapp:rootUrl/}}css/style.css?{{v context:paramRandom/}}">
|
||||
</head>
|
||||
<body>
|
||||
<p>Hello World</p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,21 @@
|
|||
:root {
|
||||
/* fonts */
|
||||
--main-font: sans-serif;
|
||||
|
||||
/* font sizes */
|
||||
--main-font-size: 18px;
|
||||
|
||||
/* colors */
|
||||
--main-background-color: #0d0d0d;
|
||||
--main-text-color: #d0d0d0;
|
||||
|
||||
/* margins and padding */
|
||||
--content-padding: 2em;
|
||||
}
|
||||
body {
|
||||
background: var(--main-background-color);
|
||||
font-family: var(--main-font);
|
||||
font-style: var(--main-font-size);
|
||||
color: var(--main-text-color);
|
||||
padding: var(--content-padding);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* This Java source file was generated by the Gradle 'init' task.
|
||||
*/
|
||||
package hello;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import rife.test.MockConversation;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class AppTest {
|
||||
@Test
|
||||
void verifyRoot() {
|
||||
var m = new MockConversation(new App());
|
||||
assertEquals(m.doRequest("/").getStatus(), 302);
|
||||
}
|
||||
|
||||
@Test
|
||||
void verifyHello() {
|
||||
var m = new MockConversation(new App());
|
||||
assertEquals("Hello", m.doRequest("/hello")
|
||||
.getTemplate().getValue("title"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,184 @@
|
|||
package com.uwyn.rife2.gradle
|
||||
|
||||
import org.gradle.testkit.runner.BuildResult
|
||||
import org.gradle.testkit.runner.GradleRunner
|
||||
import org.gradle.testkit.runner.TaskOutcome
|
||||
import org.gradle.util.GFileUtils
|
||||
import org.gradle.util.GradleVersion
|
||||
import spock.lang.Specification
|
||||
import spock.lang.TempDir
|
||||
|
||||
import java.nio.file.Path
|
||||
|
||||
abstract class AbstractFunctionalTest extends Specification {
|
||||
|
||||
private final String gradleVersion = System.getProperty("gradleVersion", GradleVersion.current().version)
|
||||
|
||||
@TempDir
|
||||
Path testDirectory
|
||||
|
||||
boolean debug
|
||||
|
||||
private StringWriter outputWriter
|
||||
private StringWriter errorOutputWriter
|
||||
private String output
|
||||
private String errorOutput
|
||||
|
||||
BuildResult result
|
||||
|
||||
Path path(String... pathElements) {
|
||||
Path cur = testDirectory
|
||||
pathElements.each {
|
||||
cur = cur.resolve(it)
|
||||
}
|
||||
cur
|
||||
}
|
||||
|
||||
File file(String... pathElements) {
|
||||
path(pathElements).toFile()
|
||||
}
|
||||
|
||||
File getGroovyBuildFile() {
|
||||
file("build.gradle")
|
||||
}
|
||||
|
||||
File getBuildFile() {
|
||||
groovyBuildFile
|
||||
}
|
||||
|
||||
File getKotlinBuildFile() {
|
||||
file("build.gradle.kts")
|
||||
}
|
||||
|
||||
File getGroovySettingsFile() {
|
||||
file("settings.gradle")
|
||||
}
|
||||
|
||||
File getKotlinSettingsFile() {
|
||||
file("settings.gradle.kts")
|
||||
}
|
||||
|
||||
File getSettingsFile() {
|
||||
groovySettingsFile
|
||||
}
|
||||
|
||||
void run(String... args) {
|
||||
try {
|
||||
result = newRunner(args)
|
||||
.build()
|
||||
} finally {
|
||||
recordOutputs()
|
||||
}
|
||||
}
|
||||
|
||||
void outputContains(String text) {
|
||||
assert output.normalize().contains(text.normalize())
|
||||
}
|
||||
|
||||
void outputDoesNotContain(String text) {
|
||||
assert !output.normalize().contains(text.normalize())
|
||||
}
|
||||
|
||||
void errorOutputContains(String text) {
|
||||
assert errorOutput.normalize().contains(text.normalize())
|
||||
}
|
||||
|
||||
void tasks(@DelegatesTo(value = TaskExecutionGraph, strategy = Closure.DELEGATE_FIRST) Closure spec) {
|
||||
def graph = new TaskExecutionGraph()
|
||||
spec.delegate = graph
|
||||
spec.resolveStrategy = Closure.DELEGATE_FIRST
|
||||
spec()
|
||||
}
|
||||
|
||||
private void recordOutputs() {
|
||||
output = outputWriter.toString()
|
||||
errorOutput = errorOutputWriter.toString()
|
||||
}
|
||||
|
||||
private GradleRunner newRunner(String... args) {
|
||||
outputWriter = new StringWriter()
|
||||
errorOutputWriter = new StringWriter()
|
||||
ArrayList<String> autoArgs = computeAutoArgs()
|
||||
def runner = GradleRunner.create()
|
||||
.forwardStdOutput(tee(new OutputStreamWriter(System.out), outputWriter))
|
||||
.forwardStdError(tee(new OutputStreamWriter(System.err), errorOutputWriter))
|
||||
.withPluginClasspath()
|
||||
.withProjectDir(testDirectory.toFile())
|
||||
.withArguments([*autoArgs, *args])
|
||||
if (gradleVersion) {
|
||||
runner.withGradleVersion(gradleVersion)
|
||||
}
|
||||
if (debug) {
|
||||
runner.withDebug(true)
|
||||
}
|
||||
runner
|
||||
}
|
||||
|
||||
private ArrayList<String> computeAutoArgs() {
|
||||
List<String> autoArgs = [
|
||||
"-s",
|
||||
"--console=verbose"
|
||||
]
|
||||
if (Boolean.getBoolean("config.cache")) {
|
||||
autoArgs << '--configuration-cache'
|
||||
}
|
||||
autoArgs
|
||||
}
|
||||
|
||||
private static Writer tee(Writer one, Writer two) {
|
||||
return TeeWriter.of(one, two)
|
||||
}
|
||||
|
||||
void fails(String... args) {
|
||||
try {
|
||||
result = newRunner(args)
|
||||
.buildAndFail()
|
||||
} finally {
|
||||
recordOutputs()
|
||||
}
|
||||
}
|
||||
|
||||
private class TaskExecutionGraph {
|
||||
void succeeded(String... tasks) {
|
||||
tasks.each { task ->
|
||||
contains(task)
|
||||
assert result.task(task).outcome == TaskOutcome.SUCCESS
|
||||
}
|
||||
}
|
||||
|
||||
void failed(String... tasks) {
|
||||
tasks.each { task ->
|
||||
contains(task)
|
||||
assert result.task(task).outcome == TaskOutcome.FAILED
|
||||
}
|
||||
}
|
||||
|
||||
void skipped(String... tasks) {
|
||||
tasks.each { task ->
|
||||
contains(task)
|
||||
assert result.task(task).outcome == TaskOutcome.SKIPPED
|
||||
}
|
||||
}
|
||||
|
||||
void contains(String... tasks) {
|
||||
tasks.each { task ->
|
||||
assert result.task(task) != null: "Expected to find task $task in the graph but it was missing"
|
||||
}
|
||||
}
|
||||
|
||||
void doesNotContain(String... tasks) {
|
||||
tasks.each { task ->
|
||||
assert result.task(task) == null: "Task $task should be missing from the task graph but it was found with an outcome of ${result.task(task).outcome}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usesProject(String name) {
|
||||
File sampleDir = new File("src/test-projects/$name")
|
||||
GFileUtils.copyDirectory(sampleDir, testDirectory.toFile())
|
||||
}
|
||||
|
||||
File file(String path) {
|
||||
new File(testDirectory.toFile(), path)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.uwyn.rife2.gradle
|
||||
|
||||
import java.nio.file.FileSystems
|
||||
import java.nio.file.Files
|
||||
|
||||
class PackagingTest extends AbstractFunctionalTest {
|
||||
def setup() {
|
||||
usesProject("minimal")
|
||||
}
|
||||
|
||||
def "#archive contains compiled resources"() {
|
||||
def jarFile = file(archive).toPath()
|
||||
when:
|
||||
run task
|
||||
|
||||
then: "compiles templates are found in the archive"
|
||||
tasks {
|
||||
succeeded ":${Rife2Plugin.PRECOMPILE_TEMPLATES_TASK_NAME}"
|
||||
}
|
||||
Files.exists(jarFile)
|
||||
try (def fs = FileSystems.newFileSystem(jarFile, [:])) {
|
||||
fs.getRootDirectories().each {
|
||||
Files.walk(it).forEach { path ->
|
||||
println path
|
||||
}
|
||||
}
|
||||
assert Files.exists(fs.getPath("/rife/template/html/hello.class"))
|
||||
}
|
||||
|
||||
where:
|
||||
task | archive
|
||||
'jar' | 'build/libs/hello-1.0.jar'
|
||||
'uberJar' | 'build/libs/hello-uber-1.0.jar'
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package com.uwyn.rife2.gradle
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class TeeWriter extends Writer {
|
||||
private final Writer one
|
||||
private final Writer two
|
||||
|
||||
static TeeWriter of(Writer one, Writer two) {
|
||||
new TeeWriter(one, two)
|
||||
}
|
||||
|
||||
private TeeWriter(Writer one, Writer two) {
|
||||
this.one = one
|
||||
this.two = two
|
||||
}
|
||||
|
||||
@Override
|
||||
void write(int c) throws IOException {
|
||||
try {
|
||||
one.write(c)
|
||||
} finally {
|
||||
two.write(c)
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void write(char[] cbuf) throws IOException {
|
||||
try {
|
||||
one.write(cbuf)
|
||||
} finally {
|
||||
two.write(cbuf)
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void write(char[] cbuf, int off, int len) throws IOException {
|
||||
try {
|
||||
one.write(cbuf, off, len)
|
||||
} finally {
|
||||
two.write(cbuf, off, len)
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void write(String str) throws IOException {
|
||||
try {
|
||||
one.write(str)
|
||||
} finally {
|
||||
two.write(str)
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void write(String str, int off, int len) throws IOException {
|
||||
try {
|
||||
one.write(str, off, len)
|
||||
} finally {
|
||||
two.write(str, off, len)
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void flush() throws IOException {
|
||||
try {
|
||||
one.flush()
|
||||
} finally {
|
||||
two.flush()
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void close() throws IOException {
|
||||
try {
|
||||
one.close()
|
||||
} finally {
|
||||
two.close()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package com.uwyn.rife2.gradle
|
||||
|
||||
class TemplateCompilationTest extends AbstractFunctionalTest {
|
||||
def setup() {
|
||||
usesProject("minimal")
|
||||
}
|
||||
|
||||
def "doesn't precompile templates when calling `run`"() {
|
||||
given:
|
||||
buildFile << """
|
||||
tasks.named("run") {
|
||||
doFirst {
|
||||
throw new RuntimeException("force stop")
|
||||
}
|
||||
}
|
||||
"""
|
||||
when:
|
||||
fails 'run'
|
||||
|
||||
then: "precompile templates task must not be present in task graph"
|
||||
errorOutputContains("force stop")
|
||||
tasks {
|
||||
doesNotContain ":${Rife2Plugin.PRECOMPILE_TEMPLATES_TASK_NAME}"
|
||||
}
|
||||
}
|
||||
|
||||
def "`run` task classpath includes template sources"() {
|
||||
given:
|
||||
buildFile << """
|
||||
tasks.register("dumpRunClasspath") {
|
||||
doLast {
|
||||
tasks.named("run").get().classpath.files.each {
|
||||
println "Classpath entry: \$it"
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
when:
|
||||
run("dumpRunClasspath")
|
||||
|
||||
then: "template sources must be present in the classpath"
|
||||
outputContains("Classpath entry: ${file("src/main/templates").absolutePath}")
|
||||
}
|
||||
|
||||
def "compiles templates when running #task"() {
|
||||
when:
|
||||
run task
|
||||
|
||||
then: "precompile templates task must be present in task graph"
|
||||
tasks {
|
||||
succeeded ":${Rife2Plugin.PRECOMPILE_TEMPLATES_TASK_NAME}"
|
||||
}
|
||||
|
||||
where:
|
||||
task << ['jar', 'test', 'uberJar']
|
||||
}
|
||||
}
|
17
gradle/libs.versions.toml
Normal file
17
gradle/libs.versions.toml
Normal file
|
@ -0,0 +1,17 @@
|
|||
[versions]
|
||||
jetty = "11.0.13"
|
||||
jsoup = "1.15.3"
|
||||
junit-jupiter = "5.9.1"
|
||||
slf4j = "2.0.5"
|
||||
spock = "2.3-groovy-3.0"
|
||||
|
||||
[libraries]
|
||||
jetty-server = { module = "org.eclipse.jetty:jetty-server", version.ref = "jetty" }
|
||||
jetty-servlet = { module = "org.eclipse.jetty:jetty-servlet", version.ref = "jetty" }
|
||||
jsoup = { module = "org.jsoup:jsoup", version.ref = "jsoup" }
|
||||
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit-jupiter" }
|
||||
slf4j-simple = { module = "org.slf4j:slf4j-simple", version.ref = "slf4j" }
|
||||
spock-core = { module = "org.spockframework:spock-core", version.ref = "spock" }
|
||||
|
||||
[bundles]
|
||||
jetty = [ "jetty-server", "jetty-servlet" ]
|
|
@ -2,10 +2,9 @@ plugins {
|
|||
war
|
||||
}
|
||||
|
||||
version = 1.0
|
||||
|
||||
base {
|
||||
archivesName.set("hello")
|
||||
version = 1.0
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
@ -21,4 +20,4 @@ tasks.war {
|
|||
webAppDirectory.set(file("../app/src/main/webapp"))
|
||||
webXml = file("src/web.xml")
|
||||
rootSpec.exclude("**/jetty*.jar", "**/slf4j*.jar", "**/rife2*-agent.jar")
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue