@@ -28,7 +28,9 @@ import org.gradle.api.tasks.Input
2828import 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
3436class 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