blob: 25281df36a8e6463160f170ad4475e1e22dc4430 [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
22import org.gradle.internal.os.OperatingSystem
23
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
31ext.init.checkoutRoot = "${supportRoot}/../.."
32ext.init.prebuiltsRoot = "${init.checkoutRoot}/prebuilts"
33ext.init.prebuiltsRootUri = "file://${init.prebuiltsRoot}"
34ext.init.enablePublicRepos = System.getenv("ALLOW_PUBLIC_REPOS") != null
Yigit Boyar7bfacb72017-03-02 14:27:41 -080035ext.runningInBuildServer = System.env.DIST_DIR != null && System.env.OUT_DIR != null
Yigit Boyar88c16ce2017-02-08 16:06:14 -080036
37ext.repoNames = ["${init.prebuiltsRoot}/gradle-plugin",
38 "${init.prebuiltsRoot}/tools/common/m2/repository",
39 "${init.prebuiltsRoot}/tools/common/m2/internal",
40 "${init.prebuiltsRoot}/maven_repo/android"]
41
42apply from: "${supportRoot}/buildSrc/dependencies.gradle"
43
44
45def loadDefaultVersions() {
46 apply from: "${supportRootFolder}/buildSrc/versions.gradle"
47}
48
49def addMavenRepositories(RepositoryHandler handler) {
50 repoNames.each { repo ->
51 handler.maven {
52 url repo
53 }
54 if (ext.init.enablePublicRepos) {
55 handler.mavenCentral()
56 handler.jcenter()
57 }
58 }
59}
60
61def enableDoclavaAndJDiff(p) {
62 p.configurations {
63 doclava
64 jdiff
65 }
66
67 p.dependencies {
68 doclava project(':doclava')
69 jdiff project(':jdiff')
70 jdiff libs.xml_parser_apis
71 jdiff libs.xerces_impl
72 }
73 apply from: "${ext.supportRootFolder}/buildSrc/diff_and_docs.gradle"
74}
75
76def setSdkInLocalPropertiesFile() {
77 final String platform = OperatingSystem.current().isMacOsX() ? 'darwin' : 'linux'
78 System.setProperty('android.dir', "${supportRootFolder}/../../")
Aurimas Liutikasd2d9bda2017-03-03 16:06:39 -080079 ext.buildToolsVersion = '26.0.0'
Yigit Boyar88c16ce2017-02-08 16:06:14 -080080 final String fullSdkPath = "${init.prebuiltsRoot}/fullsdk-${platform}"
81 if (file(fullSdkPath).exists()) {
82 gradle.ext.currentSdk = 26
Yigit Boyar88c16ce2017-02-08 16:06:14 -080083 project.ext.androidJar = files("${fullSdkPath}/platforms/android-${gradle.ext.currentSdk}" +
84 "/android.jar")
85 System.setProperty('android.home', "${init.prebuiltsRoot}/fullsdk-${platform}")
86 File props = file("local.properties")
87 props.write "sdk.dir=${fullSdkPath}"
Aurimas Liutikas3c666002017-03-08 19:30:28 -080088 ext.usingFullSdk = true
Yigit Boyar88c16ce2017-02-08 16:06:14 -080089 } else {
90 gradle.ext.currentSdk = 'current'
Yigit Boyar88c16ce2017-02-08 16:06:14 -080091 project.ext.androidJar = files("${init.prebuiltsRoot}/sdk/current/android.jar")
92 File props = file("local.properties")
93 props.write "android.dir=../../"
Aurimas Liutikas3c666002017-03-08 19:30:28 -080094 ext.usingFullSdk = false
Yigit Boyar88c16ce2017-02-08 16:06:14 -080095 }
96}
97
98def setupRepoOutAndBuildNumber() {
99 ext.supportRepoOut = ''
100 ext.buildNumber = Integer.toString(ext.extraVersion)
101
102 /*
103 * With the build server you are given two env variables.
104 * The OUT_DIR is a temporary directory you can use to put things during the build.
105 * The DIST_DIR is where you want to save things from the build.
106 *
107 * The build server will copy the contents of DIST_DIR to somewhere and make it available.
108 */
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800109 if (ext.runningInBuildServer) {
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800110 buildDir = new File(System.env.OUT_DIR + '/gradle/frameworks/support/build')
111 .getCanonicalFile()
112 project.ext.distDir = new File(System.env.DIST_DIR).getCanonicalFile()
113
114 // the build server does not pass the build number so we infer it from the last folder of
115 // the dist path.
116 ext.buildNumber = project.ext.distDir.getName()
117 } 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')
126 ext.testApkDistOut = ext.distDir
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800127 ext.testResultsDistDir = new File(distDir, "host-test-reports")
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800128 ext.docsDir = new File(buildDir, 'javadoc')
129}
130
131def configureSubProjects() {
132 // lint every library
133 def lintTask = project.tasks.create("lint")
134 subprojects {
135 // Only modify Android projects.
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800136 if (project.name.equals('doclava') || project.name.equals('jdiff')) {
137 // disable tests and return
138 project.tasks.whenTaskAdded { task ->
139 if (task instanceof org.gradle.api.tasks.testing.Test) {
140 task.enabled = false
141 }
142 }
143 return
144 }
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800145
146 // Current SDK is set in studioCompat.gradle.
147 project.ext.currentSdk = gradle.ext.currentSdk
148 apply plugin: 'maven'
149
150 version = rootProject.ext.supportVersion
151 group = 'com.android.support'
152
153 init.addMavenRepositories(repositories)
154 project.plugins.whenPluginAdded { plugin ->
155 def isAndroidLibrary = "com.android.build.gradle.LibraryPlugin"
156 .equals(plugin.class.name)
157 def isAndroidApp = "com.android.build.gradle.AppPlugin".equals(plugin.class.name)
158 def isJavaLibrary = "org.gradle.api.plugins.JavaPlugin".equals(plugin.class.name)
159
160 if (isAndroidLibrary || isAndroidApp) {
161 project.android.buildToolsVersion = rootProject.buildToolsVersion
162
163 // Enable code coverage for debug builds only if we are not running inside the IDE,
164 // since enabling coverage reports breaks the method parameter resolution in the IDE
165 // debugger.
166 project.android.buildTypes.debug.testCoverageEnabled =
167 !hasProperty('android.injected.invoked.from.ide')
168
169 // Copy the class files in a jar to be later used to generate code coverage report
170 project.android.testVariants.all { v ->
171 // check if the variant has any source files
172 // and test coverage is enabled
173 if (v.buildType.testCoverageEnabled
174 && v.sourceSets.any { !it.java.sourceFiles.isEmpty() }) {
175 def jarifyTask = project.tasks.create(
176 name: "package${v.name.capitalize()}ClassFilesForCoverageReport",
177 type: Jar) {
178 from v.testedVariant.javaCompile.destinationDir
179 exclude "**/R.class"
180 exclude "**/R\$*.class"
181 exclude "**/BuildConfig.class"
182 destinationDir file(project.distDir)
183 archiveName "${project.archivesBaseName}-${v.baseName}-allclasses.jar"
184 }
185 def jacocoAntConfig =
186 project.configurations[JacocoPlugin.ANT_CONFIGURATION_NAME]
187 def jacocoAntArtifacts = jacocoAntConfig.resolvedConfiguration
188 .resolvedArtifacts
189 def version = jacocoAntArtifacts.find { "org.jacoco.ant".equals(it.name) }
190 .moduleVersion.id.version
191 def collectJacocoAntPackages = project.tasks.create(
192 name: "collectJacocoAntPackages",
193 type: Jar) {
194 from(jacocoAntArtifacts.collect { zipTree(it.getFile()) }) {
195 // exclude all the signatures the jar might have
196 exclude "META-INF/*.SF"
197 exclude "META-INF/*.DSA"
198 exclude "META-INF/*.RSA"
199 }
200 destinationDir file(project.distDir)
201 archiveName "jacocoant-" + version + ".jar"
202 }
203 jarifyTask.dependsOn v.getJavaCompiler()
204 v.assemble.dependsOn jarifyTask, collectJacocoAntPackages
205 }
206 }
207
208 // Enforce NewApi lint check as fatal.
209 project.android.lintOptions.check 'NewApi'
210 project.android.lintOptions.fatal 'NewApi'
211 lintTask.dependsOn project.lint
212 }
213
214 if (isAndroidLibrary || isJavaLibrary) {
215 // Add library to the aggregate dependency report.
216 task allDeps(type: DependencyReportTask) {}
217
218 // Create release and separate zip task for library.
219 task release(type: Upload) {
220 configuration = configurations.archives
221 repositories {
222 mavenDeployer {
223 repository(url: uri("$rootProject.ext.supportRepoOut"))
224
225 // Disable unique names for SNAPSHOTS so they can be updated in place.
226 setUniqueVersion(false)
227 doLast {
228 // Remove any invalid maven-metadata.xml files that may have been
229 // created for SNAPSHOT versions that are *not* uniquely versioned.
230 pom*.each { pom ->
231 if (pom.version.endsWith('-SNAPSHOT')) {
232 final File artifactDir = new File(
233 rootProject.ext.supportRepoOut,
234 pom.groupId.replace('.', '/')
235 + '/' + pom.artifactId
236 + '/' + pom.version)
237 delete fileTree(dir: artifactDir,
238 include: 'maven-metadata.xml*')
239 }
240 }
241 }
242 }
243 }
244 }
245
246 def deployer = release.repositories.mavenDeployer
247 deployer.pom*.whenConfigured { pom ->
248 pom.dependencies.findAll { dep ->
249 dep.groupId == 'com.android.support' &&
250 dep.artifactId != 'support-annotations'
251 }*.type = 'aar'
252 }
253
254 ext.versionDir = {
255 def groupDir = new File(rootProject.ext.supportRepoOut,
256 project.group.replace('.', '/'))
257 def artifactDir = new File(groupDir, archivesBaseName)
258 return new File(artifactDir, version)
259 }
260
261 task generateSourceProps(dependsOn: createRepository)
262 generateSourceProps.doLast({
263 def content = "Maven.GroupId=$deployer.pom.groupId\n" +
264 "Maven.ArtifactId=$deployer.pom.artifactId\n" +
265 "Maven.Version=$deployer.pom.version\n" +
266 "Extra.VendorDisplay=Android\n" +
267 "Extra.VendorId=android\n" +
268 "Pkg.Desc=$project.name\n" +
269 "Pkg.Revision=1\n" +
270 "Maven.Dependencies=" +
271 String.join(",", project.configurations.compile.allDependencies
272 .collect {
273 def p = parent.findProject(it.name)
274 return p ? "$p.group:$p.archivesBaseName:$p.version" : null
275 }.grep()) +
276 "\n"
277 Files.write(content, new File(versionDir(), 'source.properties'),
278 Charsets.UTF_8)
279 })
280
281 task createSeparateZip(type: Zip, dependsOn: generateSourceProps) {
282 into archivesBaseName
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800283 destinationDir rootProject.ext.distDir
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800284 baseName = project.group
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800285 version = rootProject.ext.buildNumber
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800286 }
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800287 rootProject.createArchive.dependsOn createSeparateZip
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800288
289 // Before the upload, make sure the repo is ready.
290 release.dependsOn rootProject.tasks.prepareRepo
291
292 // Make the mainupload depend on this one.
293 mainUpload.dependsOn release
294 }
295 }
296
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800297 // Copy instrumentation test APKs and app APKs into the dist dir
298 // For test apks, they are uploaded only if we have java test sources.
299 // For regular app apks, they are uploaded only if they have java sources.
300 project.tasks.whenTaskAdded { task ->
301 if (task.name.startsWith("packageDebug")) {
302 def testApk = task.name.contains("AndroidTest")
303 task.doLast {
304 def source = testApk ? project.android.sourceSets.androidTest
305 : project.android.sourceSets.main
306 if (task.hasProperty("outputFile") && !source.java.sourceFiles.isEmpty()) {
307 copy {
308 from(task.outputFile)
309 into(rootProject.ext.testApkDistOut)
310 rename { String fileName ->
311 // multiple modules may have the same name so prefix the name with
312 // the module's path to ensure it is unique.
313 // e.g. palette-v7-debug-androidTest.apk becomes
314 // support-palette-v7_palette-v7-debug-androidTest.apk
315 "${project.getPath().replace(':', '-').substring(1)}_${fileName}"
316 }
317 }
318 }
319 }
320 }
321 }
322
323 // copy host side test results to DIST
324 project.tasks.whenTaskAdded { task ->
325 if (task instanceof org.gradle.api.tasks.testing.Test) {
326 def junitReport = task.reports.junitXml
327 if (junitReport.enabled) {
328 def zipTask = project.tasks.create(name : "zipResultsOf${task.name.capitalize()}", type : Zip) {
329 destinationDir(testResultsDistDir)
Yigit Boyar278676d2017-03-10 15:29:11 -0800330 // first one is always :, drop it.
331 archiveName("${project.getPath().split(":").join("_").substring(1)}.zip")
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800332 }
333 if (project.rootProject.ext.runningInBuildServer) {
334 task.ignoreFailures = true
335 }
336 task.finalizedBy zipTask
337 task.doFirst {
338 zipTask.from(junitReport.destination)
339 }
340 }
341 }
342 }
343
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800344 project.afterEvaluate {
345 // The archivesBaseName isn't available initially, so set it now
346 def createZipTask = project.tasks.findByName("createSeparateZip")
347 if (createZipTask != null) {
348 createZipTask.appendix = archivesBaseName
349 createZipTask.from versionDir()
350 }
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800351 }
352
353 project.afterEvaluate { p ->
354 // remove dependency on the test so that we still get coverage even if some tests fail
355 p.tasks.findAll { it instanceof JacocoReportTask }.each { task ->
356 def toBeRemoved = new ArrayList()
357 def dependencyList = task.taskDependencies.values
358 dependencyList.each { dep ->
359 if (dep instanceof String) {
360 def t = tasks.findByName(dep)
361 if (t instanceof DeviceProviderInstrumentTestTask) {
362 toBeRemoved.add(dep)
363 task.mustRunAfter(t)
364 }
365 }
366 }
367 toBeRemoved.each { dep ->
368 dependencyList.remove(dep)
369 }
370 }
371 }
372 }
373}
374
375def setupRelease() {
376 apply from: "${ext.supportRootFolder}/buildSrc/release.gradle"
377}
378
379ext.init.addMavenRepositories = this.&addMavenRepositories
380ext.init.enableDoclavaAndJDiff = this.&enableDoclavaAndJDiff
381ext.init.setSdkInLocalPropertiesFile = this.&setSdkInLocalPropertiesFile
382ext.init.setupRepoOutAndBuildNumber = this.&setupRepoOutAndBuildNumber
383ext.init.setupRelease = this.&setupRelease
384ext.init.loadDefaultVersions = this.&loadDefaultVersions
385ext.init.configureSubProjects = this.&configureSubProjects