From bb1cb71e12084616c845988c70c8e59052bc190c Mon Sep 17 00:00:00 2001 From: Wouter Born Date: Thu, 23 Jul 2026 16:20:56 +0200 Subject: [PATCH] Automate extension runtime dependency packaging * Automatically discover extension subprojects, excluding `deployment` and `ems` * Package extension JARs together with their transitive runtime dependencies * Select standard JVM runtime variants when resolving dependencies * Exclude dependencies already provided by the Manager core image * Use a configuration-cache-compatible task to synchronize the extension directory and remove stale files Fixes #66 --- deployment/build.gradle | 123 +++++++++++++++++++++++++++++++++++----- 1 file changed, 110 insertions(+), 13 deletions(-) diff --git a/deployment/build.gradle b/deployment/build.gradle index bdbee54..0ae4d8d 100644 --- a/deployment/build.gradle +++ b/deployment/build.gradle @@ -1,25 +1,122 @@ +import org.gradle.api.DefaultTask +import org.gradle.api.attributes.Category +import org.gradle.api.attributes.LibraryElements +import org.gradle.api.attributes.Usage +import org.gradle.api.attributes.java.TargetJvmEnvironment +import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.DuplicatesStrategy +import org.gradle.api.file.FileSystemOperations +import org.gradle.api.tasks.Classpath +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.TaskAction + +import javax.inject.Inject + plugins { id 'base' } -tasks.register("copyDockerFile", Copy) { - from layout.projectDirectory.file("Dockerfile") - into layout.buildDirectory +abstract class DistributeExtensions extends DefaultTask { + + @Classpath + abstract ConfigurableFileCollection getExtensionFiles() + + @Classpath + abstract ConfigurableFileCollection getManagerFiles() + + @OutputDirectory + abstract DirectoryProperty getDestinationDirectory() + + @Inject + abstract FileSystemOperations getFileSystemOperations() + + @TaskAction + void distribute() { + Set managerFileNames = managerFiles.files.collect { + it.name + } as Set + + fileSystemOperations.sync { + from(extensionFiles) { + exclude { details -> + managerFileNames.contains(details.file.name) + } + } + + into(destinationDirectory.get().asFile) + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + } + } } -tasks.register("distributeExtensions", Copy) { - def extensionProjects = [ - project(":demo-setup"), - project(":energy"), - project(":entsoe") - ] +def excludedExtensionProjects = [ + project.path, + ":ems" +] as Set + +def extensionProjects = rootProject.subprojects.findAll { + !excludedExtensionProjects.contains(it.path) +} - extensionProjects.each { extProj -> - def jarTask = extProj.tasks.named("jar") - from(jarTask.flatMap { it.archiveFile }) +def configureRuntimeAttributes = { configuration -> + configuration.attributes { + attribute( + Usage.USAGE_ATTRIBUTE, + objects.named(Usage, Usage.JAVA_RUNTIME) + ) + attribute( + Category.CATEGORY_ATTRIBUTE, + objects.named(Category, Category.LIBRARY) + ) + attribute( + LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, + objects.named(LibraryElements, LibraryElements.JAR) + ) + attribute( + TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE, + objects.named( + TargetJvmEnvironment, + TargetJvmEnvironment.STANDARD_JVM + ) + ) } +} + +configurations { + extensionRuntime { + canBeConsumed = false + canBeResolved = true + } + + managerRuntime { + canBeConsumed = false + canBeResolved = true + } +} + +configureRuntimeAttributes(configurations.extensionRuntime) +configureRuntimeAttributes(configurations.managerRuntime) + +dependencies { + extensionProjects.each { extensionProject -> + extensionRuntime project(path: extensionProject.path) + } + + managerRuntime libs.openremote.manager +} + +tasks.register("copyDockerFile", Copy) { + from layout.projectDirectory.file("Dockerfile") + into layout.buildDirectory +} - into layout.buildDirectory.dir("extensions") +tasks.register("distributeExtensions", DistributeExtensions) { + extensionFiles.from(configurations.extensionRuntime) + managerFiles.from(configurations.managerRuntime) + destinationDirectory.set( + layout.buildDirectory.dir("extensions") + ) } tasks.register("installDist") {