|
27 | 27 | package io.spine.gradle.publish |
28 | 28 |
|
29 | 29 | import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar |
| 30 | +import org.gradle.api.file.DuplicatesStrategy |
30 | 31 |
|
31 | 32 | /** |
32 | | - * Calls [ShadowJar.mergeServiceFiles] for the files we use in the Spine SDK. |
| 33 | + * Configures a `ShadowJar` task for Spine SDK publishing. |
33 | 34 | */ |
34 | 35 | @Suppress("unused") |
35 | | -fun ShadowJar.handleMergingServiceFiles() { |
| 36 | +fun ShadowJar.setup() { |
| 37 | + duplicatesStrategy = DuplicatesStrategy.INCLUDE // Required for service-file merging. |
| 38 | + handleMergingServiceFiles() |
| 39 | + deduplicateEntries() |
| 40 | +} |
| 41 | + |
| 42 | +/** |
| 43 | + * Calls [ShadowJar.mergeServiceFiles] for the files we use in the Spine SDK. |
| 44 | + */ |
| 45 | +private fun ShadowJar.handleMergingServiceFiles() { |
36 | 46 | ServiceFiles.all.forEach { |
37 | 47 | append(it) |
38 | 48 | } |
39 | 49 | } |
40 | 50 |
|
| 51 | +/** |
| 52 | + * Installs a first-copy-wins exclusion predicate for all JAR entries except those |
| 53 | + * registered for merging by [handleMergingServiceFiles]. |
| 54 | + * |
| 55 | + * Shadow's [org.gradle.api.file.DuplicatesStrategy.INCLUDE] must remain on the task so |
| 56 | + * that every copy of a merged file reaches its |
| 57 | + * [AppendingTransformer][com.github.jengelman.gradle.plugins.shadow.transformers.AppendingTransformer]. |
| 58 | + * All other entries — `.class` files, settings JSONs, Kotlin module descriptors, |
| 59 | + * Maven metadata, etc. — are deduplicated here to suppress duplicate-entry warnings |
| 60 | + * and keep the fat JAR size minimal. |
| 61 | + */ |
| 62 | +private fun ShadowJar.deduplicateEntries() { |
| 63 | + val mergePaths = ServiceFiles.all |
| 64 | + val seenPaths = mutableSetOf<String>() |
| 65 | + doFirst { seenPaths.clear() } |
| 66 | + eachFile { |
| 67 | + if (path !in mergePaths && !seenPaths.add(path)) { |
| 68 | + exclude() |
| 69 | + } |
| 70 | + } |
| 71 | +} |
| 72 | + |
41 | 73 | @Suppress("ConstPropertyName") |
42 | 74 | private object ServiceFiles { |
43 | 75 |
|
@@ -81,7 +113,7 @@ private object ServiceFiles { |
81 | 113 | private const val eventRoutingSetupClasses = "$routeSetupPrefix.EventRoutingSetup" |
82 | 114 | private const val stateRoutingSetupClasses = "$routeSetupPrefix.StateRoutingSetup" |
83 | 115 |
|
84 | | - val all = arrayOf( |
| 116 | + val all = setOf( |
85 | 117 | descriptorSetReferences, |
86 | 118 | optionProviders, |
87 | 119 | messageValidators, |
|
0 commit comments