Repository: GradleUp/shadow
Pull request #1536 (2025-07-23 01:54:17)

Minor tweaks


Patch:
diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/GradleCompat.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/GradleCompat.kt
index 170668b2..262b95ab 100644
--- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/GradleCompat.kt
+++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/GradleCompat.kt
@@ -22,10 +22,8 @@ import org.gradle.jvm.toolchain.JavaToolchainService
  * Return `runtimeClasspath` or `runtime` configuration.
  */
 internal inline val Project.runtimeConfiguration: Configuration
-  get() {
-    return configurations.findByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME)
-      ?: configurations.getByName("runtime")
-  }
+  get() = configurations.findByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME)
+    ?: configurations.getByName("runtime")
 
 internal inline val Project.sourceSets: SourceSetContainer
   get() = extensions.getByType(SourceSetContainer::class.java)
diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt
index 42c0e69d..d362996b 100644
--- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt
+++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/RelocatorRemapper.kt
@@ -49,6 +49,6 @@ internal class RelocatorRemapper(
   }
 
   fun mapPath(path: String): String {
-    return map(path.substring(0, path.indexOf('.')))
+    return map(path.substringBefore('.'))
   }
 }
diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocator.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocator.kt
index c5ee0e43..ad2d7d0e 100644
--- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocator.kt
+++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocator.kt
@@ -212,7 +212,7 @@ public open class SimpleRelocator @JvmOverloads constructor(
         // Actually, class patterns should just use 'foo.bar.*' ending with a single asterisk, but some users
         // mistake them for path patterns like 'my/path/**', so let us be a bit more lenient here.
         if (filePattern.endsWith("/*") || filePattern.endsWith("/**")) {
-          val packagePattern = filePattern.substring(0, filePattern.lastIndexOf('/'))
+          val packagePattern = filePattern.take(filePattern.lastIndexOf('/'))
           add(packagePattern)
         }
       }
diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction.kt
index 9eb262ff..c498e9e8 100644
--- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction.kt
+++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction.kt
@@ -87,9 +87,6 @@ public open class ShadowCopyAction(
     }
   }
 
