From 3361065fe113a3035eac5c46be5b166b3cc4cb28 Mon Sep 17 00:00:00 2001 From: Goooler Date: Wed, 9 Sep 2026 17:38:14 +0800 Subject: [PATCH 1/3] Add functional tests for non-jar exclude and custom r8 args --- .../gradle/plugins/shadow/BasePluginTest.kt | 6 ++++ .../gradle/plugins/shadow/FilteringTest.kt | 23 +++++++++++++++ .../plugins/shadow/R8MinimizationTest.kt | 28 +++++++++++++++++++ .../shadow/util/AppendableMavenRepository.kt | 18 ++++++++++++ 4 files changed, 75 insertions(+) diff --git a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/BasePluginTest.kt b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/BasePluginTest.kt index 4bcd76c31..f830a319d 100644 --- a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/BasePluginTest.kt +++ b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/BasePluginTest.kt @@ -111,6 +111,11 @@ abstract class BasePluginTest { // Circular dependency with e. addDependency(e) } + val g = + jarModule("my", "g", "1.0") { + buildJar { insert("g.properties", "g") } + addDependency(pomModule("my", "pom-dep", "1.0")) + } bomModule("my", "bom", "1.0") { addDependency(a) addDependency(b) @@ -118,6 +123,7 @@ abstract class BasePluginTest { addDependency(d) addDependency(e) addDependency(f) + addDependency(g) } } localRepo.publish() diff --git a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/FilteringTest.kt b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/FilteringTest.kt index 7b7fa5b55..25c137088 100644 --- a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/FilteringTest.kt +++ b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/FilteringTest.kt @@ -237,6 +237,29 @@ class FilteringTest : BasePluginTest() { } } + @Test + fun excludeNonJarTransitiveDependency() { + projectScript.appendText( + """ + |dependencies { + | implementation 'my:g:1.0' + |} + |$shadowJarTask { + | dependencies { + | exclude(dependency('my:pom-dep:.*')) + | } + |} + """ + .trimMargin() + ) + + runWithSuccess(shadowJarPath) + + assertThat(outputShadowedJar).useAll { + containsOnly("g.properties", *entriesInAB, "META-INF/", "META-INF/MANIFEST.MF") + } + } + private fun commonAssertions() { assertThat(outputShadowedJar).useAll { containsOnly("c.properties", *entriesInAB, "META-INF/", "META-INF/MANIFEST.MF") diff --git a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/R8MinimizationTest.kt b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/R8MinimizationTest.kt index 1f88bf4c4..1894896e0 100644 --- a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/R8MinimizationTest.kt +++ b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/R8MinimizationTest.kt @@ -512,6 +512,34 @@ class R8MinimizationTest : BasePluginTest() { assertThat(result.output).contains("R8 launcher JDK ${JavaVersion.current().majorVersion}") } + @Test + fun passCustomR8Args() { + writeR8AppAndLibModules( + appShadowBlock = + """ + |minimize { + | r8 { + | args.addAll(['--map-diagnostics', 'warning', 'info']) + | } + |} + """ + .trimMargin() + ) + + runWithSuccess(appShadowJarPath) + + assertThat(outputAppShadowedJar).useAll { + containsExactly( + // lib/Used.class has been inlined as custom args override default `--no-minification`. + "app/App.class", + "META-INF/MANIFEST.MF", + ) + classLoader { + loadClass("app.App") + } + } + } + @Test fun supportClasspathInR8() { writeR8AppAndLibModules( diff --git a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/AppendableMavenRepository.kt b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/AppendableMavenRepository.kt index a52c30c8e..f4e86a06e 100644 --- a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/AppendableMavenRepository.kt +++ b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/util/AppendableMavenRepository.kt @@ -43,6 +43,17 @@ class AppendableMavenRepository(val root: Path) { return bomModule.coordinate } + fun pomModule( + groupId: String, + artifactId: String, + version: String, + action: PomModule.() -> Unit = {}, + ): String { + val pomModule = PomModule(groupId, artifactId, version).also(action) + modules += pomModule + return pomModule.coordinate + } + fun publish() { check(modules.isNotEmpty()) { "No modules to publish. Please add at least one module." } val writer = MavenXpp3Writer() @@ -68,6 +79,10 @@ class AppendableMavenRepository(val root: Path) { dependencyManagement = DependencyManagement().apply { dependencies = module.dependencies } } + is PomModule -> { + packaging = "pom" + dependencies = module.dependencies + } } } @@ -142,6 +157,9 @@ class AppendableMavenRepository(val root: Path) { class BomModule(groupId: String, artifactId: String, version: String) : Module(groupId, artifactId, version) + + class PomModule(groupId: String, artifactId: String, version: String) : + Module(groupId, artifactId, version) } private val logger = Logging.getLogger(AppendableMavenRepository::class.java) From 5a018f0d07fee73fd19020f137709f64cedce839 Mon Sep 17 00:00:00 2001 From: Zongle Wang Date: Wed, 9 Sep 2026 17:58:33 +0800 Subject: [PATCH 2/3] Modify R8MinimizationTest to disable tree shaking Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../gradle/plugins/shadow/R8MinimizationTest.kt | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/R8MinimizationTest.kt b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/R8MinimizationTest.kt index 1894896e0..962138061 100644 --- a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/R8MinimizationTest.kt +++ b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/R8MinimizationTest.kt @@ -519,7 +519,8 @@ class R8MinimizationTest : BasePluginTest() { """ |minimize { | r8 { - | args.addAll(['--map-diagnostics', 'warning', 'info']) + | // Disable shrinking to prove custom R8 args are passed through. + | args.add("--no-tree-shaking") | } |} """ @@ -529,13 +530,18 @@ class R8MinimizationTest : BasePluginTest() { runWithSuccess(appShadowJarPath) assertThat(outputAppShadowedJar).useAll { - containsExactly( - // lib/Used.class has been inlined as custom args override default `--no-minification`. + containsOnly( "app/App.class", + "lib/Reflective.class", + "lib/Unused.class", + "lib/Used.class", "META-INF/MANIFEST.MF", ) classLoader { loadClass("app.App") + loadClass("lib.Used") + loadClass("lib.Unused") + loadClass("lib.Reflective") } } } From f398ac0313953a6907d872859bc465e935b2d3d2 Mon Sep 17 00:00:00 2001 From: Goooler Date: Wed, 9 Sep 2026 18:02:20 +0800 Subject: [PATCH 3/3] Assert obfuscated classes in passCustomR8Args --- .../gradle/plugins/shadow/R8MinimizationTest.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/R8MinimizationTest.kt b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/R8MinimizationTest.kt index 962138061..e8486419e 100644 --- a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/R8MinimizationTest.kt +++ b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/R8MinimizationTest.kt @@ -531,17 +531,17 @@ class R8MinimizationTest : BasePluginTest() { assertThat(outputAppShadowedJar).useAll { containsOnly( + "a/a.class", + "a/b.class", + "a/c.class", "app/App.class", - "lib/Reflective.class", - "lib/Unused.class", - "lib/Used.class", "META-INF/MANIFEST.MF", ) classLoader { loadClass("app.App") - loadClass("lib.Used") - loadClass("lib.Unused") - loadClass("lib.Reflective") + loadClass("a.a") + loadClass("a.b") + loadClass("a.c") } } }