blob: b0f7192a999fa4a3870f87eba0199048b1cb1eca [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
20import com.google.common.base.Charsets
21import com.google.common.io.Files
Aurimas Liutikas9ab3b4c32017-04-19 09:33:27 -070022
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 Boyar88c16ce2017-02-08 16:06:14 -080033
Aurimas Liutikas9ab3b4c32017-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"
Alan Viverette5b3946f2017-04-27 09:59:22 -040037ext.docs = [:]
38ext.docs.offline = rootProject.getProperties().containsKey("offlineDocs")
39ext.docs.dac = [
40 libraryroot: "android/support",
41 dataname: "SUPPORT_DATA"
42]
Yigit Boyar88c16ce2017-02-08 16:06:14 -080043
44def loadDefaultVersions() {
45 apply from: "${supportRootFolder}/buildSrc/versions.gradle"
46}
47
Yigit Boyar88c16ce2017-02-08 16:06:14 -080048def enableDoclavaAndJDiff(p) {
49 p.configurations {
50 doclava
51 jdiff
52 }
53
54 p.dependencies {
55 doclava project(':doclava')
56 jdiff project(':jdiff')
57 jdiff libs.xml_parser_apis
58 jdiff libs.xerces_impl
59 }
60 apply from: "${ext.supportRootFolder}/buildSrc/diff_and_docs.gradle"
61}
62
63def setSdkInLocalPropertiesFile() {
Aurimas Liutikasb06771d2017-04-20 09:46:49 -070064 final String osName = System.getProperty("os.name").toLowerCase();
65 final boolean isMacOsX =
66 osName.contains("mac os x") || osName.contains("darwin") || osName.contains("osx");
67 final String platform = isMacOsX ? 'darwin' : 'linux'
Yigit Boyar88c16ce2017-02-08 16:06:14 -080068 System.setProperty('android.dir', "${supportRootFolder}/../../")
Aurimas Liutikasd2d9bda2017-03-03 16:06:39 -080069 ext.buildToolsVersion = '26.0.0'
Aurimas Liutikas9ab3b4c32017-04-19 09:33:27 -070070 final String fullSdkPath = "${repos.prebuiltsRoot}/fullsdk-${platform}"
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
Aurimas Liutikas9ab3b4c32017-04-19 09:33:27 -070078 System.setProperty('android.home', "${repos.prebuiltsRoot}/fullsdk-${platform}")
Yigit Boyar88c16ce2017-02-08 16:06:14 -080079 File props = file("local.properties")
80 props.write "sdk.dir=${fullSdkPath}"
Aurimas Liutikas3c666002017-03-08 19:30:28 -080081 ext.usingFullSdk = true
Yigit Boyar88c16ce2017-02-08 16:06:14 -080082 } else {
83 gradle.ext.currentSdk = 'current'
Aurimas Liutikas9ab3b4c32017-04-19 09:33:27 -070084 project.ext.androidJar = files("${repos.prebuiltsRoot}/sdk/current/android.jar")
Alan Viverette810a1482017-03-20 12:43:43 -040085 project.ext.androidSrcJar = null
Aurimas Liutikas9ab3b4c32017-04-19 09:33:27 -070086 project.ext.androidApiTxt = file("${repos.prebuiltsRoot}/sdk/api/26.txt")
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 = ''
Yigit Boyar88c16ce2017-02-08 16:06:14 -080098 ext.buildNumber = Integer.toString(ext.extraVersion)
99
100 /*
101 * With the build server you are given two env variables.
102 * The OUT_DIR is a temporary directory you can use to put things during the build.
103 * The DIST_DIR is where you want to save things from the build.
104 *
105 * The build server will copy the contents of DIST_DIR to somewhere and make it available.
106 */
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800107 if (ext.runningInBuildServer) {
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800108 buildDir = new File(System.env.OUT_DIR + '/gradle/frameworks/support/build')
109 .getCanonicalFile()
110 project.ext.distDir = new File(System.env.DIST_DIR).getCanonicalFile()
111
112 // the build server does not pass the build number so we infer it from the last folder of
113 // the dist path.
114 ext.buildNumber = project.ext.distDir.getName()
Aurimas Liutikasa0150042017-04-21 09:46:12 -0700115
116 // the build server should always print out full stack traces for any failures.
117 gradle.startParameter.showStacktrace = ShowStacktrace.ALWAYS
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800118 } else {
119 buildDir = file("${ext.supportRootFolder}/../../out/host/gradle/frameworks/support/build")
120 project.ext.distDir = new File("${ext.supportRootFolder}/../../out/dist")
121 }
122 subprojects {
123 // Change buildDir first so that all plugins pick up the new value.
124 project.buildDir = new File("$project.parent.buildDir/../$project.name/build")
125 }
126 ext.supportRepoOut = new File(buildDir, 'support_repo')
Yigit Boyaref300662017-05-01 11:52:07 -0700127 ext.artifactoryRepoOut = new File(buildDir, 'artifactory_repo')
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800128 ext.testApkDistOut = ext.distDir
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800129 ext.testResultsDistDir = new File(distDir, "host-test-reports")
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800130 ext.docsDir = new File(buildDir, 'javadoc')
131}
132
133def configureSubProjects() {
134 // lint every library
135 def lintTask = project.tasks.create("lint")
136 subprojects {
137 // Only modify Android projects.
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800138 if (project.name.equals('doclava') || project.name.equals('jdiff')) {
139 // disable tests and return
140 project.tasks.whenTaskAdded { task ->
141 if (task instanceof org.gradle.api.tasks.testing.Test) {
142 task.enabled = false
143 }
144 }
145 return
146 }
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800147
148 // Current SDK is set in studioCompat.gradle.
149 project.ext.currentSdk = gradle.ext.currentSdk
150 apply plugin: 'maven'
151
152 version = rootProject.ext.supportVersion
153 group = 'com.android.support'
154
Aurimas Liutikas9ab3b4c32017-04-19 09:33:27 -0700155 repos.addMavenRepositories(repositories)
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800156 project.plugins.whenPluginAdded { plugin ->
157 def isAndroidLibrary = "com.android.build.gradle.LibraryPlugin"
158 .equals(plugin.class.name)
159 def isAndroidApp = "com.android.build.gradle.AppPlugin".equals(plugin.class.name)
160 def isJavaLibrary = "org.gradle.api.plugins.JavaPlugin".equals(plugin.class.name)
161
162 if (isAndroidLibrary || isAndroidApp) {
163 project.android.buildToolsVersion = rootProject.buildToolsVersion
164
165 // Enable code coverage for debug builds only if we are not running inside the IDE,
166 // since enabling coverage reports breaks the method parameter resolution in the IDE
167 // debugger.
168 project.android.buildTypes.debug.testCoverageEnabled =
Sergey Vasilinetsac8e72b2017-04-26 15:55:17 -0700169 !project.hasProperty('android.injected.invoked.from.ide')
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800170
171 // Copy the class files in a jar to be later used to generate code coverage report
172 project.android.testVariants.all { v ->
173 // check if the variant has any source files
174 // and test coverage is enabled
175 if (v.buildType.testCoverageEnabled
176 && v.sourceSets.any { !it.java.sourceFiles.isEmpty() }) {
177 def jarifyTask = project.tasks.create(
178 name: "package${v.name.capitalize()}ClassFilesForCoverageReport",
179 type: Jar) {
180 from v.testedVariant.javaCompile.destinationDir
181 exclude "**/R.class"
182 exclude "**/R\$*.class"
183 exclude "**/BuildConfig.class"
184 destinationDir file(project.distDir)
185 archiveName "${project.archivesBaseName}-${v.baseName}-allclasses.jar"
186 }
187 def jacocoAntConfig =
188 project.configurations[JacocoPlugin.ANT_CONFIGURATION_NAME]
189 def jacocoAntArtifacts = jacocoAntConfig.resolvedConfiguration
190 .resolvedArtifacts
191 def version = jacocoAntArtifacts.find { "org.jacoco.ant".equals(it.name) }
192 .moduleVersion.id.version
193 def collectJacocoAntPackages = project.tasks.create(
194 name: "collectJacocoAntPackages",
195 type: Jar) {
196 from(jacocoAntArtifacts.collect { zipTree(it.getFile()) }) {
197 // exclude all the signatures the jar might have
198 exclude "META-INF/*.SF"
199 exclude "META-INF/*.DSA"
200 exclude "META-INF/*.RSA"
201 }
202 destinationDir file(project.distDir)
203 archiveName "jacocoant-" + version + ".jar"
204 }
205 jarifyTask.dependsOn v.getJavaCompiler()
206 v.assemble.dependsOn jarifyTask, collectJacocoAntPackages
207 }
208 }
209
210 // Enforce NewApi lint check as fatal.
211 project.android.lintOptions.check 'NewApi'
212 project.android.lintOptions.fatal 'NewApi'
213 lintTask.dependsOn project.lint
214 }
215
216 if (isAndroidLibrary || isJavaLibrary) {
217 // Add library to the aggregate dependency report.
218 task allDeps(type: DependencyReportTask) {}
Yigit Boyaref300662017-05-01 11:52:07 -0700219 // create a release task that produces artifactory friends artifacts
220 // a.k.a. unique versions for snapshots with their maven-metadata files.
221 task artifactoryRelease(type : Upload) {
222 configuration = configurations.archives
223 repositories {
224 mavenDeployer {
225 repository(url: uri("$rootProject.ext.artifactoryRepoOut"))
226 setUniqueVersion(true)
227 }
228 }
229 }
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800230 // Create release and separate zip task for library.
231 task release(type: Upload) {
232 configuration = configurations.archives
233 repositories {
234 mavenDeployer {
235 repository(url: uri("$rootProject.ext.supportRepoOut"))
236
237 // Disable unique names for SNAPSHOTS so they can be updated in place.
238 setUniqueVersion(false)
239 doLast {
240 // Remove any invalid maven-metadata.xml files that may have been
241 // created for SNAPSHOT versions that are *not* uniquely versioned.
242 pom*.each { pom ->
243 if (pom.version.endsWith('-SNAPSHOT')) {
244 final File artifactDir = new File(
245 rootProject.ext.supportRepoOut,
246 pom.groupId.replace('.', '/')
247 + '/' + pom.artifactId
248 + '/' + pom.version)
249 delete fileTree(dir: artifactDir,
250 include: 'maven-metadata.xml*')
251 }
252 }
253 }
254 }
255 }
256 }
Yigit Boyaref300662017-05-01 11:52:07 -0700257 artifactoryRelease.dependsOn release
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800258
259 def deployer = release.repositories.mavenDeployer
260 deployer.pom*.whenConfigured { pom ->
261 pom.dependencies.findAll { dep ->
262 dep.groupId == 'com.android.support' &&
263 dep.artifactId != 'support-annotations'
264 }*.type = 'aar'
265 }
266
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800267 // Before the upload, make sure the repo is ready.
268 release.dependsOn rootProject.tasks.prepareRepo
269
270 // Make the mainupload depend on this one.
271 mainUpload.dependsOn release
Yigit Boyaref300662017-05-01 11:52:07 -0700272 mainUpload.dependsOn artifactoryRelease
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800273 }
274 }
275
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800276 // Copy instrumentation test APKs and app APKs into the dist dir
277 // For test apks, they are uploaded only if we have java test sources.
278 // For regular app apks, they are uploaded only if they have java sources.
279 project.tasks.whenTaskAdded { task ->
280 if (task.name.startsWith("packageDebug")) {
281 def testApk = task.name.contains("AndroidTest")
282 task.doLast {
283 def source = testApk ? project.android.sourceSets.androidTest
284 : project.android.sourceSets.main
285 if (task.hasProperty("outputFile") && !source.java.sourceFiles.isEmpty()) {
286 copy {
287 from(task.outputFile)
288 into(rootProject.ext.testApkDistOut)
289 rename { String fileName ->
290 // multiple modules may have the same name so prefix the name with
291 // the module's path to ensure it is unique.
292 // e.g. palette-v7-debug-androidTest.apk becomes
293 // support-palette-v7_palette-v7-debug-androidTest.apk
294 "${project.getPath().replace(':', '-').substring(1)}_${fileName}"
295 }
296 }
297 }
298 }
299 }
300 }
301
302 // copy host side test results to DIST
303 project.tasks.whenTaskAdded { task ->
304 if (task instanceof org.gradle.api.tasks.testing.Test) {
305 def junitReport = task.reports.junitXml
306 if (junitReport.enabled) {
307 def zipTask = project.tasks.create(name : "zipResultsOf${task.name.capitalize()}", type : Zip) {
308 destinationDir(testResultsDistDir)
Yigit Boyar278676d2017-03-10 15:29:11 -0800309 // first one is always :, drop it.
310 archiveName("${project.getPath().split(":").join("_").substring(1)}.zip")
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800311 }
312 if (project.rootProject.ext.runningInBuildServer) {
313 task.ignoreFailures = true
314 }
315 task.finalizedBy zipTask
316 task.doFirst {
317 zipTask.from(junitReport.destination)
318 }
319 }
320 }
321 }
322
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800323 project.afterEvaluate {
324 // The archivesBaseName isn't available initially, so set it now
325 def createZipTask = project.tasks.findByName("createSeparateZip")
326 if (createZipTask != null) {
327 createZipTask.appendix = archivesBaseName
328 createZipTask.from versionDir()
329 }
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800330 }
331
332 project.afterEvaluate { p ->
333 // remove dependency on the test so that we still get coverage even if some tests fail
334 p.tasks.findAll { it instanceof JacocoReportTask }.each { task ->
335 def toBeRemoved = new ArrayList()
336 def dependencyList = task.taskDependencies.values
337 dependencyList.each { dep ->
338 if (dep instanceof String) {
339 def t = tasks.findByName(dep)
340 if (t instanceof DeviceProviderInstrumentTestTask) {
341 toBeRemoved.add(dep)
342 task.mustRunAfter(t)
343 }
344 }
345 }
346 toBeRemoved.each { dep ->
347 dependencyList.remove(dep)
348 }
349 }
350 }
351 }
352}
353
354def setupRelease() {
355 apply from: "${ext.supportRootFolder}/buildSrc/release.gradle"
356}
357
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800358ext.init.enableDoclavaAndJDiff = this.&enableDoclavaAndJDiff
359ext.init.setSdkInLocalPropertiesFile = this.&setSdkInLocalPropertiesFile
360ext.init.setupRepoOutAndBuildNumber = this.&setupRepoOutAndBuildNumber
361ext.init.setupRelease = this.&setupRelease
362ext.init.loadDefaultVersions = this.&loadDefaultVersions
363ext.init.configureSubProjects = this.&configureSubProjects