Skip to content

Commit 31f5f40

Browse files
committed
fix: #14930 doc: add javadoc
1 parent 2191a0c commit 31f5f40

File tree

1 file changed

+52
-1
lines changed

1 file changed

+52
-1
lines changed

grails-forge/buildSrc/src/main/groovy/org/apache/grails/forge/buildlogic/shadowjar/GrailsShadowLicenseTransform.groovy

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ import org.gradle.api.tasks.Input
2828
import java.util.regex.Pattern
2929

3030
/**
31-
* supports combining into a single license file.
31+
* This transformer assists in combining all known licenses into a single META-INF/LICENSE file. Please note that the
32+
* shadow plugin will initially copy all dependencies that are in the local project and then it will copy all other external
33+
* dependencies. Transformers only apply to the copied jar file dependencies, and not to the local project dependencies.
3234
*/
3335
@CompileStatic
3436
class GrailsShadowLicenseTransform implements Transformer {
@@ -59,12 +61,22 @@ class GrailsShadowLicenseTransform implements Transformer {
5961
@Input
6062
Boolean separators = false
6163

64+
/**
65+
* Whether this transformer can process the given resource. If set to true, it's expected the transformer will
66+
* write the resource.
67+
*/
6268
@Override
6369
boolean canTransformResource(FileTreeElement element) {
6470
def path = element.relativePath.pathString
6571
LICENSE_PATTERNS.any { pattern -> pattern.matcher(path).matches() }
6672
}
6773

74+
/**
75+
* Parses any file that matches the license patterns and extracts the license text, deduplicating & combining where
76+
* possible.
77+
*
78+
* @param context contains the input stream of the resource to transform
79+
*/
6880
@Override
6981
// Multiple assignments without list expressions on the right hand side are unsupported in static type checking mode
7082
@CompileDynamic
@@ -95,6 +107,10 @@ class GrailsShadowLicenseTransform implements Transformer {
95107
}
96108
}
97109

110+
/**
111+
* Some libraries ship with a license.header file that contains a Java block comment. This method strips the
112+
* Java block comment syntax and returns the text without the comment.
113+
*/
98114
private static String stripJavaBlockComment(String text) {
99115
if (!text.startsWith('/*')) {
100116
return text
@@ -109,6 +125,15 @@ class GrailsShadowLicenseTransform implements Transformer {
109125
.join('\n')
110126
}
111127

128+
/**
129+
* Normalizes the license text by collapsing whitespace and uppercasing all characters. It also returns a mapping
130+
* of the normalized text to the original license text, where each character in the normalized text maps to its
131+
* original index in the license text. This allows us to index into the normalized text from sections of the license text
132+
* for deduplication purposes.
133+
*
134+
* @param license the original license text
135+
* @return a tuple containing the normalized license text and a list of index mappings
136+
*/
112137
private static Tuple2<String, List<Integer>> normalize(String license) {
113138
def sb = new StringBuilder()
114139
List<Integer> indexMappings = [] // each char in sb maps to original index
@@ -135,6 +160,13 @@ class GrailsShadowLicenseTransform implements Transformer {
135160
new Tuple2<String, List<Integer>>(normalized, indexMappings[startTrim..<endTrim])
136161
}
137162

163+
/**
164+
* For a given license, this method will extract the duplicate license text and return the remaining text
165+
* @param license the original license text
166+
* @param normalized a normalized version of the license text, with all whitespace collapsed and all characters uppercased
167+
* @param indexMappings a mapping of the normalized text to the original license text, where each character in the normalized text maps to its original index in the license text
168+
* @return either null if no additional license text was found or the additional license text
169+
*/
138170
private String resectLicense(String license, String normalized, List<Integer> indexMappings) {
139171
if (!normalized.startsWith(licenseTermsStart.toUpperCase())) {
140172
return license // not ASF license, return as is
@@ -171,17 +203,36 @@ class GrailsShadowLicenseTransform implements Transformer {
171203
license
172204
}
173205

206+
/**
207+
* Some licenses mix http & https links, handles simple variations of the license to ensure the license can be
208+
* deduplicated.
209+
*
210+
* @param license the license text
211+
* @return a list of variations of the license text
212+
*/
174213
private static List<String> getVariations(String license) {
175214
[license.trim()].collectMany {
176215
[it, it.replace('http://', 'https://'), it.replace('https://', 'http://')]
177216
}
178217
}
179218

219+
/**
220+
* Whether this transformer will modify the output stream.
221+
*/
180222
@Override
181223
boolean hasTransformedResource() {
224+
// Must always be true since we want to write the LICENSE file and all license files originate from jar files
225+
// after our project restructure
182226
true
183227
}
184228

229+
/**
230+
* Writes the combined license file to the output stream. The file will be written to
231+
* META-INF/LICENSE and will contain all licenses found in the project
232+
*
233+
* @param os the jar file output stream
234+
* @param preserveFileTimestamps whether to preserve file timestamps in the output jar
235+
*/
185236
@Override
186237
void modifyOutputStream(ZipOutputStream os, boolean preserveFileTimestamps) {
187238
ZipEntry zipEntry = new ZipEntry(LICENSE_PATH)

0 commit comments

Comments
 (0)