diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 48c5f56..df9f28e 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -2,19 +2,15 @@ import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.api.tasks.testing.logging.TestLogEvent 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 { @@ -30,6 +26,7 @@ repositories { } rife2 { + mainClass.set("hello.App") version.set("1.3.0") useAgent.set(true) } diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts index b29e98f..b9ea647 100644 --- a/build-logic/build.gradle.kts +++ b/build-logic/build.gradle.kts @@ -10,6 +10,13 @@ dependencies { gradleApi() } +tasks { + withType { + options.isDeprecation = true + options.compilerArgs.add("-Xlint:unchecked") + } +} + gradlePlugin { plugins { create("rife2") { diff --git a/build-logic/src/main/java/com/uwyn/rife2/gradle/Rife2Extension.java b/build-logic/src/main/java/com/uwyn/rife2/gradle/Rife2Extension.java index 1fe9591..ebd97e0 100644 --- a/build-logic/src/main/java/com/uwyn/rife2/gradle/Rife2Extension.java +++ b/build-logic/src/main/java/com/uwyn/rife2/gradle/Rife2Extension.java @@ -17,7 +17,10 @@ package com.uwyn.rife2.gradle; import org.gradle.api.provider.Property; +@SuppressWarnings("unused") public abstract class Rife2Extension { + public abstract Property getMainClass(); + public abstract Property getVersion(); public abstract Property getUseAgent(); diff --git a/build-logic/src/main/java/com/uwyn/rife2/gradle/Rife2Plugin.java b/build-logic/src/main/java/com/uwyn/rife2/gradle/Rife2Plugin.java index 7572787..17bfd18 100644 --- a/build-logic/src/main/java/com/uwyn/rife2/gradle/Rife2Plugin.java +++ b/build-logic/src/main/java/com/uwyn/rife2/gradle/Rife2Plugin.java @@ -27,14 +27,10 @@ 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.JavaExec; -import org.gradle.api.tasks.SourceSet; -import org.gradle.api.tasks.TaskContainer; -import org.gradle.api.tasks.TaskProvider; +import org.gradle.api.tasks.*; import org.gradle.api.tasks.bundling.Jar; import org.gradle.api.tasks.testing.Test; import org.gradle.process.CommandLineArgumentProvider; @@ -42,10 +38,11 @@ import org.gradle.process.CommandLineArgumentProvider; import java.util.Collections; import java.util.Locale; +@SuppressWarnings({"ALL", "unused"}) public class Rife2Plugin implements Plugin { - 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"; @Override @@ -65,6 +62,7 @@ public class Rife2Plugin implements Plugin { createRife2DevelopmentOnlyConfiguration(project, configurations, dependencyHandler, precompileTemplates); exposePrecompiledTemplatesToTestTask(project, configurations, dependencyHandler, precompileTemplates); configureAgent(project, plugins, rife2Extension, rife2AgentClasspath); + registerRunTask(project, rife2Extension, rife2AgentClasspath); TaskProvider uberJarTask = registerUberJarTask(project, plugins, javaPluginExtension, rife2Extension, tasks, precompileTemplates); bundlePrecompiledTemplatesIntoJarFile(tasks, precompileTemplates); configureMavenPublishing(project, plugins, configurations, uberJarTask); @@ -81,11 +79,13 @@ public class Rife2Plugin implements Plugin { conf.attributes(attrs -> { for (Attribute attribute : runtimeAttributes.keySet()) { Object value = runtimeAttributes.getAttribute(attribute); - //noinspection unchecked - if (Bundling.class.equals(attribute.getType())) { - attrs.attribute(Bundling.BUNDLING_ATTRIBUTE, project.getObjects().named(Bundling.class, Bundling.SHADOWED)); - } else { - attrs.attribute((Attribute) attribute, value); + 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) attribute, value); + } } } }); @@ -125,6 +125,8 @@ public class Rife2Plugin implements Plugin { TaskContainer tasks, TaskProvider precompileTemplatesTask) { return tasks.register("uberJar", Jar.class, jar -> { + jar.setGroup(RIFE2_GROUP); + jar.setDescription("Assembles the web application and all dependencies into a single jar archive."); var base = project.getExtensions().getByType(BasePluginExtension.class); jar.getArchiveBaseName().convention(project.provider(() -> base.getArchivesName().get() + "-uber")); jar.setDuplicatesStrategy(DuplicatesStrategy.EXCLUDE); @@ -156,8 +158,7 @@ public class Rife2Plugin implements Plugin { private static Rife2Extension createRife2Extension(Project project) { var rife2 = project.getExtensions().create("rife2", Rife2Extension.class); rife2.getUseAgent().convention(false); - rife2.getUberMainClass().convention(project.getExtensions().getByType(JavaApplication.class).getMainClass() - .map(mainClass -> mainClass + "Uber")); + rife2.getUberMainClass().set(rife2.getMainClass() + "Uber"); return rife2; } @@ -199,6 +200,8 @@ public class Rife2Plugin implements Plugin { private static TaskProvider registerPrecompileTemplateTask(Project project, Configuration rife2CompilerClasspath) { return project.getTasks().register("precompileTemplates", PrecompileTemplates.class, task -> { + task.setGroup(RIFE2_GROUP); + task.setDescription("Pre-compiles the templates."); task.getVerbose().convention(true); task.getClasspath().from(rife2CompilerClasspath); task.getType().convention("html"); @@ -206,4 +209,17 @@ public class Rife2Plugin implements Plugin { 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)); + }); + } } diff --git a/build-logic/src/main/java/com/uwyn/rife2/gradle/RunTask.java b/build-logic/src/main/java/com/uwyn/rife2/gradle/RunTask.java new file mode 100644 index 0000000..c107544 --- /dev/null +++ b/build-logic/src/main/java/com/uwyn/rife2/gradle/RunTask.java @@ -0,0 +1,54 @@ +/* + * 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 getAgentClassPath(); + + @Classpath + public abstract ConfigurableFileCollection getClasspath(); + + @Inject + protected abstract ExecOperations getExecOperations(); + + @Input + public abstract Property 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())); + }); + } +} \ No newline at end of file diff --git a/war/build.gradle.kts b/war/build.gradle.kts index 206f003..477784d 100644 --- a/war/build.gradle.kts +++ b/war/build.gradle.kts @@ -2,9 +2,10 @@ plugins { war } +version = 1.0 + base { archivesName.set("hello") - version = 1.0 } repositories { @@ -20,4 +21,4 @@ tasks.war { webAppDirectory.set(file("../app/src/main/webapp")) webXml = file("src/web.xml") rootSpec.exclude("**/jetty*.jar", "**/slf4j*.jar", "**/rife2*-agent.jar") -} \ No newline at end of file +}