1 /* <lambda>null2 * Copyright 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.build 18 19 import java.io.File 20 import java.io.FileInputStream 21 import java.util.zip.ZipEntry 22 import java.util.zip.ZipInputStream 23 import org.gradle.api.DefaultTask 24 import org.gradle.api.file.DirectoryProperty 25 import org.gradle.api.tasks.CacheableTask 26 import org.gradle.api.tasks.InputDirectory 27 import org.gradle.api.tasks.PathSensitive 28 import org.gradle.api.tasks.PathSensitivity 29 import org.gradle.api.tasks.TaskAction 30 31 /** Task for verifying license and version files in Androidx artifacts */ 32 @CacheableTask 33 abstract class VerifyLicenseAndVersionFilesTask : DefaultTask() { 34 @get:[InputDirectory PathSensitive(PathSensitivity.RELATIVE)] 35 abstract val repositoryDirectory: DirectoryProperty 36 37 @TaskAction 38 fun verifyFiles() { 39 verifyVersionFilesPresent() 40 verifyLicenseFilesPresent() 41 } 42 43 private fun verifyVersionFilesPresent() { 44 repositoryDirectory.asFile.get().walk().forEach { file -> 45 var expectedPrefix = "androidx" 46 if (file.path.contains("/libyuv/")) 47 expectedPrefix = "libyuv_libyuv" // external library that we don't publish 48 if (file.extension == "aar") { 49 val inputStream = FileInputStream(file) 50 val aarFileInputStream = ZipInputStream(inputStream) 51 var entry: ZipEntry? = aarFileInputStream.nextEntry 52 while (entry != null) { 53 if (entry.name == "classes.jar") { 54 var foundVersionFile = false 55 val classesJarInputStream = ZipInputStream(aarFileInputStream) 56 var jarEntry = classesJarInputStream.nextEntry 57 while (jarEntry != null) { 58 if ( 59 jarEntry.name.startsWith("META-INF/$expectedPrefix.") && 60 jarEntry.name.endsWith(".version") 61 ) { 62 foundVersionFile = true 63 break 64 } 65 jarEntry = classesJarInputStream.nextEntry 66 } 67 if (!foundVersionFile) { 68 throw Exception( 69 "Missing classes.jar/META-INF/$expectedPrefix.*version " + 70 "file in ${file.absolutePath}" 71 ) 72 } 73 break 74 } 75 entry = aarFileInputStream.nextEntry 76 } 77 } 78 } 79 } 80 81 private fun verifyLicenseFilesPresent() { 82 repositoryDirectory.asFile.get().walk().forEach { file -> 83 if (file.extension in listOf("aar", "jar", "klib")) { 84 if (!zipContainsLicense(file)) { 85 throw Exception( 86 "Missing META-INF/*/LICENSE.txt or default/licenses/*/LICENSE.txt " + 87 "file in ${file.absolutePath}" 88 ) 89 } 90 } 91 } 92 } 93 94 private fun zipContainsLicense(file: File): Boolean { 95 val inputStream = FileInputStream(file) 96 val zipInputStream = ZipInputStream(inputStream) 97 var entry: ZipEntry? = zipInputStream.nextEntry 98 while (entry != null) { 99 if (licensePatterns.any { it.matches(entry!!.name) }) { 100 return true 101 } 102 entry = zipInputStream.nextEntry 103 } 104 return false 105 } 106 } 107 108 private val licensePatterns = 109 listOf(Regex("META-INF/.*/LICENSE.txt"), Regex("default/licenses/.*/LICENSE.txt")) 110