Skip to content

Commit 8bac78f

Browse files
chore: simplify shadowJar publishing. (#230)
* chore: simplify shadowJar publishing. * chore: simplify project dependency.
1 parent e1d5ea6 commit 8bac78f

File tree

3 files changed

+24
-80
lines changed

3 files changed

+24
-80
lines changed
Lines changed: 22 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
1-
import com.fasterxml.jackson.databind.MapperFeature
2-
import com.fasterxml.jackson.databind.SerializationFeature
3-
import com.fasterxml.jackson.databind.json.JsonMapper
4-
import com.fasterxml.jackson.databind.node.ArrayNode
5-
import com.fasterxml.jackson.databind.node.JsonNodeFactory
6-
import com.fasterxml.jackson.databind.node.ObjectNode
71
import com.vanniktech.maven.publish.JavadocJar.Dokka
82
import com.vanniktech.maven.publish.KotlinJvm
93
import com.vanniktech.maven.publish.MavenPublishBaseExtension
@@ -16,7 +10,7 @@ plugins {
1610
}
1711

1812
dependencies {
19-
// Ignore transtive dependencies and instead manage explicitly.
13+
// Ignore transitive dependencies and instead manage explicitly.
2014
implementation(libs.awsDynamodbLocal) {
2115
isTransitive = false
2216
}
@@ -28,6 +22,7 @@ dependencies {
2822
implementation(libs.kotlinStdLib)
2923

3024
// Shadow dependencies will not be shaded.
25+
// https://gradleup.com/shadow/configuration/#configuring-the-runtime-classpath
3126
shadow(libs.bundles.sqlite4java)
3227
shadow(libs.aws2Dynamodb)
3328
shadow(libs.aws2DynamodbEnhanced)
@@ -39,12 +34,18 @@ dependencies {
3934
shadow(libs.slf4jApi)
4035
}
4136

42-
tasks.named<Jar>("jar") {
37+
tasks.jar {
4338
archiveClassifier.set("unshaded")
4439
}
4540

4641
tasks.shadowJar {
47-
// Dependencies to be shaded must be explicitly included as dependencies.
42+
// https://gradleup.com/shadow/configuration/reproducible-builds/
43+
isPreserveFileTimestamps = false
44+
isReproducibleFileOrder = true
45+
46+
// Explicit allow-list of dependencies to be included. Without this block, _everything_ on runtimeClasspath would be
47+
// included. An alternative would be an explicit deny-list, but this is seen as safer. Engineers should take care to
48+
// update it when they update the dependencies of this project.
4849
dependencies {
4950
include(dependency("com.amazonaws:DynamoDBLocal"))
5051
include(dependency("com.fasterxml.jackson.core:.*"))
@@ -78,82 +79,25 @@ tasks.shadowJar {
7879
archiveClassifier = ""
7980
}
8081

81-
// Override all published JARs to point at the shadow jar
82-
listOf(configurations["apiElements"], configurations["runtimeElements"]).forEach {
83-
it.outgoing {
84-
artifacts.clear()
85-
artifact(tasks.named("shadowJar"))
86-
}
82+
tasks.assemble {
83+
dependsOn(tasks.shadowJar)
8784
}
8885

89-
// Post-process the gradle module metadata JSON to use the shadow JAR's dependencies as the runtime
90-
// dependencies in gradle builds.
91-
tasks.withType<GenerateModuleMetadata>().configureEach {
92-
doLast {
93-
try {
94-
outputFile.get().asFile.takeIf { it.exists() }?.let { moduleFile ->
95-
val mapper = JsonMapper.builder()
96-
.enable(SerializationFeature.INDENT_OUTPUT)
97-
.nodeFactory(JsonNodeFactory.withExactBigDecimals(true))
98-
.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, false)
99-
.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, false)
100-
.build()
101-
val moduleJson = mapper.readTree(moduleFile) as ObjectNode
102-
val variants = moduleJson.get("variants") as ArrayNode
103-
104-
val shadowVariant = variants
105-
.elements().asSequence()
106-
.map { it as ObjectNode }
107-
.find { it.get("name").asText() == "shadowRuntimeElements" }
108-
?: throw NoSuchElementException("could not find the `shadowRuntimeElements` variant!")
109-
110-
val runtimeVariant = variants
111-
.elements().asSequence()
112-
.map { it as ObjectNode }
113-
.find { it.get("name").asText() == "runtimeElements" }
114-
?: throw NoSuchElementException("could not find the `runtimeElements` variant!")
115-
116-
runtimeVariant.replace("dependencies", shadowVariant.get("dependencies"))
117-
118-
moduleFile.writeText(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(moduleJson))
119-
}
120-
} catch (e: Exception) {
121-
throw GradleException("could not post-process the module metadata!", e)
86+
val javaComponent = components["java"] as AdhocComponentWithVariants
87+
listOf("apiElements", "runtimeElements")
88+
.map { configurations[it] }
89+
.forEach { unpublishable ->
90+
// Hide the un-shadowed variants in local consumption, by mangling their attributes
91+
unpublishable.attributes {
92+
attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named("DO_NOT_USE"))
12293
}
94+
95+
// Hide the un-shadowed variants in publishing
96+
javaComponent.withVariantsFromConfiguration(unpublishable) { skip() }
12397
}
124-
}
12598

12699
configure<MavenPublishBaseExtension> {
127100
configure(
128101
KotlinJvm(javadocJar = Dokka("dokkaGfm"))
129102
)
130-
131-
pom {
132-
withXml {
133-
val root = asNode()
134-
135-
// First collect all dependencies nodes.
136-
val dependenciesNodes = root.children()
137-
.filterIsInstance<groovy.util.Node>()
138-
.filter { it.name().toString().contains("dependencies") }
139-
.toList()
140-
141-
// Then remove them safely.
142-
dependenciesNodes.forEach { node ->
143-
root.remove(node)
144-
}
145-
146-
// Add a new dependencies node with shadow configuration.
147-
val dependenciesNode = root.appendNode("dependencies")
148-
149-
// Add all shadow dependencies to the POM.
150-
project.configurations.named("shadow").get().allDependencies.forEach { dep ->
151-
val dependencyNode = dependenciesNode.appendNode("dependency")
152-
dependencyNode.appendNode("groupId", dep.group)
153-
dependencyNode.appendNode("artifactId", dep.name)
154-
dependencyNode.appendNode("version", dep.version)
155-
dependencyNode.appendNode("scope", "compile")
156-
}
157-
}
158-
}
159103
}

tempest-testing-jvm/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ plugins {
1111
dependencies {
1212
api(project(":tempest-testing"))
1313
implementation(project(":tempest-testing-internal"))
14-
implementation(project(path = ":tempest-dynamodb-local", configuration = "shadow"))
14+
implementation(project(":tempest-dynamodb-local"))
1515
implementation(libs.kotlinStdLib)
1616

1717
testImplementation(libs.assertj)

tempest2-testing-jvm/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ plugins {
1111
dependencies {
1212
api(project(":tempest2-testing"))
1313
implementation(project(":tempest2-testing-internal"))
14-
implementation(project(path = ":tempest-dynamodb-local", configuration = "shadow"))
14+
implementation(project(":tempest-dynamodb-local"))
1515
implementation(libs.kotlinStdLib)
1616

1717
testImplementation(libs.assertj)

0 commit comments

Comments
 (0)