Skip to content

Commit f36fadf

Browse files
GooolerCopilot
andauthored
Tweak manifest attribute tests (#1786)
* Replace `isGreaterThan` with `isEqualTo` * Replace `manifest.attribute` calls * Revert "Replace `manifest.attribute` calls" This reverts commit 727403d. * Replace `manifest.from` calls * Unit test `inheritManifestAttrsFromJars` * Unit test `inheritManifestMainClassFromJar` * Simplify `DefaultInheritManifest` * Document more about `Configuring the JAR Manifest` * Update docs/configuration/README.md --------- Co-authored-by: Copilot <[email protected]>
1 parent 21f2613 commit f36fadf

File tree

4 files changed

+60
-86
lines changed

4 files changed

+60
-86
lines changed

docs/configuration/README.md

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -91,17 +91,15 @@ When deploying a shadowed JAR as an execution JAR, it is important to note that
9191

9292
## Configuring the JAR Manifest
9393

94-
Beyond the automatic configuration of the `Class-Path` entry, the [`ShadowJar`][ShadowJar] manifest is configured in a
95-
number of ways. First, the manifest for the [`ShadowJar`][ShadowJar] task is configured to __inherit__ from the
96-
manifest of the standard [`Jar`][Jar] task. This means that any configuration performed on the [`Jar`][Jar] task
97-
will propagate to the [`ShadowJar`][ShadowJar] tasks.
94+
The [`ShadowJar`][ShadowJar] manifest is configured in a number of ways. First, the manifest for the `shadowJar` task
95+
is configured to __inherit__ from the manifest of the standard `jar` task.
9896

9997
=== "Kotlin"
10098

10199
```kotlin
102100
tasks.jar {
103101
manifest {
104-
attributes["Class-Path"] = "/libs/foo.jar"
102+
attributes["Main-Class"] = "my.Main"
105103
}
106104
}
107105
```
@@ -111,19 +109,19 @@ will propagate to the [`ShadowJar`][ShadowJar] tasks.
111109
```groovy
112110
tasks.named('jar', Jar) {
113111
manifest {
114-
attributes 'Class-Path': '/libs/foo.jar'
112+
attributes 'Main-Class': 'my.Main'
115113
}
116114
}
117115
```
118116

119-
Inspecting the `META-INF/MANIFEST.MF` entry in the JAR file will reveal the following attribute:
117+
Inspecting the `META-INF/MANIFEST.MF` entry in the JAR files will reveal the following attribute:
120118

121119
```property
122-
Class-Path: /libs/foo.jar
120+
Main-Class: my.Main
123121
```
124122

125-
If it is desired to inherit a manifest from a JAR task other than the standard [`Jar`][Jar] task, the `from`
126-
methods on the `shadowJar.manifest` object can be used to configure the upstream.
123+
If it is desired to merge a manifest from another [`Jar`][Jar] task, the `manifest.from` methods can be used to
124+
configure the upstream.
127125

128126
=== "Kotlin"
129127

@@ -149,7 +147,7 @@ methods on the `shadowJar.manifest` object can be used to configure the upstream
149147
}
150148

