/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import com.android.build.gradle.internal.coverage.JacocoPlugin import com.android.build.gradle.internal.coverage.JacocoReportTask import com.android.build.gradle.internal.tasks.DeviceProviderInstrumentTestTask import com.google.common.base.Charsets import com.google.common.io.Files import org.gradle.api.logging.configuration.ShowStacktrace def supportRoot = ext.supportRootFolder if (supportRoot == null) { throw new RuntimeException("variable supportRootFolder is not set. you must set it before" + " including this script") } def init = new Properties() ext.init = init ext.init.debugKeystore = file("${supportRoot}/development/keystore/debug.keystore") ext.runningInBuildServer = System.env.DIST_DIR != null && System.env.OUT_DIR != null apply from: "${supportRoot}/buildSrc/dependencies.gradle" ext.docs = [:] ext.docs.offline = rootProject.getProperties().containsKey("offlineDocs") ext.docs.dac = [ libraryroot: "android/support", dataname: "SUPPORT_DATA" ] def loadDefaultVersions() { apply from: "${supportRootFolder}/buildSrc/versions.gradle" } def enableDoclavaAndJDiff(p) { p.configurations { doclava jdiff } p.dependencies { doclava project(':doclava') jdiff project(':jdiff') jdiff libs.xml_parser_apis jdiff libs.xerces_impl } apply from: "${ext.supportRootFolder}/buildSrc/diff_and_docs.gradle" } def setSdkInLocalPropertiesFile() { final String osName = System.getProperty("os.name").toLowerCase(); final boolean isMacOsX = osName.contains("mac os x") || osName.contains("darwin") || osName.contains("osx"); final String platform = isMacOsX ? 'darwin' : 'linux' System.setProperty('android.dir', "${supportRootFolder}/../../") ext.buildToolsVersion = '26.0.0' final String fullSdkPath = "${repos.prebuiltsRoot}/fullsdk-${platform}" if (file(fullSdkPath).exists()) { gradle.ext.currentSdk = 26 project.ext.androidJar = files("${fullSdkPath}/platforms/android-${gradle.currentSdk}/android.jar") project.ext.androidSrcJar = file("${fullSdkPath}/platforms/android-${gradle.currentSdk}/android-stubs-src.jar") project.ext.androidApiTxt = null System.setProperty('android.home', "${repos.prebuiltsRoot}/fullsdk-${platform}") File props = file("local.properties") props.write "sdk.dir=${fullSdkPath}" ext.usingFullSdk = true } else { gradle.ext.currentSdk = 'current' project.ext.androidJar = files("${repos.prebuiltsRoot}/sdk/current/android.jar") project.ext.androidSrcJar = null project.ext.androidApiTxt = file("${repos.prebuiltsRoot}/sdk/api/26.txt") File props = file("local.properties") props.write "android.dir=../../" ext.usingFullSdk = false } } def setupRepoOutAndBuildNumber() { ext.supportRepoOut = '' ext.buildNumber = Integer.toString(ext.extraVersion) /* * With the build server you are given two env variables. * The OUT_DIR is a temporary directory you can use to put things during the build. * The DIST_DIR is where you want to save things from the build. * * The build server will copy the contents of DIST_DIR to somewhere and make it available. */ if (ext.runningInBuildServer) { buildDir = new File(System.env.OUT_DIR + '/gradle/frameworks/support/build') .getCanonicalFile() project.ext.distDir = new File(System.env.DIST_DIR).getCanonicalFile() // the build server does not pass the build number so we infer it from the last folder of // the dist path. ext.buildNumber = project.ext.distDir.getName() // the build server should always print out full stack traces for any failures. gradle.startParameter.showStacktrace = ShowStacktrace.ALWAYS } else { buildDir = file("${ext.supportRootFolder}/../../out/host/gradle/frameworks/support/build") project.ext.distDir = new File("${ext.supportRootFolder}/../../out/dist") } subprojects { // Change buildDir first so that all plugins pick up the new value. project.buildDir = new File("$project.parent.buildDir/../$project.name/build") } ext.supportRepoOut = new File(buildDir, 'support_repo') ext.testApkDistOut = ext.distDir ext.testResultsDistDir = new File(distDir, "host-test-reports") ext.docsDir = new File(buildDir, 'javadoc') } def configureSubProjects() { // lint every library def lintTask = project.tasks.create("lint") subprojects { repos.addMavenRepositories(repositories) // Only modify Android projects. if (project.name.equals('doclava') || project.name.equals('jdiff') || project.name.equals('support-testutils') || project.name.equals('noto-emoji-compat')) { // disable tests and return project.tasks.whenTaskAdded { task -> if (task instanceof org.gradle.api.tasks.testing.Test) { task.enabled = false } } return } // Current SDK is set in studioCompat.gradle. project.ext.currentSdk = gradle.ext.currentSdk apply plugin: 'maven' version = rootProject.ext.supportVersion group = 'com.android.support' project.plugins.whenPluginAdded { plugin -> def isAndroidLibrary = "com.android.build.gradle.LibraryPlugin" .equals(plugin.class.name) def isAndroidApp = "com.android.build.gradle.AppPlugin".equals(plugin.class.name) def isJavaLibrary = "org.gradle.api.plugins.JavaPlugin".equals(plugin.class.name) if (isAndroidLibrary || isAndroidApp) { project.android.buildToolsVersion = rootProject.buildToolsVersion // Enable code coverage for debug builds only if we are not running inside the IDE, // since enabling coverage reports breaks the method parameter resolution in the IDE // debugger. project.android.buildTypes.debug.testCoverageEnabled = !project.hasProperty('android.injected.invoked.from.ide') // Copy the class files in a jar to be later used to generate code coverage report project.android.testVariants.all { v -> // check if the variant has any source files // and test coverage is enabled if (v.buildType.testCoverageEnabled && v.sourceSets.any { !it.java.sourceFiles.isEmpty() }) { def jarifyTask = project.tasks.create( name: "package${v.name.capitalize()}ClassFilesForCoverageReport", type: Jar) { from v.testedVariant.javaCompile.destinationDir exclude "**/R.class" exclude "**/R\$*.class" exclude "**/BuildConfig.class" destinationDir file(project.distDir) archiveName "${project.archivesBaseName}-${v.baseName}-allclasses.jar" } def jacocoAntConfig = project.configurations[JacocoPlugin.ANT_CONFIGURATION_NAME] def jacocoAntArtifacts = jacocoAntConfig.resolvedConfiguration .resolvedArtifacts def version = jacocoAntArtifacts.find { "org.jacoco.ant".equals(it.name) } .moduleVersion.id.version def collectJacocoAntPackages = project.tasks.create( name: "collectJacocoAntPackages", type: Jar) { from(jacocoAntArtifacts.collect { zipTree(it.getFile()) }) { // exclude all the signatures the jar might have exclude "META-INF/*.SF" exclude "META-INF/*.DSA" exclude "META-INF/*.RSA" } destinationDir file(project.distDir) archiveName "jacocoant-" + version + ".jar" } jarifyTask.dependsOn v.getJavaCompiler() v.assemble.dependsOn jarifyTask, collectJacocoAntPackages } } // Enforce NewApi lint check as fatal. project.android.lintOptions.check 'NewApi' project.android.lintOptions.fatal 'NewApi' lintTask.dependsOn project.lint } if (isAndroidLibrary || isJavaLibrary) { // Add library to the aggregate dependency report. task allDeps(type: DependencyReportTask) {} project.afterEvaluate { Upload uploadTask = (Upload) project.tasks.uploadArchives; uploadTask.repositories.mavenDeployer { // Disable unique names for SNAPSHOTS so they can be updated in place. setUniqueVersion(false) } uploadTask.doLast { // Remove any invalid maven-metadata.xml files that may have been // created for SNAPSHOT versions that are *not* uniquely versioned. repositories.mavenDeployer.pom*.each { pom -> if (pom.version.endsWith('-SNAPSHOT')) { final File artifactDir = new File( rootProject.ext.supportRepoOut, pom.groupId.replace('.', '/') + '/' + pom.artifactId + '/' + pom.version) delete fileTree(dir: artifactDir, include: 'maven-metadata.xml*') } } } uploadTask.repositories.mavenDeployer.pom*.whenConfigured { pom -> pom.dependencies.findAll { dep -> dep.groupId == 'com.android.support' && dep.artifactId != 'support-annotations' }*.type = 'aar' } // Before the upload, make sure the repo is ready. uploadTask.dependsOn rootProject.tasks.prepareRepo // Make the mainupload depend on this one. mainUpload.dependsOn uploadTask } } } // Copy instrumentation test APKs and app APKs into the dist dir // For test apks, they are uploaded only if we have java test sources. // For regular app apks, they are uploaded only if they have java sources. project.tasks.whenTaskAdded { task -> if (task.name.startsWith("packageDebug")) { def testApk = task.name.contains("AndroidTest") task.doLast { def source = testApk ? project.android.sourceSets.androidTest : project.android.sourceSets.main if (task.hasProperty("outputFile") && !source.java.sourceFiles.isEmpty()) { copy { from(task.outputFile) into(rootProject.ext.testApkDistOut) rename { String fileName -> // multiple modules may have the same name so prefix the name with // the module's path to ensure it is unique. // e.g. palette-v7-debug-androidTest.apk becomes // support-palette-v7_palette-v7-debug-androidTest.apk "${project.getPath().replace(':', '-').substring(1)}_${fileName}" } } } } } } // copy host side test results to DIST project.tasks.whenTaskAdded { task -> if (task instanceof org.gradle.api.tasks.testing.Test) { def junitReport = task.reports.junitXml if (junitReport.enabled) { def zipTask = project.tasks.create(name : "zipResultsOf${task.name.capitalize()}", type : Zip) { destinationDir(testResultsDistDir) // first one is always :, drop it. archiveName("${project.getPath().split(":").join("_").substring(1)}.zip") } if (project.rootProject.ext.runningInBuildServer) { task.ignoreFailures = true } task.finalizedBy zipTask task.doFirst { zipTask.from(junitReport.destination) } } } } project.afterEvaluate { // The archivesBaseName isn't available initially, so set it now def createZipTask = project.tasks.findByName("createSeparateZip") if (createZipTask != null) { createZipTask.appendix = archivesBaseName createZipTask.from versionDir() } } project.afterEvaluate { p -> // remove dependency on the test so that we still get coverage even if some tests fail p.tasks.findAll { it instanceof JacocoReportTask }.each { task -> def toBeRemoved = new ArrayList() def dependencyList = task.taskDependencies.values dependencyList.each { dep -> if (dep instanceof String) { def t = tasks.findByName(dep) if (t instanceof DeviceProviderInstrumentTestTask) { toBeRemoved.add(dep) task.mustRunAfter(t) } } } toBeRemoved.each { dep -> dependencyList.remove(dep) } } } } } def setupRelease() { apply from: "${ext.supportRootFolder}/buildSrc/release.gradle" } ext.init.enableDoclavaAndJDiff = this.&enableDoclavaAndJDiff ext.init.setSdkInLocalPropertiesFile = this.&setSdkInLocalPropertiesFile ext.init.setupRepoOutAndBuildNumber = this.&setupRepoOutAndBuildNumber ext.init.setupRelease = this.&setupRelease ext.init.loadDefaultVersions = this.&loadDefaultVersions ext.init.configureSubProjects = this.&configureSubProjects