blob: 24d133ea63517b4fb83a2185427b562addd4e6e8 [file] [log] [blame]
Yigit Boyar88c16ce2017-02-08 16:06:14 -08001/*
2 * Copyright (C) 2017 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
17import com.android.build.gradle.internal.coverage.JacocoPlugin
18import com.android.build.gradle.internal.coverage.JacocoReportTask
19import com.android.build.gradle.internal.tasks.DeviceProviderInstrumentTestTask
Aurimas Liutikasa0150042017-04-21 09:46:12 -070020import org.gradle.api.logging.configuration.ShowStacktrace
Yigit Boyar88c16ce2017-02-08 16:06:14 -080021
22def supportRoot = ext.supportRootFolder
23if (supportRoot == null) {
24 throw new RuntimeException("variable supportRootFolder is not set. you must set it before" +
25 " including this script")
26}
27def init = new Properties()
28ext.init = init
Alan Viverette1b862372017-03-22 11:32:28 -040029ext.init.debugKeystore = file("${supportRoot}/development/keystore/debug.keystore")
Yigit Boyar88c16ce2017-02-08 16:06:14 -080030
Aurimas Liutikas9ab3b4c2017-04-19 09:33:27 -070031ext.runningInBuildServer = System.env.DIST_DIR != null && System.env.OUT_DIR != null
Yigit Boyar88c16ce2017-02-08 16:06:14 -080032
33apply from: "${supportRoot}/buildSrc/dependencies.gradle"
Alan Viverette5b3946f2017-04-27 09:59:22 -040034ext.docs = [:]
35ext.docs.offline = rootProject.getProperties().containsKey("offlineDocs")
36ext.docs.dac = [
37 libraryroot: "android/support",
38 dataname: "SUPPORT_DATA"
39]
Yigit Boyar88c16ce2017-02-08 16:06:14 -080040
41def loadDefaultVersions() {
42 apply from: "${supportRootFolder}/buildSrc/versions.gradle"
43}
44
Yigit Boyar88c16ce2017-02-08 16:06:14 -080045def enableDoclavaAndJDiff(p) {
46 p.configurations {
47 doclava
48 jdiff
49 }
50
51 p.dependencies {
Aurimas Liutikaseca7a072017-07-11 01:11:52 +000052 doclava project(':doclava')
53 jdiff project(':jdiff')
Yigit Boyar88c16ce2017-02-08 16:06:14 -080054 jdiff libs.xml_parser_apis
55 jdiff libs.xerces_impl
56 }
57 apply from: "${ext.supportRootFolder}/buildSrc/diff_and_docs.gradle"
58}
59
Aurimas Liutikasbb78f3f2017-06-19 11:30:37 -070060def getFullSdkPath() {
Aurimas Liutikasb06771d2017-04-20 09:46:49 -070061 final String osName = System.getProperty("os.name").toLowerCase();
62 final boolean isMacOsX =
63 osName.contains("mac os x") || osName.contains("darwin") || osName.contains("osx");
64 final String platform = isMacOsX ? 'darwin' : 'linux'
Aurimas Liutikasbb78f3f2017-06-19 11:30:37 -070065 return "${repos.prebuiltsRoot}/fullsdk-${platform}"
66}
67
68def setSdkInLocalPropertiesFile() {
Aurimas Liutikasd2d9bda2017-03-03 16:06:39 -080069 ext.buildToolsVersion = '26.0.0'
Aurimas Liutikasbb78f3f2017-06-19 11:30:37 -070070 final String fullSdkPath = getFullSdkPath();
Yigit Boyar88c16ce2017-02-08 16:06:14 -080071 if (file(fullSdkPath).exists()) {
72 gradle.ext.currentSdk = 26
Alan Viveretteeb9f3322017-03-09 16:29:57 -050073 project.ext.androidJar =
74 files("${fullSdkPath}/platforms/android-${gradle.currentSdk}/android.jar")
75 project.ext.androidSrcJar =
76 file("${fullSdkPath}/platforms/android-${gradle.currentSdk}/android-stubs-src.jar")
Alan Viverette810a1482017-03-20 12:43:43 -040077 project.ext.androidApiTxt = null
Yigit Boyar88c16ce2017-02-08 16:06:14 -080078 File props = file("local.properties")
79 props.write "sdk.dir=${fullSdkPath}"
Aurimas Liutikas3c666002017-03-08 19:30:28 -080080 ext.usingFullSdk = true
Yigit Boyar88c16ce2017-02-08 16:06:14 -080081 } else {
82 gradle.ext.currentSdk = 'current'
Aurimas Liutikas9ab3b4c2017-04-19 09:33:27 -070083 project.ext.androidJar = files("${repos.prebuiltsRoot}/sdk/current/android.jar")
Alan Viverette810a1482017-03-20 12:43:43 -040084 project.ext.androidSrcJar = null
Aurimas Liutikas9ab3b4c2017-04-19 09:33:27 -070085 project.ext.androidApiTxt = file("${repos.prebuiltsRoot}/sdk/api/26.txt")
Aurimas Liutikasbb78f3f2017-06-19 11:30:37 -070086 System.setProperty('android.dir', "${supportRootFolder}/../../")
Yigit Boyar88c16ce2017-02-08 16:06:14 -080087 File props = file("local.properties")
88 props.write "android.dir=../../"
Aurimas Liutikas3c666002017-03-08 19:30:28 -080089 ext.usingFullSdk = false
Yigit Boyar88c16ce2017-02-08 16:06:14 -080090 }
91}
92
93def setupRepoOutAndBuildNumber() {
Yigit Boyaref300662017-05-01 11:52:07 -070094 // common support repo folder which works well for prebuilts.
Yigit Boyar88c16ce2017-02-08 16:06:14 -080095 ext.supportRepoOut = ''
Yigit Boyaref300662017-05-01 11:52:07 -070096 // files in artifactoryRepoOut can be safely copied into a real artifactory.
97 ext.artifactoryRepoOut = ''
Aurimas Liutikas76542da2017-06-29 17:00:29 -070098 ext.buildNumber = "0"
Yigit Boyar88c16ce2017-02-08 16:06:14 -080099 /*
100 * With the build server you are given two env variables.
101 * The OUT_DIR is a temporary directory you can use to put things during the build.
102 * The DIST_DIR is where you want to save things from the build.
103 *
104 * The build server will copy the contents of DIST_DIR to somewhere and make it available.
105 */
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800106 if (ext.runningInBuildServer) {
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800107 buildDir = new File(System.env.OUT_DIR + '/gradle/frameworks/support/build')
108 .getCanonicalFile()
109 project.ext.distDir = new File(System.env.DIST_DIR).getCanonicalFile()
110
111 // the build server does not pass the build number so we infer it from the last folder of
112 // the dist path.
113 ext.buildNumber = project.ext.distDir.getName()
Aurimas Liutikasa0150042017-04-21 09:46:12 -0700114
115 // the build server should always print out full stack traces for any failures.
116 gradle.startParameter.showStacktrace = ShowStacktrace.ALWAYS
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800117 } else {
118 buildDir = file("${ext.supportRootFolder}/../../out/host/gradle/frameworks/support/build")
119 project.ext.distDir = new File("${ext.supportRootFolder}/../../out/dist")
120 }
121 subprojects {
122 // Change buildDir first so that all plugins pick up the new value.
123 project.buildDir = new File("$project.parent.buildDir/../$project.name/build")
124 }
125 ext.supportRepoOut = new File(buildDir, 'support_repo')
Yigit Boyaref300662017-05-01 11:52:07 -0700126 ext.artifactoryRepoOut = new File(buildDir, 'artifactory_repo')
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800127 ext.testApkDistOut = ext.distDir
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800128 ext.testResultsDistDir = new File(distDir, "host-test-reports")
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800129 ext.docsDir = new File(buildDir, 'javadoc')
130}
131
Aurimas Liutikas38e8f4d2017-06-16 08:31:03 -0700132def configureBuildOnServer() {
133 def buildOnServerTask = rootProject.tasks.create("buildOnServer")
134 rootProject.tasks.whenTaskAdded { task ->
135 if ("createArchive".equals(task.name)) {
136 buildOnServerTask.dependsOn task
137 }
138 }
139
140 subprojects {
141 project.tasks.whenTaskAdded { task ->
142 if ("assembleErrorProne".equals(task.name) || "assembleAndroidTest".equals(task.name)) {
143 buildOnServerTask.dependsOn task
144 }
145 }
146 }
147}
148
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800149def configureSubProjects() {
150 // lint every library
151 def lintTask = project.tasks.create("lint")
152 subprojects {
Aurimas Liutikas6509a1a2017-05-09 16:25:43 -0700153 repos.addMavenRepositories(repositories)
154
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800155 // Only modify Android projects.
Aurimas Liutikaseca7a072017-07-11 01:11:52 +0000156 if (project.name.equals('doclava')
157 || project.name.equals('jdiff')
158 || project.name.equals('support-testutils')
Aurimas Liutikas6509a1a2017-05-09 16:25:43 -0700159 || project.name.equals('noto-emoji-compat')) {
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800160 // disable tests and return
161 project.tasks.whenTaskAdded { task ->
162 if (task instanceof org.gradle.api.tasks.testing.Test) {
163 task.enabled = false
164 }
165 }
166 return
167 }
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800168
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800169 project.ext.currentSdk = gradle.ext.currentSdk
170 apply plugin: 'maven'
171
172 version = rootProject.ext.supportVersion
173 group = 'com.android.support'
174
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800175 project.plugins.whenPluginAdded { plugin ->
176 def isAndroidLibrary = "com.android.build.gradle.LibraryPlugin"
177 .equals(plugin.class.name)
178 def isAndroidApp = "com.android.build.gradle.AppPlugin".equals(plugin.class.name)
179 def isJavaLibrary = "org.gradle.api.plugins.JavaPlugin".equals(plugin.class.name)
180
181 if (isAndroidLibrary || isAndroidApp) {
182 project.android.buildToolsVersion = rootProject.buildToolsVersion
183
184 // Enable code coverage for debug builds only if we are not running inside the IDE,
185 // since enabling coverage reports breaks the method parameter resolution in the IDE
186 // debugger.
187 project.android.buildTypes.debug.testCoverageEnabled =
Sergey Vasilinetsac8e72b2017-04-26 15:55:17 -0700188 !project.hasProperty('android.injected.invoked.from.ide')
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800189
190 // Copy the class files in a jar to be later used to generate code coverage report
191 project.android.testVariants.all { v ->
192 // check if the variant has any source files
193 // and test coverage is enabled
194 if (v.buildType.testCoverageEnabled
195 && v.sourceSets.any { !it.java.sourceFiles.isEmpty() }) {
196 def jarifyTask = project.tasks.create(
197 name: "package${v.name.capitalize()}ClassFilesForCoverageReport",
198 type: Jar) {
199 from v.testedVariant.javaCompile.destinationDir
200 exclude "**/R.class"
201 exclude "**/R\$*.class"
202 exclude "**/BuildConfig.class"
203 destinationDir file(project.distDir)
Aurimas Liutikas76542da2017-06-29 17:00:29 -0700204 archiveName "${project.name}-${v.baseName}-allclasses.jar"
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800205 }
Aurimas Liutikas21b7fce2017-06-23 09:52:08 -0700206
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800207 def collectJacocoAntPackages = project.tasks.create(
208 name: "collectJacocoAntPackages",
209 type: Jar) {
Aurimas Liutikas21b7fce2017-06-23 09:52:08 -0700210 inputs.files project.configurations[JacocoPlugin.ANT_CONFIGURATION_NAME]
211 from {
Aurimas Liutikas585a9342017-06-25 16:07:56 -0700212 project.configurations[JacocoPlugin.ANT_CONFIGURATION_NAME]
213 .resolvedConfiguration
214 .resolvedArtifacts.collect{ zipTree(it.getFile()) }} {
Aurimas Liutikas21b7fce2017-06-23 09:52:08 -0700215 // exclude all the signatures the jar might have
216 exclude "META-INF/*.SF"
217 exclude "META-INF/*.DSA"
218 exclude "META-INF/*.RSA"
219 }
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800220 destinationDir file(project.distDir)
Aurimas Liutikas21b7fce2017-06-23 09:52:08 -0700221 archiveName "jacocoant.jar"
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800222 }
Aurimas Liutikas21b7fce2017-06-23 09:52:08 -0700223
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800224 jarifyTask.dependsOn v.getJavaCompiler()
Aurimas Liutikas21b7fce2017-06-23 09:52:08 -0700225 v.assemble.dependsOn jarifyTask , collectJacocoAntPackages
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800226 }
227 }
228
229 // Enforce NewApi lint check as fatal.
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800230 project.android.lintOptions.fatal 'NewApi'
231 lintTask.dependsOn project.lint
232 }
233
234 if (isAndroidLibrary || isJavaLibrary) {
235 // Add library to the aggregate dependency report.
236 task allDeps(type: DependencyReportTask) {}
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800237
Aurimas Liutikas6509a1a2017-05-09 16:25:43 -0700238 project.afterEvaluate {
239 Upload uploadTask = (Upload) project.tasks.uploadArchives;
240 uploadTask.repositories.mavenDeployer {
241
242 // Disable unique names for SNAPSHOTS so they can be updated in place.
243 setUniqueVersion(false)
Aurimas Liutikasfc243312017-05-12 14:21:13 -0700244 }
245 uploadTask.doLast {
Aurimas Liutikas6509a1a2017-05-09 16:25:43 -0700246 // Remove any invalid maven-metadata.xml files that may have been
247 // created for SNAPSHOT versions that are *not* uniquely versioned.
Aurimas Liutikasfc243312017-05-12 14:21:13 -0700248 repositories.mavenDeployer.pom*.each { pom ->
Aurimas Liutikas6509a1a2017-05-09 16:25:43 -0700249 if (pom.version.endsWith('-SNAPSHOT')) {
250 final File artifactDir = new File(
251 rootProject.ext.supportRepoOut,
252 pom.groupId.replace('.', '/')
253 + '/' + pom.artifactId
254 + '/' + pom.version)
255 delete fileTree(dir: artifactDir,
256 include: 'maven-metadata.xml*')
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800257 }
258 }
259 }
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800260
Aurimas Liutikas6509a1a2017-05-09 16:25:43 -0700261 // create a release task that produces artifactory friends artifacts
262 // a.k.a. unique versions for snapshots with their maven-metadata files.
263 task artifactoryRelease(type : Upload) {
264 configuration = uploadTask.configuration
265 repositories {
266 mavenDeployer {
267 repository(url: uri("$rootProject.ext.artifactoryRepoOut"))
268 setUniqueVersion(true)
269 }
270 }
271 }
272
273 // Before the upload, make sure the repo is ready.
274 uploadTask.dependsOn rootProject.tasks.prepareRepo
275
276 artifactoryRelease.dependsOn uploadTask
277
278 // Make the mainupload depend on this one.
279 mainUpload.dependsOn uploadTask
280 mainUpload.dependsOn artifactoryRelease
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800281 }
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800282 }
283 }
284
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800285 // Copy instrumentation test APKs and app APKs into the dist dir
286 // For test apks, they are uploaded only if we have java test sources.
287 // For regular app apks, they are uploaded only if they have java sources.
288 project.tasks.whenTaskAdded { task ->
289 if (task.name.startsWith("packageDebug")) {
290 def testApk = task.name.contains("AndroidTest")
291 task.doLast {
292 def source = testApk ? project.android.sourceSets.androidTest
293 : project.android.sourceSets.main
Aurimas Liutikasef3b4922017-06-28 10:44:59 -0700294 if (task.hasProperty("outputDirectory") && !source.java.sourceFiles.isEmpty()) {
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800295 copy {
Aurimas Liutikasef3b4922017-06-28 10:44:59 -0700296 from(task.outputDirectory)
297 include '*.apk'
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800298 into(rootProject.ext.testApkDistOut)
299 rename { String fileName ->
300 // multiple modules may have the same name so prefix the name with
301 // the module's path to ensure it is unique.
302 // e.g. palette-v7-debug-androidTest.apk becomes
303 // support-palette-v7_palette-v7-debug-androidTest.apk
304 "${project.getPath().replace(':', '-').substring(1)}_${fileName}"
305 }
306 }
307 }
308 }
309 }
310 }
311
312 // copy host side test results to DIST
313 project.tasks.whenTaskAdded { task ->
314 if (task instanceof org.gradle.api.tasks.testing.Test) {
315 def junitReport = task.reports.junitXml
316 if (junitReport.enabled) {
317 def zipTask = project.tasks.create(name : "zipResultsOf${task.name.capitalize()}", type : Zip) {
318 destinationDir(testResultsDistDir)
Yigit Boyar278676d2017-03-10 15:29:11 -0800319 // first one is always :, drop it.
320 archiveName("${project.getPath().split(":").join("_").substring(1)}.zip")
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800321 }
322 if (project.rootProject.ext.runningInBuildServer) {
323 task.ignoreFailures = true
324 }
325 task.finalizedBy zipTask
326 task.doFirst {
327 zipTask.from(junitReport.destination)
328 }
329 }
330 }
331 }
332
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800333 project.afterEvaluate { p ->
334 // remove dependency on the test so that we still get coverage even if some tests fail
335 p.tasks.findAll { it instanceof JacocoReportTask }.each { task ->
336 def toBeRemoved = new ArrayList()
337 def dependencyList = task.taskDependencies.values
338 dependencyList.each { dep ->
339 if (dep instanceof String) {
340 def t = tasks.findByName(dep)
341 if (t instanceof DeviceProviderInstrumentTestTask) {
342 toBeRemoved.add(dep)
343 task.mustRunAfter(t)
344 }
345 }
346 }
347 toBeRemoved.each { dep ->
348 dependencyList.remove(dep)
349 }
350 }
351 }
352 }
353}
354
355def setupRelease() {
356 apply from: "${ext.supportRootFolder}/buildSrc/release.gradle"
357}
358
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800359ext.init.enableDoclavaAndJDiff = this.&enableDoclavaAndJDiff
360ext.init.setSdkInLocalPropertiesFile = this.&setSdkInLocalPropertiesFile
361ext.init.setupRepoOutAndBuildNumber = this.&setupRepoOutAndBuildNumber
362ext.init.setupRelease = this.&setupRelease
363ext.init.loadDefaultVersions = this.&loadDefaultVersions
Aurimas Liutikas38e8f4d2017-06-16 08:31:03 -0700364ext.init.configureSubProjects = this.&configureSubProjects
Yigit Boyare1bbf712017-03-08 13:52:37 -0800365ext.init.configureBuildOnServer = this.&configureBuildOnServer