Skip to content

Commit da34a3e

Browse files
authored
Refactor file visiting logic in StreamAction (#1233)
* Remove ShadowJar.rootPatternSet Seems it's unused now. * Test `duplicatesStrategyFailShouldFailBuildForDuplicatedEntries` * Convert the resolution result to ZipTree * Cleanups * Reduce RelativeArchivePath and ArchiveFileTreeElement * Defer includedZipTrees * Fix `failBuildIfProcessingBadJar` * Cleanups * Remove recordVisit * Test more strategies in ServiceFileTransformerTest * Test `shadowJarIsCachedCorrectlyAfterDuplicatesStrategyChanged` * Update baseline * Refactor and simplify visitFile * Show how to add extra files into shadowed jars * Unify from and into orders * Update changelog * Remove TODO for `injectMultiReleaseAttrIfPresent` * Fix merge * Merge `RealStreamAction` back into `ShadowCopyAction` * Cleanups * Adjust ShadowCopyAction ctor * Seems we have no need to close context.inputStream in transformers * Fix `canAddExtraFilesIntoShadowJar` * Mark `withDebug` for testing * Revert "Mark `withDebug` for testing" This reverts commit ec3df52. * Cleanups * Drop `ZipCompressor` * Drop `rootPatternSet` property * Shorten obtaining relative paths > Returns the path of this file, relative to the root of the containing file tree. Always uses '/' as the hierarchy separator, regardless of platform file separator. Same as calling getRelativePath().getPathString(). * Fix merge * Fix merge * Cleanups * Add dir entries in the last
1 parent 46f6b36 commit da34a3e

28 files changed

+334
-511
lines changed

api/shadow.api

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,6 @@ public abstract class com/github/jengelman/gradle/plugins/shadow/ShadowPlugin :
6464
public fun apply (Lorg/gradle/api/Project;)V
6565
}
6666

