Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 35 additions & 3 deletions buildSrc/src/main/kotlin/io/spine/gradle/publish/ShadowJarExts.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,49 @@
package io.spine.gradle.publish

import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.gradle.api.file.DuplicatesStrategy

/**
* Calls [ShadowJar.mergeServiceFiles] for the files we use in the Spine SDK.
* Configures a `ShadowJar` task for Spine SDK publishing.
*/
@Suppress("unused")
fun ShadowJar.handleMergingServiceFiles() {
fun ShadowJar.setup() {
duplicatesStrategy = DuplicatesStrategy.INCLUDE // Required for service-file merging.
handleMergingServiceFiles()
deduplicateEntries()
}

/**
* Calls [ShadowJar.mergeServiceFiles] for the files we use in the Spine SDK.
*/
private fun ShadowJar.handleMergingServiceFiles() {
ServiceFiles.all.forEach {
append(it)
}
}

/**
* Installs a first-copy-wins exclusion predicate for all JAR entries except those
* registered for merging by [handleMergingServiceFiles].
*
* Shadow's [org.gradle.api.file.DuplicatesStrategy.INCLUDE] must remain on the task so
* that every copy of a merged file reaches its
* [AppendingTransformer][com.github.jengelman.gradle.plugins.shadow.transformers.AppendingTransformer].
* All other entries — `.class` files, settings JSONs, Kotlin module descriptors,
* Maven metadata, etc. — are deduplicated here to suppress duplicate-entry warnings
* and keep the fat JAR size minimal.
*/
private fun ShadowJar.deduplicateEntries() {
val mergePaths = ServiceFiles.all
val seenPaths = mutableSetOf<String>()
doFirst { seenPaths.clear() }
eachFile {
if (path !in mergePaths && !seenPaths.add(path)) {
exclude()
}
}
}

@Suppress("ConstPropertyName")
private object ServiceFiles {

Expand Down Expand Up @@ -81,7 +113,7 @@ private object ServiceFiles {
private const val eventRoutingSetupClasses = "$routeSetupPrefix.EventRoutingSetup"
private const val stateRoutingSetupClasses = "$routeSetupPrefix.StateRoutingSetup"

val all = arrayOf(
val all = setOf(
descriptorSetReferences,
optionProviders,
messageValidators,
Expand Down
Loading