From f6deafda3a7d6dbd65010eb58beb7b5e0c2184ea Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Wed, 22 Feb 2023 13:44:43 +0100 Subject: [PATCH] Add support for publishing the fat jar This commit adds compatibility with the Maven publish plugin, by making sure that if the application is published, then the uber jar is published as a classified artifact (`-uber`) in addition to the regular jar. A sample publishing configuration was added to the `app`, with a "local" publishing repository in /build/repo. For example, calling `./gradlew pAPTBR` will create the `build/repo` directory with the corresponding Maven repository structure after publishing. --- app/build.gradle.kts | 22 +++++++++ .../com/uwyn/rife2/gradle/Rife2Plugin.java | 47 +++++++++++++++---- 2 files changed, 61 insertions(+), 8 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 68f44cb..48c5f56 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -4,17 +4,25 @@ import org.gradle.api.tasks.testing.logging.TestLogEvent plugins { application id("com.uwyn.rife2") + `maven-publish` } base { archivesName.set("hello") version = 1.0 + group = "com.example" } application { mainClass.set("hello.App") } +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(17)) + } +} + repositories { // Use Maven Central for resolving dependencies. mavenCentral() @@ -44,3 +52,17 @@ tasks { } } } + +publishing { + repositories { + maven { + name = "Build" + url = uri(rootProject.layout.buildDirectory.dir("repo")) + } + } + publications { + create("maven") { + from(components["java"]) + } + } +} 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 ec85119..7572787 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 @@ -20,6 +20,11 @@ import org.gradle.api.Project; import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.ConfigurationContainer; import org.gradle.api.artifacts.dsl.DependencyHandler; +import org.gradle.api.attributes.Attribute; +import org.gradle.api.attributes.AttributeContainer; +import org.gradle.api.attributes.Bundling; +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; @@ -60,8 +65,34 @@ public class Rife2Plugin implements Plugin { createRife2DevelopmentOnlyConfiguration(project, configurations, dependencyHandler, precompileTemplates); exposePrecompiledTemplatesToTestTask(project, configurations, dependencyHandler, precompileTemplates); configureAgent(project, plugins, rife2Extension, rife2AgentClasspath); - registerUberJarTask(project, plugins, javaPluginExtension, rife2Extension, tasks, precompileTemplates); + TaskProvider uberJarTask = registerUberJarTask(project, plugins, javaPluginExtension, rife2Extension, tasks, precompileTemplates); bundlePrecompiledTemplatesIntoJarFile(tasks, precompileTemplates); + configureMavenPublishing(project, plugins, configurations, uberJarTask); + } + + private static void configureMavenPublishing(Project project, PluginContainer plugins, ConfigurationContainer configurations, TaskProvider uberJarTask) { + plugins.withId("maven-publish", unused -> { + Configuration rife2UberJarElements = configurations.create("rife2UberJarElements", conf -> { + conf.setDescription("Exposes the uber jar archive of the RIFE2 web application."); + conf.setCanBeResolved(false); + conf.setCanBeConsumed(true); + conf.getOutgoing().artifact(uberJarTask, artifact -> artifact.setClassifier("uber")); + AttributeContainer runtimeAttributes = configurations.getByName(JavaPlugin.RUNTIME_ELEMENTS_CONFIGURATION_NAME).getAttributes(); + 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); + } + } + }); + }); + AdhocComponentWithVariants component = (AdhocComponentWithVariants) project.getComponents().getByName("java"); + component.addVariantsFromConfiguration(rife2UberJarElements, ConfigurationVariantDetails::mapToOptional); + }); } private static void exposePrecompiledTemplatesToTestTask(Project project, ConfigurationContainer configurations, DependencyHandler dependencyHandler, TaskProvider precompileTemplates) { @@ -87,13 +118,13 @@ public class Rife2Plugin implements Plugin { configurations.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME).extendsFrom(rife2DevelopmentOnly); } - private static void registerUberJarTask(Project project, - PluginContainer plugins, - JavaPluginExtension javaPluginExtension, - Rife2Extension rife2Extension, - TaskContainer tasks, - TaskProvider precompileTemplatesTask) { - tasks.register("uberJar", Jar.class, jar -> { + private static TaskProvider registerUberJarTask(Project project, + PluginContainer plugins, + JavaPluginExtension javaPluginExtension, + Rife2Extension rife2Extension, + TaskContainer tasks, + TaskProvider precompileTemplatesTask) { + return tasks.register("uberJar", Jar.class, jar -> { var base = project.getExtensions().getByType(BasePluginExtension.class); jar.getArchiveBaseName().convention(project.provider(() -> base.getArchivesName().get() + "-uber")); jar.setDuplicatesStrategy(DuplicatesStrategy.EXCLUDE);