67-
public abstract interface class com/github/jengelman/gradle/plugins/shadow/internal/ZipCompressor {
68-
public abstract fun createArchiveOutputStream (Ljava/io/File;)Lorg/apache/tools/zip/ZipOutputStream;
69-
}
70-
7167
public abstract class com/github/jengelman/gradle/plugins/shadow/legacy/LegacyShadowPlugin : org/gradle/api/Plugin {
7268
public fun <init> ()V
7369
public synthetic fun apply (Ljava/lang/Object;)V
@@ -175,45 +171,14 @@ public abstract interface class com/github/jengelman/gradle/plugins/shadow/tasks
175171

176172
public class com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction : org/gradle/api/internal/file/copy/CopyAction {
177173
public static final field Companion Lcom/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction$Companion;
178-
public fun <init> (Ljava/io/File;Lcom/github/jengelman/gradle/plugins/shadow/internal/ZipCompressor;Lorg/gradle/api/internal/DocumentationRegistry;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;Lorg/gradle/api/tasks/util/PatternSet;ZLjava/util/Set;)V
174+
public fun <init> (Ljava/io/File;Lkotlin/jvm/functions/Function1;Lorg/gradle/api/internal/DocumentationRegistry;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;ZLjava/lang/String;)V
179175
public fun execute (Lorg/gradle/api/internal/file/copy/CopyActionProcessingStream;)Lorg/gradle/api/tasks/WorkResult;
180176
}
181177

182-
public class com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction$ArchiveFileTreeElement : org/gradle/api/file/FileTreeElement {
183-
public fun <init> (Lcom/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction$RelativeArchivePath;)V
184-
public fun asFileTreeElement ()Lorg/gradle/api/file/FileTreeElement;
185-
public fun copyTo (Ljava/io/File;)Z
186-
public fun copyTo (Ljava/io/OutputStream;)V
187-
public fun getFile ()Ljava/io/File;
188-
public fun getLastModified ()J
189-
public fun getMode ()I
190-
public fun getName ()Ljava/lang/String;
191-
public fun getPath ()Ljava/lang/String;
192-
public fun getPermissions ()Lorg/gradle/api/file/FilePermissions;
193-
public fun getRelativePath ()Lcom/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction$RelativeArchivePath;
194-
public synthetic fun getRelativePath ()Lorg/gradle/api/file/RelativePath;
195-
public fun getSize ()J
196-
public fun isClass ()Z
197-
public fun isDirectory ()Z
198-
public fun open ()Ljava/io/InputStream;
199-
}
200-
201178
public final class com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction$Companion {
202179
public final fun getCONSTANT_TIME_FOR_ZIP_ENTRIES ()J
203180
}
204181

205-
public class com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction$RelativeArchivePath : org/gradle/api/file/RelativePath {
206-
public fun <init> (Lorg/apache/tools/zip/ZipEntry;Z)V
207-
public final fun charAt (I)C
208-
public fun get (I)C
209-
public fun getEntry ()Lorg/apache/tools/zip/ZipEntry;
210-
public fun getLength ()I
211-
public fun getParent ()Lcom/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction$RelativeArchivePath;
212-
public synthetic fun getParent ()Lorg/gradle/api/file/RelativePath;
213-
public fun isClass ()Z
214-
public final fun length ()I
215-
}
216-
217182
public abstract class com/github/jengelman/gradle/plugins/shadow/tasks/ShadowJar : org/gradle/api/tasks/bundling/Jar, com/github/jengelman/gradle/plugins/shadow/tasks/ShadowSpec {
218183
public fun <init> ()V
219184
public fun append (Ljava/lang/String;)Lcom/github/jengelman/gradle/plugins/shadow/tasks/ShadowJar;
@@ -231,13 +196,11 @@ public abstract class com/github/jengelman/gradle/plugins/shadow/tasks/ShadowJar
231196
public fun getExcludes ()Ljava/util/Set;
232197
public fun getIncludedDependencies ()Lorg/gradle/api/file/ConfigurableFileCollection;
233198
public fun getIncludes ()Ljava/util/Set;
234-
protected fun getInternalCompressor ()Lcom/github/jengelman/gradle/plugins/shadow/internal/ZipCompressor;
235199
public fun getManifest ()Lcom/github/jengelman/gradle/plugins/shadow/tasks/InheritManifest;
236200
public synthetic fun getManifest ()Lorg/gradle/api/java/archives/Manifest;
237201
public fun getMinimizeJar ()Lorg/gradle/api/provider/Property;
238202
public fun getRelocationPrefix ()Lorg/gradle/api/provider/Property;
239203
public fun getRelocators ()Lorg/gradle/api/provider/SetProperty;
240-
protected fun getRootPatternSet ()Lorg/gradle/api/tasks/util/PatternSet;
241204
public fun getSourceSetsClassesDirs ()Lorg/gradle/api/file/ConfigurableFileCollection;
242205
public fun getToMinimize ()Lorg/gradle/api/file/ConfigurableFileCollection;
243206
public fun getTransformers ()Lorg/gradle/api/provider/SetProperty;

lint-baseline.xml

Lines changed: 8 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
4242
<location
4343
file="src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction.kt"
44-
line="26"
44+
line="17"
4545
column="1"/>
4646
</issue>
4747

@@ -52,18 +52,7 @@
5252
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
5353
<location
5454
file="src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction.kt"
55-
line="27"
56-
column="1"/>
57-
</issue>
58-
59-
<issue
60-
id="InternalGradleApiUsage"
61-
message="Avoid using internal Gradle APIs"
62-
errorLine1="import org.gradle.api.internal.file.DefaultFilePermissions"
63-
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
64-
<location
65-
file="src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction.kt"
66-
line="28"
55+
line="18"
6756
column="1"/>
6857
</issue>
6958

@@ -74,7 +63,7 @@
7463
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
7564
<location
7665
file="src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction.kt"
77-
line="29"
66+
line="19"
7867
column="1"/>
7968
</issue>
8069

@@ -85,7 +74,7 @@
8574
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
8675
<location
8776
file="src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction.kt"
88-
line="30"
77+
line="20"
8978
column="1"/>
9079
</issue>
9180

@@ -96,7 +85,7 @@
9685
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
9786
<location
9887
file="src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowCopyAction.kt"
99-
line="31"
88+
line="21"
10089
column="1"/>
10190
</issue>
10291

@@ -107,7 +96,7 @@
10796
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
10897
<location
10998
file="src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowJar.kt"
110-
line="34"
99+
line="33"
111100
column="1"/>
112101
</issue>
113102

@@ -118,7 +107,7 @@
118107
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
119108
<location
120109
file="src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowJar.kt"
121-
line="35"
110+
line="34"
122111
column="1"/>
123112
</issue>
124113

@@ -129,62 +118,7 @@
129118
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
130119
<location
131120
file="src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowJar.kt"
132-
line="36"
133-
column="1"/>
134-
</issue>
135-
136-
<issue
137-
id="InternalGradleApiUsage"
138-
message="Avoid using internal Gradle APIs"
139-
errorLine1="import org.gradle.api.internal.file.copy.DefaultCopySpec"
140-
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
141-
<location
142-
file="src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowJar.kt"
143-
line="37"
144-
column="1"/>
145-
</issue>
146-
147-
<issue
148-
id="InternalGradleApiUsage"
149-
message="Avoid using internal Gradle APIs"
150-
errorLine1="import org.gradle.api.internal.file.DefaultFileTreeElement"
151-
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
152-
<location
153-
file="src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/Utils.kt"
154-
line="16"
155-
column="1"/>
156-
</issue>
157-
158-
<issue
159-
id="InternalGradleApiUsage"
160-
message="Avoid using internal Gradle APIs"
161-
errorLine1="import org.gradle.internal.file.Chmod"
162-
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
163-
<location
164-
file="src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/Utils.kt"
165-
line="17"
166-
column="1"/>
167-
</issue>
168-
169-
<issue
170-
id="InternalGradleApiUsage"
171-
message="Avoid using internal Gradle APIs"
172-
errorLine1="import org.gradle.internal.file.FileMetadata"
173-
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
174-
<location
175-
file="src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/Utils.kt"
176-
line="18"
177-
column="1"/>
178-
</issue>
179-
180-
<issue
181-
id="InternalGradleApiUsage"
182-
message="Avoid using internal Gradle APIs"
183-
errorLine1="import org.gradle.internal.file.Stat"
184-
errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
185-
<location
186-
file="src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/internal/Utils.kt"
187-
line="19"
121+
line="35"
188122
column="1"/>
189123
</issue>
190124

src/docs/changes/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,18 @@
1212
- **BREAKING CHANGE:** Move tracking unused classes logic out of `ShadowCopyAction`. ([#1257](https://github.com/GradleUp/shadow/pull/1257))
1313
- Reduce duplicated `SimpleRelocator` to improve performance. ([#1271](https://github.com/GradleUp/shadow/pull/1271))
1414
- **BREAKING CHANGE:** Move `DependencyFilter` from `com.github.jengelman.gradle.plugins.shadow.internal` into `com.github.jengelman.gradle.plugins.shadow.tasks`. ([#1272](https://github.com/GradleUp/shadow/pull/1272))
15+
- Handle file unzipping via `Project.zipTree`. ([#1233](https://github.com/GradleUp/shadow/pull/1233))
16+
17+
**Fixed**
18+
19+
- Honor `DuplicatesStrategy`. ([#1233](https://github.com/GradleUp/shadow/pull/1233))
20+
- Honor unzipped jars via `from`. ([#1233](https://github.com/GradleUp/shadow/pull/1233))
1521

1622
**Removed**
1723

1824
- **BREAKING CHANGE:** Remove `BaseStreamAction`. ([#1258](https://github.com/GradleUp/shadow/pull/1258))
1925
- **BREAKING CHANGE:** Remove `ShadowStats`. ([#1264](https://github.com/GradleUp/shadow/pull/1264))
26+
- **BREAKING CHANGE:** Remove `ShadowCopyAction.ArchiveFileTreeElement` and `RelativeArchivePath`. ([#1233](https://github.com/GradleUp/shadow/pull/1233))
2027

2128

2229
## [v9.0.0-beta8] (2025-02-08)

src/docs/configuration/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,18 @@ tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.Shadow
9999
manifest.inheritFrom(testJar.get().manifest)
100100
}
101101
```
102+
103+
## Adding Extra Files
104+
105+
The `shadowJar` task is a subclass of the `Jar` task, which means that the
106+
[from](https://docs.gradle.org/current/dsl/org.gradle.jvm.tasks.Jar.html#org.gradle.jvm.tasks.Jar:from(java.lang.Object,%20groovy.lang.Closure))
107+
method can be used to add extra files.
108+
109+
```groovy
110+
tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
111+
from('extra.jar') {
112+
// Copy the contents of the extra.jar file into META-INF/ in the shadowed JAR.
113+
into('META-INF')
114+
}
115+
}
116+
```

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

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.github.jengelman.gradle.plugins.shadow
33
import assertk.all
44
import assertk.assertThat
55
import assertk.assertions.contains
6+
import assertk.assertions.containsMatch
67
import assertk.assertions.isEqualTo
78
import assertk.assertions.isGreaterThan
89
import assertk.assertions.isNotEmpty
@@ -20,8 +21,11 @@ import com.github.jengelman.gradle.plugins.shadow.util.Issue
2021
import com.github.jengelman.gradle.plugins.shadow.util.containsEntries
2122
import com.github.jengelman.gradle.plugins.shadow.util.doesNotContainEntries
2223
import com.github.jengelman.gradle.plugins.shadow.util.getMainAttr
24+
import com.github.jengelman.gradle.plugins.shadow.util.getStream
2325
import com.github.jengelman.gradle.plugins.shadow.util.runProcess
2426
import kotlin.io.path.appendText
27+
import kotlin.io.path.name
28+
import kotlin.io.path.outputStream
2529
import kotlin.io.path.writeText
2630
import org.gradle.api.plugins.JavaPlugin
2731
import org.gradle.testfixtures.ProjectBuilder
@@ -595,9 +599,7 @@ class JavaPluginTest : BasePluginTest() {
595599

596600
assertThat(result).all {
597601
taskOutcomeEquals(shadowJarTask, FAILED)
598-
transform { it.output }.contains(
599-
"java.util.zip.ZipException: archive is not a ZIP archive",
600-
)
602+
transform { it.output }.containsMatch("Cannot expand ZIP '.*bad\\.jar'".toRegex())
601603
}
602604
}
603605

@@ -653,4 +655,38 @@ class JavaPluginTest : BasePluginTest() {
653655
getMainAttr("Bar-Attr").isEqualTo("Bar-Value")
654656
}
655657
}
658+
659+
@Test
660+
fun canAddExtraFilesIntoShadowJar() {
661+
writeMainClass()
662+
projectScriptPath.appendText(
663+
"""
664+
$shadowJar {
665+
from(files('${artifactAJar.toUri().toURL().path}')) {
666+
into('META-INF')
667+
}
668+
}
669+
""".trimIndent(),
670+
)
671+
672+
run(shadowJarTask)
673+
674+
assertThat(outputShadowJar).useAll {
675+
containsEntries(
676+
"my/Main.class",
677+
"META-INF/a-1.0.jar",
678+
)
679+
doesNotContainEntries(*entriesInA)
680+
}
681+
val unzipped = path("unzipped")
682+
outputShadowJar.use {
683+
it.getStream("META-INF/a-1.0.jar").use { inputStream ->
684+
inputStream.copyTo(unzipped.outputStream())
685+
}
686+
}
687+
assertThat(jarPath(unzipped.name)).useAll {
688+
containsEntries(*entriesInA)
689+
doesNotContainEntries("my/Main.class")
690+
}
691+
}
656692
}

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import com.github.jengelman.gradle.plugins.shadow.util.doesNotContainEntries
88
import kotlin.io.path.appendText
99
import kotlin.io.path.readText
1010
import kotlin.io.path.writeText
11+
import org.gradle.api.file.DuplicatesStrategy
1112
import org.junit.jupiter.api.Test
1213

1314
class ShadowJarCachingTest : BaseCachingTest() {
@@ -210,4 +211,23 @@ class ShadowJarCachingTest : BaseCachingTest() {
210211

211212
assertions()
212213
}
214+
215+
@Test
216+
fun shadowJarIsCachedCorrectlyAfterDuplicatesStrategyChanged() {
217+
listOf(
218+
DuplicatesStrategy.EXCLUDE,
219+
DuplicatesStrategy.INCLUDE,
220+
DuplicatesStrategy.WARN,
221+
).forEach { strategy ->
222+
projectScriptPath.appendText(
223+
"""
224+
$shadowJar {
225+
duplicatesStrategy = DuplicatesStrategy.$strategy
226+
}
227+
""".trimIndent() + System.lineSeparator(),
228+
)
229+
230+
assertCompositeExecutions()
231+
}
232+
}
213233
}

0 commit comments

Comments
 (0)