blob: ee2c1cc1fc5694ac3bdf77df4ad843e716113200 [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
Sergey Vasilinets22b62142017-11-22 20:32:27 -080017
Sergey Vasilinets22b62142017-11-22 20:32:27 -080018import android.support.DiffAndDocs
Aurimas Liutikas62d3e1d2017-11-28 15:28:01 -080019import android.support.gmaven.GMavenVersionChecker
Yigit Boyar88c16ce2017-02-08 16:06:14 -080020import com.android.build.gradle.internal.coverage.JacocoPlugin
21import com.android.build.gradle.internal.coverage.JacocoReportTask
22import com.android.build.gradle.internal.tasks.DeviceProviderInstrumentTestTask
Aurimas Liutikasa0150042017-04-21 09:46:12 -070023import org.gradle.api.logging.configuration.ShowStacktrace
Yigit Boyar88c16ce2017-02-08 16:06:14 -080024
25def supportRoot = ext.supportRootFolder
26if (supportRoot == null) {
27 throw new RuntimeException("variable supportRootFolder is not set. you must set it before" +
28 " including this script")
29}
30def init = new Properties()
31ext.init = init
Alan Viverette1b862372017-03-22 11:32:28 -040032ext.init.debugKeystore = file("${supportRoot}/development/keystore/debug.keystore")
Yigit Boyara9ac19d2017-09-20 16:11:49 -070033rootProject.ext.versionChecker = new GMavenVersionChecker(rootProject)
Aurimas Liutikas9ab3b4c2017-04-19 09:33:27 -070034ext.runningInBuildServer = System.env.DIST_DIR != null && System.env.OUT_DIR != null
Yigit Boyar88c16ce2017-02-08 16:06:14 -080035
36apply from: "${supportRoot}/buildSrc/dependencies.gradle"
Aurimas Liutikas62d3e1d2017-11-28 15:28:01 -080037apply from: "${supportRoot}/buildSrc/build_dependencies.gradle"
Yigit Boyar88c16ce2017-02-08 16:06:14 -080038
Sergey Vasilinets16385352017-12-13 16:56:47 -080039def enableDoclavaAndJDiff(p, dacOptions) {
Yigit Boyar88c16ce2017-02-08 16:06:14 -080040 p.configurations {
41 doclava
42 jdiff
43 }
44
45 p.dependencies {
Aurimas Liutikaseca7a072017-07-11 01:11:52 +000046 doclava project(':doclava')
47 jdiff project(':jdiff')
Aurimas Liutikas62d3e1d2017-11-28 15:28:01 -080048 jdiff build_libs.xml_parser_apis
49 jdiff build_libs.xerces_impl
Yigit Boyar88c16ce2017-02-08 16:06:14 -080050 }
Sergey Vasilinets16385352017-12-13 16:56:47 -080051 def allChecks = DiffAndDocs.configureDiffAndDocs(rootProject, supportRootFolder, dacOptions)
52 createArchive.dependsOn(allChecks)
Yigit Boyar88c16ce2017-02-08 16:06:14 -080053}
54
Aurimas Liutikasbb78f3f2017-06-19 11:30:37 -070055def getFullSdkPath() {
Aurimas Liutikasb06771d2017-04-20 09:46:49 -070056 final String osName = System.getProperty("os.name").toLowerCase();
57 final boolean isMacOsX =
58 osName.contains("mac os x") || osName.contains("darwin") || osName.contains("osx");
59 final String platform = isMacOsX ? 'darwin' : 'linux'
Aurimas Liutikasbb78f3f2017-06-19 11:30:37 -070060 return "${repos.prebuiltsRoot}/fullsdk-${platform}"
61}
62
63def setSdkInLocalPropertiesFile() {
Aurimas Liutikasd1aad142017-11-28 16:27:27 -080064 ext.buildToolsVersion = '27.0.1'
Aurimas Liutikasbb78f3f2017-06-19 11:30:37 -070065 final String fullSdkPath = getFullSdkPath();
Yigit Boyar88c16ce2017-02-08 16:06:14 -080066 if (file(fullSdkPath).exists()) {
67 gradle.ext.currentSdk = 26
Alan Viveretteeb9f3322017-03-09 16:29:57 -050068 project.ext.androidJar =
69 files("${fullSdkPath}/platforms/android-${gradle.currentSdk}/android.jar")
70 project.ext.androidSrcJar =
71 file("${fullSdkPath}/platforms/android-${gradle.currentSdk}/android-stubs-src.jar")
Alan Viverette810a1482017-03-20 12:43:43 -040072 project.ext.androidApiTxt = null
Yigit Boyar88c16ce2017-02-08 16:06:14 -080073 File props = file("local.properties")
74 props.write "sdk.dir=${fullSdkPath}"
Aurimas Liutikas3c666002017-03-08 19:30:28 -080075 ext.usingFullSdk = true
Yigit Boyar88c16ce2017-02-08 16:06:14 -080076 } else {
77 gradle.ext.currentSdk = 'current'
Aurimas Liutikas9ab3b4c2017-04-19 09:33:27 -070078 project.ext.androidJar = files("${repos.prebuiltsRoot}/sdk/current/android.jar")
Alan Viverette810a1482017-03-20 12:43:43 -040079 project.ext.androidSrcJar = null
Aurimas Liutikas9ab3b4c2017-04-19 09:33:27 -070080 project.ext.androidApiTxt = file("${repos.prebuiltsRoot}/sdk/api/26.txt")
Aurimas Liutikasbb78f3f2017-06-19 11:30:37 -070081 System.setProperty('android.dir', "${supportRootFolder}/../../")
Yigit Boyar88c16ce2017-02-08 16:06:14 -080082 File props = file("local.properties")
83 props.write "android.dir=../../"
Aurimas Liutikas3c666002017-03-08 19:30:28 -080084 ext.usingFullSdk = false
Yigit Boyar88c16ce2017-02-08 16:06:14 -080085 }
86}
87
88def setupRepoOutAndBuildNumber() {
Yigit Boyaref300662017-05-01 11:52:07 -070089 // common support repo folder which works well for prebuilts.
Yigit Boyar88c16ce2017-02-08 16:06:14 -080090 ext.supportRepoOut = ''
Aurimas Liutikas76542da2017-06-29 17:00:29 -070091 ext.buildNumber = "0"
Yigit Boyar88c16ce2017-02-08 16:06:14 -080092 /*
93 * With the build server you are given two env variables.
94 * The OUT_DIR is a temporary directory you can use to put things during the build.
95 * The DIST_DIR is where you want to save things from the build.
96 *
97 * The build server will copy the contents of DIST_DIR to somewhere and make it available.
98 */
Yigit Boyar7bfacb72017-03-02 14:27:41 -080099 if (ext.runningInBuildServer) {
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800100 buildDir = new File(System.env.OUT_DIR + '/gradle/frameworks/support/build')
101 .getCanonicalFile()
102 project.ext.distDir = new File(System.env.DIST_DIR).getCanonicalFile()
103
104 // the build server does not pass the build number so we infer it from the last folder of
105 // the dist path.
106 ext.buildNumber = project.ext.distDir.getName()
Aurimas Liutikasa0150042017-04-21 09:46:12 -0700107
108 // the build server should always print out full stack traces for any failures.
109 gradle.startParameter.showStacktrace = ShowStacktrace.ALWAYS
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800110 } else {
111 buildDir = file("${ext.supportRootFolder}/../../out/host/gradle/frameworks/support/build")
112 project.ext.distDir = new File("${ext.supportRootFolder}/../../out/dist")
113 }
114 subprojects {
115 // Change buildDir first so that all plugins pick up the new value.
116 project.buildDir = new File("$project.parent.buildDir/../$project.name/build")
117 }
118 ext.supportRepoOut = new File(buildDir, 'support_repo')
119 ext.testApkDistOut = ext.distDir
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800120 ext.testResultsDistDir = new File(distDir, "host-test-reports")
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800121 ext.docsDir = new File(buildDir, 'javadoc')
122}
123
Aurimas Liutikas38e8f4d2017-06-16 08:31:03 -0700124def configureBuildOnServer() {
125 def buildOnServerTask = rootProject.tasks.create("buildOnServer")
126 rootProject.tasks.whenTaskAdded { task ->
Aurimas Liutikas212905f2017-10-09 15:28:28 -0700127 if ("createArchive".equals(task.name) || "distDocs".equals(task.name)) {
Aurimas Liutikas38e8f4d2017-06-16 08:31:03 -0700128 buildOnServerTask.dependsOn task
129 }
130 }
131
132 subprojects {
133 project.tasks.whenTaskAdded { task ->
134 if ("assembleErrorProne".equals(task.name) || "assembleAndroidTest".equals(task.name)) {
135 buildOnServerTask.dependsOn task
136 }
137 }
138 }
139}
140
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800141def configureSubProjects() {
142 // lint every library
143 def lintTask = project.tasks.create("lint")
144 subprojects {
Aurimas Liutikas6509a1a2017-05-09 16:25:43 -0700145 repos.addMavenRepositories(repositories)
146
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800147 // Only modify Android projects.
Aurimas Liutikaseca7a072017-07-11 01:11:52 +0000148 if (project.name.equals('doclava')
149 || project.name.equals('jdiff')
Hyundo Moonbeffc442017-11-06 15:08:43 +0900150 || project.name.equals('noto-emoji-compat')) {
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800151 // disable tests and return
152 project.tasks.whenTaskAdded { task ->
153 if (task instanceof org.gradle.api.tasks.testing.Test) {
154 task.enabled = false
155 }
156 }
157 return
158 }
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800159
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800160 project.ext.currentSdk = gradle.ext.currentSdk
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800161
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800162 project.plugins.whenPluginAdded { plugin ->
163 def isAndroidLibrary = "com.android.build.gradle.LibraryPlugin"
164 .equals(plugin.class.name)
165 def isAndroidApp = "com.android.build.gradle.AppPlugin".equals(plugin.class.name)
166 def isJavaLibrary = "org.gradle.api.plugins.JavaPlugin".equals(plugin.class.name)
167
168 if (isAndroidLibrary || isAndroidApp) {
169 project.android.buildToolsVersion = rootProject.buildToolsVersion
170
171 // Enable code coverage for debug builds only if we are not running inside the IDE,
172 // since enabling coverage reports breaks the method parameter resolution in the IDE
173 // debugger.
174 project.android.buildTypes.debug.testCoverageEnabled =
Sergey Vasilinetsac8e72b2017-04-26 15:55:17 -0700175 !project.hasProperty('android.injected.invoked.from.ide')
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800176
177 // Copy the class files in a jar to be later used to generate code coverage report
178 project.android.testVariants.all { v ->
179 // check if the variant has any source files
180 // and test coverage is enabled
181 if (v.buildType.testCoverageEnabled
182 && v.sourceSets.any { !it.java.sourceFiles.isEmpty() }) {
183 def jarifyTask = project.tasks.create(
184 name: "package${v.name.capitalize()}ClassFilesForCoverageReport",
185 type: Jar) {
186 from v.testedVariant.javaCompile.destinationDir
187 exclude "**/R.class"
188 exclude "**/R\$*.class"
189 exclude "**/BuildConfig.class"
190 destinationDir file(project.distDir)
Aurimas Liutikas76542da2017-06-29 17:00:29 -0700191 archiveName "${project.name}-${v.baseName}-allclasses.jar"
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800192 }
Aurimas Liutikas21b7fce2017-06-23 09:52:08 -0700193
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800194 def collectJacocoAntPackages = project.tasks.create(
195 name: "collectJacocoAntPackages",
196 type: Jar) {
Aurimas Liutikas21b7fce2017-06-23 09:52:08 -0700197 inputs.files project.configurations[JacocoPlugin.ANT_CONFIGURATION_NAME]
198 from {
Aurimas Liutikas585a9342017-06-25 16:07:56 -0700199 project.configurations[JacocoPlugin.ANT_CONFIGURATION_NAME]
200 .resolvedConfiguration
201 .resolvedArtifacts.collect{ zipTree(it.getFile()) }} {
Aurimas Liutikas21b7fce2017-06-23 09:52:08 -0700202 // exclude all the signatures the jar might have
203 exclude "META-INF/*.SF"
204 exclude "META-INF/*.DSA"
205 exclude "META-INF/*.RSA"
206 }
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800207 destinationDir file(project.distDir)
Aurimas Liutikas21b7fce2017-06-23 09:52:08 -0700208 archiveName "jacocoant.jar"
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800209 }
Aurimas Liutikas21b7fce2017-06-23 09:52:08 -0700210
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800211 jarifyTask.dependsOn v.getJavaCompiler()
Aurimas Liutikas21b7fce2017-06-23 09:52:08 -0700212 v.assemble.dependsOn jarifyTask , collectJacocoAntPackages
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800213 }
214 }
215
216 // Enforce NewApi lint check as fatal.
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800217 project.android.lintOptions.fatal 'NewApi'
Aurimas Liutikas6c625702017-09-20 14:35:47 -0700218 lintTask.dependsOn {project.lint}
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800219 }
220
221 if (isAndroidLibrary || isJavaLibrary) {
222 // Add library to the aggregate dependency report.
223 task allDeps(type: DependencyReportTask) {}
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800224
Aurimas Liutikas6509a1a2017-05-09 16:25:43 -0700225 project.afterEvaluate {
226 Upload uploadTask = (Upload) project.tasks.uploadArchives;
227 uploadTask.repositories.mavenDeployer {
Aurimas Liutikas279780d2017-08-09 14:03:59 -0700228 repository(url: uri("$rootProject.ext.supportRepoOut"))
229 setUniqueVersion(true)
Aurimas Liutikas6509a1a2017-05-09 16:25:43 -0700230 }
231
232 // Before the upload, make sure the repo is ready.
233 uploadTask.dependsOn rootProject.tasks.prepareRepo
234
Aurimas Liutikas6509a1a2017-05-09 16:25:43 -0700235 // Make the mainupload depend on this one.
236 mainUpload.dependsOn uploadTask
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800237 }
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800238 }
239 }
240
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800241 // Copy instrumentation test APKs and app APKs into the dist dir
242 // For test apks, they are uploaded only if we have java test sources.
243 // For regular app apks, they are uploaded only if they have java sources.
244 project.tasks.whenTaskAdded { task ->
245 if (task.name.startsWith("packageDebug")) {
246 def testApk = task.name.contains("AndroidTest")
247 task.doLast {
248 def source = testApk ? project.android.sourceSets.androidTest
249 : project.android.sourceSets.main
Yigit Boyare606d6d2017-09-07 12:37:36 -0700250 def hasKotlinSources = false
251 if (source.hasProperty('kotlin')) {
252 if (!source.kotlin.files.isEmpty()) {
253 hasKotlinSources = true
254 } else {
255 // kotlin files does not show in java sources due to the *.java filter
256 // so we need to check them manually
257 hasKotlinSources = source.java.sourceDirectoryTrees.any {
258 !fileTree(dir: it.dir, include:'**/*.kt').files.isEmpty()
259 }
260 }
261 }
262 def hasSourceCode = !source.java.sourceFiles.isEmpty() || hasKotlinSources
263 if (task.hasProperty("outputDirectory") && (hasSourceCode || !testApk)) {
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800264 copy {
Aurimas Liutikasef3b4922017-06-28 10:44:59 -0700265 from(task.outputDirectory)
266 include '*.apk'
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800267 into(rootProject.ext.testApkDistOut)
268 rename { String fileName ->
Hyundo Moon9938e172017-07-26 20:51:11 +0900269 // Exclude media-compat-test-* modules from existing support library
270 // presubmit tests.
271 if (fileName.contains("media-compat-test")) {
272 fileName.replace("-debug-androidTest", "")
Yigit Boyar96a0fcd2017-08-25 18:18:28 -0700273 } else {
274 // multiple modules may have the same name so prefix the name with
275 // the module's path to ensure it is unique.
276 // e.g. palette-v7-debug-androidTest.apk becomes
277 // support-palette-v7_palette-v7-debug-androidTest.apk
278 "${project.getPath().replace(':', '-').substring(1)}_${fileName}"
Hyundo Moon9938e172017-07-26 20:51:11 +0900279 }
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800280 }
281 }
282 }
283 }
284 }
285 }
286
287 // copy host side test results to DIST
288 project.tasks.whenTaskAdded { task ->
289 if (task instanceof org.gradle.api.tasks.testing.Test) {
290 def junitReport = task.reports.junitXml
291 if (junitReport.enabled) {
292 def zipTask = project.tasks.create(name : "zipResultsOf${task.name.capitalize()}", type : Zip) {
293 destinationDir(testResultsDistDir)
Yigit Boyar278676d2017-03-10 15:29:11 -0800294 // first one is always :, drop it.
295 archiveName("${project.getPath().split(":").join("_").substring(1)}.zip")
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800296 }
297 if (project.rootProject.ext.runningInBuildServer) {
298 task.ignoreFailures = true
299 }
300 task.finalizedBy zipTask
301 task.doFirst {
302 zipTask.from(junitReport.destination)
303 }
304 }
305 }
306 }
307
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800308 project.afterEvaluate { p ->
309 // remove dependency on the test so that we still get coverage even if some tests fail
310 p.tasks.findAll { it instanceof JacocoReportTask }.each { task ->
311 def toBeRemoved = new ArrayList()
312 def dependencyList = task.taskDependencies.values
313 dependencyList.each { dep ->
314 if (dep instanceof String) {
315 def t = tasks.findByName(dep)
316 if (t instanceof DeviceProviderInstrumentTestTask) {
317 toBeRemoved.add(dep)
318 task.mustRunAfter(t)
319 }
320 }
321 }
322 toBeRemoved.each { dep ->
323 dependencyList.remove(dep)
324 }
325 }
326 }
327 }
328}
329
330def setupRelease() {
331 apply from: "${ext.supportRootFolder}/buildSrc/release.gradle"
332}
333
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800334ext.init.enableDoclavaAndJDiff = this.&enableDoclavaAndJDiff
335ext.init.setSdkInLocalPropertiesFile = this.&setSdkInLocalPropertiesFile
336ext.init.setupRepoOutAndBuildNumber = this.&setupRepoOutAndBuildNumber
337ext.init.setupRelease = this.&setupRelease
Aurimas Liutikas38e8f4d2017-06-16 08:31:03 -0700338ext.init.configureSubProjects = this.&configureSubProjects
Yigit Boyare1bbf712017-03-08 13:52:37 -0800339ext.init.configureBuildOnServer = this.&configureBuildOnServer