151149
tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
152-
manifest.from(testJar.get().manifest)
150+
manifest.from testJar.get().manifest
153151
}
154152
```
155153

src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/JavaPluginsTest.kt

Lines changed: 1 addition & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import assertk.assertions.contains
66
import assertk.assertions.containsMatch
77
import assertk.assertions.doesNotContain
88
import assertk.assertions.isEqualTo
9-
import assertk.assertions.isGreaterThan
109
import assertk.assertions.isNotEmpty
1110
import assertk.assertions.isNotEqualTo
1211
import assertk.assertions.isNotNull
@@ -512,7 +511,7 @@ class JavaPluginsTest : BasePluginTest() {
512511
assertThat(outputShadowedJar).useAll {
513512
transform { actual -> actual.entries().toList().map { it.name }.filter { it.endsWith(".class") } }
514513
.single().isEqualTo("my/plugin/MyPlugin.class")
515-
transform { it.mainAttrSize }.isGreaterThan(0)
514+
transform { it.mainAttrSize }.isEqualTo(1)
516515
// Doesn't contain Gradle classes.
517516
getMainAttr(classPathAttributeKey).isNull()
518517

@@ -687,61 +686,6 @@ class JavaPluginsTest : BasePluginTest() {
687686
)
688687
}
689688

690-
@Test
691-
fun inheritManifestAttrsFromJars() {
692-
projectScript.appendText(
693-
"""
694-
$jarTask {
695-
manifest {
696-
attributes 'Foo-Attr': 'Foo-Value'
697-
}
698-
}
699-
def testJar = tasks.register('testJar', Jar) {
700-
manifest {
701-
attributes 'Bar-Attr': 'Bar-Value'
702-
}
703-
}
704-
$shadowJarTask {
705-
manifest.from(testJar.get().manifest)
706-
}
707-
""".trimIndent(),
708-
)
709-
710-
run(shadowJarPath)
711-
712-
assertThat(outputShadowedJar).useAll {
713-
transform { it.mainAttrSize }.isGreaterThan(2)
714-
getMainAttr("Foo-Attr").isEqualTo("Foo-Value")
715-
getMainAttr("Bar-Attr").isEqualTo("Bar-Value")
716-
}
717-
}
718-
719-
@Test
720-
fun inheritManifestMainClassFromJar() {
721-
projectScript.appendText(
722-
"""
723-
$jarTask {
724-
manifest {
725-
attributes '$mainClassAttributeKey': 'my.Main'
726-
}
727-
}
728-
$shadowJarTask {
729-
mainClass = 'my.Main2' // This should not override the inherited one.
730-
}
731-
""".trimIndent(),
732-
)
733-
734-
val result = run(shadowJarPath, infoArgument)
735-
736-
assertThat(result.output).contains(
737-
"Skipping adding $mainClassAttributeKey attribute to the manifest as it is already set.",
738-
)
739-
assertThat(outputShadowedJar).useAll {
740-
transform { it.mainAttrSize }.isGreaterThan(1)
741-
getMainAttr("Main-Class").isEqualTo("my.Main")
742-
}
743-
}
744-
745689
@Test
746690
fun addExtraFilesViaFrom() {
747691
val mainClassEntry = writeClass()

src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/DefaultInheritManifest.kt

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import org.gradle.api.internal.project.DefaultProject
1010
import org.gradle.api.java.archives.Manifest
1111
import org.gradle.api.java.archives.ManifestMergeSpec
1212
import org.gradle.api.java.archives.internal.DefaultManifest
13-
import org.gradle.api.java.archives.internal.DefaultManifestMergeSpec
1413

1514
internal class DefaultInheritManifest(
1615
project: Project,
@@ -21,28 +20,13 @@ internal class DefaultInheritManifest(
2120
private val internalManifest: Manifest = manifest ?: DefaultManifest(fileResolver),
2221
) : InheritManifest,
2322
Manifest by internalManifest {
24-
private val inheritMergeSpecs = mutableListOf<DefaultManifestMergeSpec>()
2523

2624
override fun inheritFrom(
2725
vararg inheritPaths: Any,
2826
action: Action<ManifestMergeSpec>,
2927
) {
30-
val mergeSpec = DefaultManifestMergeSpec()
31-
mergeSpec.from(*inheritPaths)
32-
inheritMergeSpecs.add(mergeSpec)
33-
action.execute(mergeSpec)
34-
}
35-
36-
override fun getEffectiveManifest(): DefaultManifest {
37-
var base = DefaultManifest(fileResolver)
38-
inheritMergeSpecs.forEach {
39-
base = it.merge(base, fileResolver)
28+
inheritPaths.forEach {
29+
from(it, action)
4030
}
41-
base.from(internalManifest)
42-
return base.effectiveManifest
43-
}
44-
45-
override fun writeTo(path: Any): Manifest = apply {
46-
effectiveManifest.writeTo(path)
4731
}
4832
}

src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/ShadowPropertiesTest.kt

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import com.github.jengelman.gradle.plugins.shadow.ShadowBasePlugin.Companion.sha
1818
import com.github.jengelman.gradle.plugins.shadow.internal.applicationExtension
1919
import com.github.jengelman.gradle.plugins.shadow.internal.javaPluginExtension
2020
import com.github.jengelman.gradle.plugins.shadow.internal.javaToolchainService
21+
import com.github.jengelman.gradle.plugins.shadow.internal.mainClassAttributeKey
2122
import com.github.jengelman.gradle.plugins.shadow.internal.runtimeConfiguration
2223
import com.github.jengelman.gradle.plugins.shadow.legacy.LegacyShadowPlugin
2324
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar.Companion.SHADOW_JAR_TASK_NAME
@@ -31,6 +32,8 @@ import org.gradle.api.plugins.ApplicationPlugin
3132
import org.gradle.api.plugins.JavaPlugin
3233
import org.gradle.api.plugins.JavaPlugin.API_CONFIGURATION_NAME
3334
import org.gradle.api.plugins.JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME
35+
import org.gradle.api.tasks.TaskContainer
36+
import org.gradle.api.tasks.TaskProvider
3437
import org.gradle.api.tasks.bundling.AbstractArchiveTask
3538
import org.gradle.api.tasks.bundling.Jar
3639
import org.gradle.language.base.plugins.LifecycleBasePlugin
@@ -64,6 +67,49 @@ class ShadowPropertiesTest {
6467
}
6568
}
6669

70+
@Test
71+
fun inheritManifestAttrsFromJars() = with(project) {
72+
plugins.apply(JavaPlugin::class.java)
73+
tasks.jar.configure {
74+
it.manifest.attributes["jar"] = "fromJar"
75+
}
76+
val jar1 = tasks.register("jar1", Jar::class.java) {
77+
it.manifest.attributes["jar1"] = "fromJar1"
78+
}
79+
val jar2 = tasks.register("jar2", Jar::class.java) {
80+
it.manifest.attributes["jar2"] = "fromJar2"
81+
}
82+
tasks.shadowJar.configure {
83+
it.manifest.attributes["shadowJar"] = "fromShadowJar"
84+
it.manifest.from(jar1.get().manifest)
85+
@Suppress("DEPRECATION") // TODO: remove this once InheritManifest is removed.
86+
it.manifest.inheritFrom(jar2.get().manifest)
87+
}
88+
// Call effectiveManifest as a way to force merging to happen like writing the jar would.
89+
assertThat(tasks.shadowJar.get().manifest.effectiveManifest.attributes).containsOnly(
90+
"Manifest-Version" to "1.0",
91+
"jar" to "fromJar",
92+
"jar1" to "fromJar1",
93+
"jar2" to "fromJar2",
94+
"shadowJar" to "fromShadowJar",
95+
)
96+
}
97+
98+
@Test
99+
fun inheritManifestMainClassFromJar() = with(project) {
100+
plugins.apply(JavaPlugin::class.java)
101+
tasks.jar.configure {
102+
it.manifest.attributes[mainClassAttributeKey] = "Main"
103+
}
104+
tasks.shadowJar.configure {
105+
it.mainClass.set("Main2") // This should not override the inherited one from jar.
106+
}
107+
assertThat(tasks.shadowJar.get().manifest.attributes).containsOnly(
108+
"Manifest-Version" to "1.0",
109+
mainClassAttributeKey to "Main",
110+
)
111+
}
112+
67113
@Test
68114
fun applyJavaPlugin() = with(project) {
69115
plugins.apply(JavaPlugin::class.java)
@@ -207,5 +253,7 @@ class ShadowPropertiesTest {
207253
const val VERSION = "1.0.0"
208254

209255
val Task.dependsOnTaskNames: List<String> get() = dependsOn.filterIsInstance<Named>().map(Named::getName)
256+
257+
val TaskContainer.jar: TaskProvider<Jar> get() = named("jar", Jar::class.java)
210258
}
211259
}

0 commit comments

Comments
 (0)