blob: 91ab17f5040e6f30a57d991773f6e9e545d77060 [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
Yigit Boyar88c16ce2017-02-08 16:06:14 -080023
24def supportRoot = ext.supportRootFolder
25if (supportRoot == null) {
26 throw new RuntimeException("variable supportRootFolder is not set. you must set it before" +
27 " including this script")
28}
29def init = new Properties()
30ext.init = init
Alan Viverette1b862372017-03-22 11:32:28 -040031ext.init.debugKeystore = file("${supportRoot}/development/keystore/debug.keystore")
Yigit Boyar88c16ce2017-02-08 16:06:14 -080032
Aurimas Liutikas9ab3b4c32017-04-19 09:33:27 -070033ext.runningInBuildServer = System.env.DIST_DIR != null && System.env.OUT_DIR != null
Yigit Boyar88c16ce2017-02-08 16:06:14 -080034
35apply from: "${supportRoot}/buildSrc/dependencies.gradle"
Yigit Boyar63e6c672017-03-31 13:32:17 -070036ext.buildOfflineDocs = rootProject.getProperties().containsKey("offlineDocs")
Yigit Boyar88c16ce2017-02-08 16:06:14 -080037
38def loadDefaultVersions() {
39 apply from: "${supportRootFolder}/buildSrc/versions.gradle"
40}
41
Yigit Boyar88c16ce2017-02-08 16:06:14 -080042def enableDoclavaAndJDiff(p) {
43 p.configurations {
44 doclava
45 jdiff
46 }
47
48 p.dependencies {
49 doclava project(':doclava')
50 jdiff project(':jdiff')
51 jdiff libs.xml_parser_apis
52 jdiff libs.xerces_impl
53 }
54 apply from: "${ext.supportRootFolder}/buildSrc/diff_and_docs.gradle"
55}
56
57def setSdkInLocalPropertiesFile() {
Aurimas Liutikasb06771d2017-04-20 09:46:49 -070058 final String osName = System.getProperty("os.name").toLowerCase();
59 final boolean isMacOsX =
60 osName.contains("mac os x") || osName.contains("darwin") || osName.contains("osx");
61 final String platform = isMacOsX ? 'darwin' : 'linux'
Yigit Boyar88c16ce2017-02-08 16:06:14 -080062 System.setProperty('android.dir', "${supportRootFolder}/../../")
Aurimas Liutikasd2d9bda2017-03-03 16:06:39 -080063 ext.buildToolsVersion = '26.0.0'
Aurimas Liutikas9ab3b4c32017-04-19 09:33:27 -070064 final String fullSdkPath = "${repos.prebuiltsRoot}/fullsdk-${platform}"
Yigit Boyar88c16ce2017-02-08 16:06:14 -080065 if (file(fullSdkPath).exists()) {
66 gradle.ext.currentSdk = 26
Alan Viveretteeb9f3322017-03-09 16:29:57 -050067 project.ext.androidJar =
68 files("${fullSdkPath}/platforms/android-${gradle.currentSdk}/android.jar")
69 project.ext.androidSrcJar =
70 file("${fullSdkPath}/platforms/android-${gradle.currentSdk}/android-stubs-src.jar")
Alan Viverette810a1482017-03-20 12:43:43 -040071 project.ext.androidApiTxt = null
Aurimas Liutikas9ab3b4c32017-04-19 09:33:27 -070072 System.setProperty('android.home', "${repos.prebuiltsRoot}/fullsdk-${platform}")
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 Liutikas9ab3b4c32017-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 Liutikas9ab3b4c32017-04-19 09:33:27 -070080 project.ext.androidApiTxt = file("${repos.prebuiltsRoot}/sdk/api/26.txt")
Yigit Boyar88c16ce2017-02-08 16:06:14 -080081 File props = file("local.properties")
82 props.write "android.dir=../../"
Aurimas Liutikas3c666002017-03-08 19:30:28 -080083 ext.usingFullSdk = false
Yigit Boyar88c16ce2017-02-08 16:06:14 -080084 }
85}
86
87def setupRepoOutAndBuildNumber() {
88 ext.supportRepoOut = ''
89 ext.buildNumber = Integer.toString(ext.extraVersion)
90
91 /*
92 * With the build server you are given two env variables.
93 * The OUT_DIR is a temporary directory you can use to put things during the build.
94 * The DIST_DIR is where you want to save things from the build.
95 *
96 * The build server will copy the contents of DIST_DIR to somewhere and make it available.
97 */
Yigit Boyar7bfacb72017-03-02 14:27:41 -080098 if (ext.runningInBuildServer) {
Yigit Boyar88c16ce2017-02-08 16:06:14 -080099 buildDir = new File(System.env.OUT_DIR + '/gradle/frameworks/support/build')
100 .getCanonicalFile()
101 project.ext.distDir = new File(System.env.DIST_DIR).getCanonicalFile()
102
103 // the build server does not pass the build number so we infer it from the last folder of
104 // the dist path.
105 ext.buildNumber = project.ext.distDir.getName()
106 } else {
107 buildDir = file("${ext.supportRootFolder}/../../out/host/gradle/frameworks/support/build")
108 project.ext.distDir = new File("${ext.supportRootFolder}/../../out/dist")
109 }
110 subprojects {
111 // Change buildDir first so that all plugins pick up the new value.
112 project.buildDir = new File("$project.parent.buildDir/../$project.name/build")
113 }
114 ext.supportRepoOut = new File(buildDir, 'support_repo')
115 ext.testApkDistOut = ext.distDir
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800116 ext.testResultsDistDir = new File(distDir, "host-test-reports")
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800117 ext.docsDir = new File(buildDir, 'javadoc')
118}
119
120def configureSubProjects() {
121 // lint every library
122 def lintTask = project.tasks.create("lint")
123 subprojects {
124 // Only modify Android projects.
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800125 if (project.name.equals('doclava') || project.name.equals('jdiff')) {
126 // disable tests and return
127 project.tasks.whenTaskAdded { task ->
128 if (task instanceof org.gradle.api.tasks.testing.Test) {
129 task.enabled = false
130 }
131 }
132 return
133 }
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800134
135 // Current SDK is set in studioCompat.gradle.
136 project.ext.currentSdk = gradle.ext.currentSdk
137 apply plugin: 'maven'
138
139 version = rootProject.ext.supportVersion
140 group = 'com.android.support'
141
Aurimas Liutikas9ab3b4c32017-04-19 09:33:27 -0700142 repos.addMavenRepositories(repositories)
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800143 project.plugins.whenPluginAdded { plugin ->
144 def isAndroidLibrary = "com.android.build.gradle.LibraryPlugin"
145 .equals(plugin.class.name)
146 def isAndroidApp = "com.android.build.gradle.AppPlugin".equals(plugin.class.name)
147 def isJavaLibrary = "org.gradle.api.plugins.JavaPlugin".equals(plugin.class.name)
148
149 if (isAndroidLibrary || isAndroidApp) {
150 project.android.buildToolsVersion = rootProject.buildToolsVersion
151
152 // Enable code coverage for debug builds only if we are not running inside the IDE,
153 // since enabling coverage reports breaks the method parameter resolution in the IDE
154 // debugger.
155 project.android.buildTypes.debug.testCoverageEnabled =
156 !hasProperty('android.injected.invoked.from.ide')
157
158 // Copy the class files in a jar to be later used to generate code coverage report
159 project.android.testVariants.all { v ->
160 // check if the variant has any source files
161 // and test coverage is enabled
162 if (v.buildType.testCoverageEnabled
163 && v.sourceSets.any { !it.java.sourceFiles.isEmpty() }) {
164 def jarifyTask = project.tasks.create(
165 name: "package${v.name.capitalize()}ClassFilesForCoverageReport",
166 type: Jar) {
167 from v.testedVariant.javaCompile.destinationDir
168 exclude "**/R.class"
169 exclude "**/R\$*.class"
170 exclude "**/BuildConfig.class"
171 destinationDir file(project.distDir)
172 archiveName "${project.archivesBaseName}-${v.baseName}-allclasses.jar"
173 }
174 def jacocoAntConfig =
175 project.configurations[JacocoPlugin.ANT_CONFIGURATION_NAME]
176 def jacocoAntArtifacts = jacocoAntConfig.resolvedConfiguration
177 .resolvedArtifacts
178 def version = jacocoAntArtifacts.find { "org.jacoco.ant".equals(it.name) }
179 .moduleVersion.id.version
180 def collectJacocoAntPackages = project.tasks.create(
181 name: "collectJacocoAntPackages",
182 type: Jar) {
183 from(jacocoAntArtifacts.collect { zipTree(it.getFile()) }) {
184 // exclude all the signatures the jar might have
185 exclude "META-INF/*.SF"
186 exclude "META-INF/*.DSA"
187 exclude "META-INF/*.RSA"
188 }
189 destinationDir file(project.distDir)
190 archiveName "jacocoant-" + version + ".jar"
191 }
192 jarifyTask.dependsOn v.getJavaCompiler()
193 v.assemble.dependsOn jarifyTask, collectJacocoAntPackages
194 }
195 }
196
197 // Enforce NewApi lint check as fatal.
198 project.android.lintOptions.check 'NewApi'
199 project.android.lintOptions.fatal 'NewApi'
200 lintTask.dependsOn project.lint
201 }
202
203 if (isAndroidLibrary || isJavaLibrary) {
204 // Add library to the aggregate dependency report.
205 task allDeps(type: DependencyReportTask) {}
206
207 // Create release and separate zip task for library.
208 task release(type: Upload) {
209 configuration = configurations.archives
210 repositories {
211 mavenDeployer {
212 repository(url: uri("$rootProject.ext.supportRepoOut"))
213
214 // Disable unique names for SNAPSHOTS so they can be updated in place.
215 setUniqueVersion(false)
216 doLast {
217 // Remove any invalid maven-metadata.xml files that may have been
218 // created for SNAPSHOT versions that are *not* uniquely versioned.
219 pom*.each { pom ->
220 if (pom.version.endsWith('-SNAPSHOT')) {
221 final File artifactDir = new File(
222 rootProject.ext.supportRepoOut,
223 pom.groupId.replace('.', '/')
224 + '/' + pom.artifactId
225 + '/' + pom.version)
226 delete fileTree(dir: artifactDir,
227 include: 'maven-metadata.xml*')
228 }
229 }
230 }
231 }
232 }
233 }
234
235 def deployer = release.repositories.mavenDeployer
236 deployer.pom*.whenConfigured { pom ->
237 pom.dependencies.findAll { dep ->
238 dep.groupId == 'com.android.support' &&
239 dep.artifactId != 'support-annotations'
240 }*.type = 'aar'
241 }
242
243 ext.versionDir = {
244 def groupDir = new File(rootProject.ext.supportRepoOut,
245 project.group.replace('.', '/'))
246 def artifactDir = new File(groupDir, archivesBaseName)
247 return new File(artifactDir, version)
248 }
249
250 task generateSourceProps(dependsOn: createRepository)
251 generateSourceProps.doLast({
252 def content = "Maven.GroupId=$deployer.pom.groupId\n" +
253 "Maven.ArtifactId=$deployer.pom.artifactId\n" +
254 "Maven.Version=$deployer.pom.version\n" +
255 "Extra.VendorDisplay=Android\n" +
256 "Extra.VendorId=android\n" +
257 "Pkg.Desc=$project.name\n" +
258 "Pkg.Revision=1\n" +
259 "Maven.Dependencies=" +
260 String.join(",", project.configurations.compile.allDependencies
261 .collect {
262 def p = parent.findProject(it.name)
263 return p ? "$p.group:$p.archivesBaseName:$p.version" : null
264 }.grep()) +
265 "\n"
266 Files.write(content, new File(versionDir(), 'source.properties'),
267 Charsets.UTF_8)
268 })
269
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800270 // Before the upload, make sure the repo is ready.
271 release.dependsOn rootProject.tasks.prepareRepo
272
273 // Make the mainupload depend on this one.
274 mainUpload.dependsOn release
275 }
276 }
277
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800278 // Copy instrumentation test APKs and app APKs into the dist dir
279 // For test apks, they are uploaded only if we have java test sources.
280 // For regular app apks, they are uploaded only if they have java sources.
281 project.tasks.whenTaskAdded { task ->
282 if (task.name.startsWith("packageDebug")) {
283 def testApk = task.name.contains("AndroidTest")
284 task.doLast {
285 def source = testApk ? project.android.sourceSets.androidTest
286 : project.android.sourceSets.main
287 if (task.hasProperty("outputFile") && !source.java.sourceFiles.isEmpty()) {
288 copy {
289 from(task.outputFile)
290 into(rootProject.ext.testApkDistOut)
291 rename { String fileName ->
292 // multiple modules may have the same name so prefix the name with
293 // the module's path to ensure it is unique.
294 // e.g. palette-v7-debug-androidTest.apk becomes
295 // support-palette-v7_palette-v7-debug-androidTest.apk
296 "${project.getPath().replace(':', '-').substring(1)}_${fileName}"
297 }
298 }
299 }
300 }
301 }
302 }
303
304 // copy host side test results to DIST
305 project.tasks.whenTaskAdded { task ->
306 if (task instanceof org.gradle.api.tasks.testing.Test) {
307 def junitReport = task.reports.junitXml
308 if (junitReport.enabled) {
309 def zipTask = project.tasks.create(name : "zipResultsOf${task.name.capitalize()}", type : Zip) {
310 destinationDir(testResultsDistDir)
Yigit Boyar278676d2017-03-10 15:29:11 -0800311 // first one is always :, drop it.
312 archiveName("${project.getPath().split(":").join("_").substring(1)}.zip")
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800313 }
314 if (project.rootProject.ext.runningInBuildServer) {
315 task.ignoreFailures = true
316 }
317 task.finalizedBy zipTask
318 task.doFirst {
319 zipTask.from(junitReport.destination)
320 }
321 }
322 }
323 }
324
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800325 project.afterEvaluate {
326 // The archivesBaseName isn't available initially, so set it now
327 def createZipTask = project.tasks.findByName("createSeparateZip")
328 if (createZipTask != null) {
329 createZipTask.appendix = archivesBaseName
330 createZipTask.from versionDir()
331 }
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800332 }
333
334 project.afterEvaluate { p ->
335 // remove dependency on the test so that we still get coverage even if some tests fail
336 p.tasks.findAll { it instanceof JacocoReportTask }.each { task ->
337 def toBeRemoved = new ArrayList()
338 def dependencyList = task.taskDependencies.values
339 dependencyList.each { dep ->
340 if (dep instanceof String) {
341 def t = tasks.findByName(dep)
342 if (t instanceof DeviceProviderInstrumentTestTask) {
343 toBeRemoved.add(dep)
344 task.mustRunAfter(t)
345 }
346 }
347 }
348 toBeRemoved.each { dep ->
349 dependencyList.remove(dep)
350 }
351 }
352 }
353 }
354}
355
356def setupRelease() {
357 apply from: "${ext.supportRootFolder}/buildSrc/release.gradle"
358}
359
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800360ext.init.enableDoclavaAndJDiff = this.&enableDoclavaAndJDiff
361ext.init.setSdkInLocalPropertiesFile = this.&setSdkInLocalPropertiesFile
362ext.init.setupRepoOutAndBuildNumber = this.&setupRepoOutAndBuildNumber
363ext.init.setupRelease = this.&setupRelease
364ext.init.loadDefaultVersions = this.&loadDefaultVersions
365ext.init.configureSubProjects = this.&configureSubProjects