-  /**
-   * Handles cases like [issue 53](https://github.com/GradleUp/shadow/issues/53).
-   */
   private fun addDirs(zos: ZipOutputStream) {
     @Suppress("UNCHECKED_CAST")
     val entries = zos::class.java.getDeclaredField("entries").apply { isAccessible = true }
@@ -173,8 +170,6 @@ public open class ShadowCopyAction(
     /**
      * Applies remapping to the given class with the specified relocation path. The remapped class is then written
      * to the zip file.
-     *
-     * See [issue 364](https://github.com/GradleUp/shadow/issues/364) and [issue 408](https://github.com/GradleUp/shadow/issues/408).
      */
     private fun FileCopyDetails.remapClass() = file.inputStream().use { inputStream ->
       // We don't pass the ClassReader here. This forces the ClassWriter to rebuild the constant pool.
diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/AppendingTransformer.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/AppendingTransformer.kt
index 878e44ab..5fda7760 100644
--- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/AppendingTransformer.kt
+++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/AppendingTransformer.kt
@@ -19,14 +19,11 @@ import org.gradle.api.tasks.Optional
  * @author John Engelman
  */
 @CacheableTransformer
-@Suppress("ktlint:standard:backing-property-naming")
 public open class AppendingTransformer @Inject constructor(
   final override val objectFactory: ObjectFactory,
 ) : ResourceTransformer {
-  /**
-   * Defer initialization, see [issue 763](https://github.com/GradleUp/shadow/issues/763).
-   */
-  private var _data: ByteArrayOutputStream? = null
+  @Suppress("ktlint:standard:backing-property-naming")
+  private var _data: ByteArrayOutputStream? = null // It's nullable to allow lazy initialization to support CC.
   private inline val data get() = _data ?: ByteArrayOutputStream().also { _data = it }
 
   @get:Optional
@@ -41,23 +38,24 @@ public open class AppendingTransformer @Inject constructor(
   }
 
   override fun transform(context: TransformerContext) {
-    if (data.size() > 0) {
-      // Append the separator before the new content to ensure the separator is not at the end of the file.
-      data.write(separator.get().toByteArray())
+    data.let {
+      if (it.size() > 0) {
+        // Append the separator before the new content to ensure the separator is not at the end of the file.
+        it.write(separator.get().toByteArray())
+      }
+      context.inputStream.copyTo(it)
     }
-    context.inputStream.copyTo(data)
   }
 
-  override fun hasTransformedResource(): Boolean {
-    return data.size() > 0
-  }
+  override fun hasTransformedResource(): Boolean = data.size() > 0
 
   override fun modifyOutputStream(os: ZipOutputStream, preserveFileTimestamps: Boolean) {
     os.putNextEntry(zipEntry(resource.get(), preserveFileTimestamps))
-
-    // Closing a ByteArrayOutputStream has no effect, so we don't use a use block here.
-    data.toByteArray().inputStream().copyTo(os)
-    data.reset()
+    data.let {
+      // Closing a ByteArrayOutputStream has no effect, so we don't use a use block here.
+      it.toByteArray().inputStream().copyTo(os)
+      it.reset()
+    }
   }
 
   public companion object {
diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ComponentsXmlResourceTransformer.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ComponentsXmlResourceTransformer.kt
index ab9503b6..0fb0428a 100644
--- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ComponentsXmlResourceTransformer.kt
+++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ComponentsXmlResourceTransformer.kt
@@ -25,6 +25,22 @@ import org.gradle.api.tasks.Internal
 public open class ComponentsXmlResourceTransformer : ResourceTransformer {
   private val components = mutableMapOf<String, Xpp3Dom>()
 
+  @get:Internal
+  internal val transformedResource: ByteArray
+    get() {
+      val os = ByteArrayOutputStream(1024 * 4)
+      XmlStreamWriter(os).use { writer ->
+        val dom = Xpp3Dom("component-set")
+        val componentDom = Xpp3Dom("components")
+        dom.addChild(componentDom)
+        for (component in components.values) {
+          componentDom.addChild(component)
+        }
+        Xpp3DomWriter.write(writer, dom)
+      }
+      return os.toByteArray()
+    }
+
   override fun canTransformResource(element: FileTreeElement): Boolean {
     return COMPONENTS_XML_PATH == element.path
   }
@@ -85,22 +101,6 @@ public open class ComponentsXmlResourceTransformer : ResourceTransformer {
 
   override fun hasTransformedResource(): Boolean = components.isNotEmpty()
 
-  @get:Internal
-  internal val transformedResource: ByteArray
-    get() {
-      val os = ByteArrayOutputStream(1024 * 4)
-      XmlStreamWriter(os).use { writer ->
-        val dom = Xpp3Dom("component-set")
-        val componentDom = Xpp3Dom("components")
-        dom.addChild(componentDom)
-        for (component in components.values) {
-          componentDom.addChild(component)
-        }
-        Xpp3DomWriter.write(writer, dom)
-      }
-      return os.toByteArray()
-    }
-
   public companion object {
     public const val COMPONENTS_XML_PATH: String = "META-INF/plexus/components.xml"
 
diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/GroovyExtensionModuleTransformer.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/GroovyExtensionModuleTransformer.kt
index f34a1c38..887e485f 100644
--- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/GroovyExtensionModuleTransformer.kt
+++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/GroovyExtensionModuleTransformer.kt
@@ -46,6 +46,7 @@ public open class GroovyExtensionModuleTransformer : ResourceTransformer {
   override fun transform(context: TransformerContext) {
     val props = Properties()
     props.load(context.inputStream)
+    @Suppress("JavaMapForEach")
     props.forEach { key, value ->
       when (key as String) {
         KEY_MODULE_NAME -> handle(key, value as String) {
diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/Log4j2PluginsCacheFileTransformer.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/Log4j2PluginsCacheFileTransformer.kt
index 8f78196c..cc2a25bf 100644
--- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/Log4j2PluginsCacheFileTransformer.kt
+++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/Log4j2PluginsCacheFileTransformer.kt
@@ -48,9 +48,7 @@ public open class Log4j2PluginsCacheFileTransformer : ResourceTransformer {
   /**
    * @return `true` if any dat file collected.
    */
-  override fun hasTransformedResource(): Boolean {
-    return tempFiles.isNotEmpty()
-  }
+  override fun hasTransformedResource(): Boolean = tempFiles.isNotEmpty()
 
   override fun modifyOutputStream(os: ZipOutputStream, preserveFileTimestamps: Boolean) {
     try {
diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformer.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformer.kt
index 4f331a0c..aed3c054 100644
--- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformer.kt
+++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/PropertiesFileTransformer.kt
@@ -212,9 +212,7 @@ public open class PropertiesFileTransformer @Inject constructor(
     return mergeSeparator
   }
 
-  override fun hasTransformedResource(): Boolean {
-    return propertiesEntries.isNotEmpty()
-  }
+  override fun hasTransformedResource(): Boolean = propertiesEntries.isNotEmpty()
 
   override fun modifyOutputStream(os: ZipOutputStream, preserveFileTimestamps: Boolean) {
     // Cannot close the writer as the OutputStream needs to remain open.


Test patch:
diff --git a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/PublishingTest.kt b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/PublishingTest.kt
index 79570aa1..cfdff411 100644
--- a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/PublishingTest.kt
+++ b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/PublishingTest.kt
@@ -65,8 +65,7 @@ class PublishingTest : BasePluginTest() {
           archiveClassifier = ''
           archiveBaseName = 'maven-all'
         """.trimIndent(),
-      ) +
-        System.lineSeparator(),
+      ) + System.lineSeparator(),
     )
 
     publish()
@@ -555,11 +554,10 @@ class PublishingTest : BasePluginTest() {
       TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE.name to JavaVersion.current().majorVersion,
     )
 
-    val shadowVariantAttrs = commonVariantAttrs +
-      arrayOf(
-        Bundling.BUNDLING_ATTRIBUTE.name to Bundling.SHADOWED,
-        Usage.USAGE_ATTRIBUTE.name to Usage.JAVA_RUNTIME,
-      )
+    val shadowVariantAttrs = commonVariantAttrs + arrayOf(
+      Bundling.BUNDLING_ATTRIBUTE.name to Bundling.SHADOWED,
+      Usage.USAGE_ATTRIBUTE.name to Usage.JAVA_RUNTIME,
+    )
 
     fun MavenXpp3Reader.read(path: Path): Model = path.inputStream().use { read(it) }
 
diff --git a/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocatorTest.kt b/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocatorTest.kt
index 4141b675..f6cf39a5 100644
--- a/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocatorTest.kt
+++ b/src/test/kotlin/com/github/jengelman/gradle/plugins/shadow/relocation/SimpleRelocatorTest.kt
@@ -80,7 +80,7 @@ class SimpleRelocatorTest {
     // Include with Regex
     var relocator = SimpleRelocator(
       "org.foo",
-      includes = listOf("%regex[org/foo/R(\\\$.*)?\$]"),
+      includes = listOf("%regex[org/foo/R(\\$.*)?$]"),
     )
     assertThat(relocator.canRelocatePath("org/foo/R.class")).isTrue()
     assertThat(relocator.canRelocatePath("org/foo/R\$string.class")).isTrue()
@@ -148,7 +148,7 @@ class SimpleRelocatorTest {
     var relocator = SimpleRelocator("org/foo", rawString = true)
     assertThat(relocator.canRelocatePath("(I)org/foo/bar/Class;")).isTrue()
 
-    relocator = SimpleRelocator("^META-INF/org.foo.xml\$", rawString = true)
+    relocator = SimpleRelocator("^META-INF/org.foo.xml$", rawString = true)
     assertThat(relocator.canRelocatePath("META-INF/org.foo.xml")).isTrue()
   }
 
@@ -216,7 +216,7 @@ class SimpleRelocatorTest {
     assertThat(relocator.relocatePath("(I)Lorg/foo/bar/Class;"))
       .isEqualTo("(I)Lhidden/org/foo/bar/Class;")
 
-    relocator = SimpleRelocator("^META-INF/org.foo.xml\$", "META-INF/hidden.org.foo.xml", rawString = true)
+    relocator = SimpleRelocator("^META-INF/org.foo.xml$", "META-INF/hidden.org.foo.xml", rawString = true)
     assertThat(relocator.relocatePath("META-INF/org.foo.xml"))
       .isEqualTo("META-INF/hidden.org.foo.xml")
   }
@@ -243,7 +243,7 @@ class SimpleRelocatorTest {
       excludes = listOf("org/apache/iceberg/spark/parquet/**", "org/apache/spark/sql/execution/datasources/parquet/**"),
     )
     assertThat(relocator.canRelocatePath("org/apache/iceberg/spark/parquet/SparkNativeParquet.class")).isFalse()
-    assertThat(relocator.canRelocatePath("org/apache/iceberg/spark/parquet/SparkNativeParquet\$.class")).isFalse()
+    assertThat(relocator.canRelocatePath("org/apache/iceberg/spark/parquet/SparkNativeParquet$.class")).isFalse()
     assertThat(relocator.canRelocatePath("org/apache/spark/sql/execution/datasources/parquet/v1.class")).isFalse()
     assertThat(relocator.canRelocatePath("org/foo/Class.class")).isTrue()
   }
@@ -255,7 +255,7 @@ class SimpleRelocatorTest {
       excludes = listOf("%regex[org/apache/iceberg/.*]", "%regex[org/apache/spark/.*]"),
     )
     assertThat(relocator.canRelocatePath("org/apache/iceberg/spark/parquet/SparkNativeParquet.class")).isFalse()
-    assertThat(relocator.canRelocatePath("org/apache/iceberg/spark/parquet/SparkNativeParquet\$.class")).isFalse()
+    assertThat(relocator.canRelocatePath("org/apache/iceberg/spark/parquet/SparkNativeParquet$.class")).isFalse()
     assertThat(relocator.canRelocatePath("org/apache/spark/sql/execution/datasources/parquet/v1.class")).isFalse()
     assertThat(relocator.canRelocatePath("org/foo/Class.class")).isTrue()
   }
@@ -266,7 +266,7 @@ class SimpleRelocatorTest {
       includes = listOf("org/apache/iceberg/spark/parquet/**", "org/apache/spark/sql/execution/datasources/parquet/**"),
     )
     assertThat(relocator.canRelocatePath("org/apache/iceberg/spark/parquet/SparkNativeParquet.class")).isTrue()
-    assertThat(relocator.canRelocatePath("org/apache/iceberg/spark/parquet/SparkNativeParquet\$.class")).isTrue()
+    assertThat(relocator.canRelocatePath("org/apache/iceberg/spark/parquet/SparkNativeParquet$.class")).isTrue()
     assertThat(relocator.canRelocatePath("org/apache/spark/sql/execution/datasources/parquet/v1.class")).isTrue()
     assertThat(relocator.canRelocatePath("org/foo/Class.class")).isFalse()
   }
@@ -277,7 +277,7 @@ class SimpleRelocatorTest {
       includes = listOf("%regex[org/apache/iceberg/.*]", "%regex[org/apache/spark/.*]"),
     )
     assertThat(relocator.canRelocatePath("org/apache/iceberg/spark/parquet/SparkNativeParquet.class")).isTrue()
-    assertThat(relocator.canRelocatePath("org/apache/iceberg/spark/parquet/SparkNativeParquet\$.class")).isTrue()
+    assertThat(relocator.canRelocatePath("org/apache/iceberg/spark/parquet/SparkNativeParquet$.class")).isTrue()
     assertThat(relocator.canRelocatePath("org/apache/spark/sql/execution/datasources/parquet/v1.class")).isTrue()
     assertThat(relocator.canRelocatePath("org/foo/Class.class")).isFalse()
   }