blob: 2b703ffabc261a6506a9cdec83e16b1a60613bbe [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 Liutikas3196ef12018-01-02 16:02:50 -080019import android.support.SupportConfig
Aurimas Liutikas62d3e1d2017-11-28 15:28:01 -080020import android.support.gmaven.GMavenVersionChecker
Yigit Boyar88c16ce2017-02-08 16:06:14 -080021import 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
Aurimas Liutikas419f9932017-12-18 12:53:17 -080025import javax.tools.ToolProvider
26
Yigit Boyar88c16ce2017-02-08 16:06:14 -080027def supportRoot = ext.supportRootFolder
28if (supportRoot == null) {
29 throw new RuntimeException("variable supportRootFolder is not set. you must set it before" +
30 " including this script")
31}
32def init = new Properties()
33ext.init = init
Yigit Boyara9ac19d2017-09-20 16:11:49 -070034rootProject.ext.versionChecker = new GMavenVersionChecker(rootProject)
Aurimas Liutikas9ab3b4c32017-04-19 09:33:27 -070035ext.runningInBuildServer = System.env.DIST_DIR != null && System.env.OUT_DIR != null
Yigit Boyar88c16ce2017-02-08 16:06:14 -080036
37apply from: "${supportRoot}/buildSrc/dependencies.gradle"
Aurimas Liutikas62d3e1d2017-11-28 15:28:01 -080038apply from: "${supportRoot}/buildSrc/build_dependencies.gradle"
Yigit Boyar88c16ce2017-02-08 16:06:14 -080039
Sergey Vasilinets16385352017-12-13 16:56:47 -080040def enableDoclavaAndJDiff(p, dacOptions) {
Yigit Boyar88c16ce2017-02-08 16:06:14 -080041 p.configurations {
42 doclava
43 jdiff
44 }
45
46 p.dependencies {
Aurimas Liutikas419f9932017-12-18 12:53:17 -080047 doclava build_libs.doclava
48 // tools.jar required for com.sun.javadoc
49 doclava files(((URLClassLoader) ToolProvider.getSystemToolClassLoader()).getURLs())
50 jdiff build_libs.jdiff
Aurimas Liutikas62d3e1d2017-11-28 15:28:01 -080051 jdiff build_libs.xml_parser_apis
52 jdiff build_libs.xerces_impl
Yigit Boyar88c16ce2017-02-08 16:06:14 -080053 }
Sergey Vasilinets16385352017-12-13 16:56:47 -080054 def allChecks = DiffAndDocs.configureDiffAndDocs(rootProject, supportRootFolder, dacOptions)
55 createArchive.dependsOn(allChecks)
Yigit Boyar88c16ce2017-02-08 16:06:14 -080056}
57
Aurimas Liutikasbb78f3f2017-06-19 11:30:37 -070058def getFullSdkPath() {
Aurimas Liutikasb06771d2017-04-20 09:46:49 -070059 final String osName = System.getProperty("os.name").toLowerCase();
60 final boolean isMacOsX =
61 osName.contains("mac os x") || osName.contains("darwin") || osName.contains("osx");
62 final String platform = isMacOsX ? 'darwin' : 'linux'
Aurimas Liutikasbb78f3f2017-06-19 11:30:37 -070063 return "${repos.prebuiltsRoot}/fullsdk-${platform}"
64}
65
66def setSdkInLocalPropertiesFile() {
Aurimas Liutikas3196ef12018-01-02 16:02:50 -080067 final File fullSdkPath = file(getFullSdkPath())
68 if (fullSdkPath.exists()) {
69 project.ext.fullSdkPath = fullSdkPath
Yigit Boyar88c16ce2017-02-08 16:06:14 -080070 File props = file("local.properties")
Aurimas Liutikas3196ef12018-01-02 16:02:50 -080071 props.write "sdk.dir=${fullSdkPath.getAbsolutePath()}"
Aurimas Liutikas3c666002017-03-08 19:30:28 -080072 ext.usingFullSdk = true
Yigit Boyar88c16ce2017-02-08 16:06:14 -080073 } else {
Aurimas Liutikas3196ef12018-01-02 16:02:50 -080074 throw Exception("You are using non ub-supportlib-* checkout. You need to check out "
75 + "ub-supportlib-* to work on support library. See go/supportlib for details.")
Yigit Boyar88c16ce2017-02-08 16:06:14 -080076 }
77}
78
79def setupRepoOutAndBuildNumber() {
Yigit Boyaref300662017-05-01 11:52:07 -070080 // common support repo folder which works well for prebuilts.
Yigit Boyar88c16ce2017-02-08 16:06:14 -080081 ext.supportRepoOut = ''
Aurimas Liutikas76542da2017-06-29 17:00:29 -070082 ext.buildNumber = "0"
Yigit Boyar88c16ce2017-02-08 16:06:14 -080083 /*
84 * With the build server you are given two env variables.
85 * The OUT_DIR is a temporary directory you can use to put things during the build.
86 * The DIST_DIR is where you want to save things from the build.
87 *
88 * The build server will copy the contents of DIST_DIR to somewhere and make it available.
89 */
Yigit Boyar7bfacb72017-03-02 14:27:41 -080090 if (ext.runningInBuildServer) {
Yigit Boyar88c16ce2017-02-08 16:06:14 -080091 buildDir = new File(System.env.OUT_DIR + '/gradle/frameworks/support/build')
92 .getCanonicalFile()
93 project.ext.distDir = new File(System.env.DIST_DIR).getCanonicalFile()
94
95 // the build server does not pass the build number so we infer it from the last folder of
96 // the dist path.
97 ext.buildNumber = project.ext.distDir.getName()
Aurimas Liutikasa0150042017-04-21 09:46:12 -070098
99 // the build server should always print out full stack traces for any failures.
100 gradle.startParameter.showStacktrace = ShowStacktrace.ALWAYS
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800101 } else {
102 buildDir = file("${ext.supportRootFolder}/../../out/host/gradle/frameworks/support/build")
103 project.ext.distDir = new File("${ext.supportRootFolder}/../../out/dist")
104 }
105 subprojects {
106 // Change buildDir first so that all plugins pick up the new value.
107 project.buildDir = new File("$project.parent.buildDir/../$project.name/build")
108 }
109 ext.supportRepoOut = new File(buildDir, 'support_repo')
110 ext.testApkDistOut = ext.distDir
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800111 ext.testResultsDistDir = new File(distDir, "host-test-reports")
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800112 ext.docsDir = new File(buildDir, 'javadoc')
113}
114
Aurimas Liutikas38e8f4d92017-06-16 08:31:03 -0700115def configureBuildOnServer() {
116 def buildOnServerTask = rootProject.tasks.create("buildOnServer")
117 rootProject.tasks.whenTaskAdded { task ->
Aurimas Liutikas212905f2017-10-09 15:28:28 -0700118 if ("createArchive".equals(task.name) || "distDocs".equals(task.name)) {
Aurimas Liutikas38e8f4d92017-06-16 08:31:03 -0700119 buildOnServerTask.dependsOn task
120 }
121 }
122
123 subprojects {
124 project.tasks.whenTaskAdded { task ->
125 if ("assembleErrorProne".equals(task.name) || "assembleAndroidTest".equals(task.name)) {
126 buildOnServerTask.dependsOn task
127 }
128 }
129 }
Aurimas Liutikas7cf34972017-12-18 09:27:47 -0800130 buildOnServerTask.dependsOn createJacocoAntUberJarTask()
131}
132
133def createJacocoAntUberJarTask() {
134 def myJacoco = project.configurations.create('myJacoco')
135 project.dependencies.add('myJacoco', build_libs.jacoco_ant)
136
137 return project.tasks.create(
138 name: "JacocoAntUberJar",
139 type: Jar) {
140 inputs.files myJacoco
141 from {
142 myJacoco
143 .resolvedConfiguration
144 .resolvedArtifacts.collect{ zipTree(it.getFile()) }} {
145 // exclude all the signatures the jar might have
146 exclude "META-INF/*.SF"
147 exclude "META-INF/*.DSA"
148 exclude "META-INF/*.RSA"
149 }
150 destinationDir file(project.distDir)
151 archiveName "jacocoant.jar"
152 }
Aurimas Liutikas38e8f4d92017-06-16 08:31:03 -0700153}
154
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800155def configureSubProjects() {
156 // lint every library
157 def lintTask = project.tasks.create("lint")
158 subprojects {
Aurimas Liutikas6509a1a2017-05-09 16:25:43 -0700159 repos.addMavenRepositories(repositories)
160
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800161 // Only modify Android projects.
Aurimas Liutikas6319e4c2017-12-18 21:08:02 -0800162 if (project.name.equals('noto-emoji-compat')) {
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800163 // disable tests and return
164 project.tasks.whenTaskAdded { task ->
165 if (task instanceof org.gradle.api.tasks.testing.Test) {
166 task.enabled = false
167 }
168 }
169 return
170 }
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800171
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800172 project.plugins.whenPluginAdded { plugin ->
173 def isAndroidLibrary = "com.android.build.gradle.LibraryPlugin"
174 .equals(plugin.class.name)
175 def isAndroidApp = "com.android.build.gradle.AppPlugin".equals(plugin.class.name)
176 def isJavaLibrary = "org.gradle.api.plugins.JavaPlugin".equals(plugin.class.name)
177
178 if (isAndroidLibrary || isAndroidApp) {
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800179 // Enable code coverage for debug builds only if we are not running inside the IDE,
180 // since enabling coverage reports breaks the method parameter resolution in the IDE
181 // debugger.
182 project.android.buildTypes.debug.testCoverageEnabled =
Sergey Vasilinetsac8e72b2017-04-26 15:55:17 -0700183 !project.hasProperty('android.injected.invoked.from.ide')
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800184
185 // Copy the class files in a jar to be later used to generate code coverage report
186 project.android.testVariants.all { v ->
187 // check if the variant has any source files
188 // and test coverage is enabled
189 if (v.buildType.testCoverageEnabled
190 && v.sourceSets.any { !it.java.sourceFiles.isEmpty() }) {
191 def jarifyTask = project.tasks.create(
192 name: "package${v.name.capitalize()}ClassFilesForCoverageReport",
193 type: Jar) {
194 from v.testedVariant.javaCompile.destinationDir
195 exclude "**/R.class"
196 exclude "**/R\$*.class"
197 exclude "**/BuildConfig.class"
198 destinationDir file(project.distDir)
Aurimas Liutikas76542da2017-06-29 17:00:29 -0700199 archiveName "${project.name}-${v.baseName}-allclasses.jar"
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800200 }
Aurimas Liutikas21b7fce2017-06-23 09:52:08 -0700201
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800202 jarifyTask.dependsOn v.getJavaCompiler()
Aurimas Liutikas7cf34972017-12-18 09:27:47 -0800203 v.assemble.dependsOn jarifyTask
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800204 }
205 }
206
207 // Enforce NewApi lint check as fatal.
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800208 project.android.lintOptions.fatal 'NewApi'
Aurimas Liutikas6c625702017-09-20 14:35:47 -0700209 lintTask.dependsOn {project.lint}
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800210 }
211
212 if (isAndroidLibrary || isJavaLibrary) {
213 // Add library to the aggregate dependency report.
214 task allDeps(type: DependencyReportTask) {}
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800215
Aurimas Liutikas6509a1a2017-05-09 16:25:43 -0700216 project.afterEvaluate {
217 Upload uploadTask = (Upload) project.tasks.uploadArchives;
218 uploadTask.repositories.mavenDeployer {
Aurimas Liutikas279780d2017-08-09 14:03:59 -0700219 repository(url: uri("$rootProject.ext.supportRepoOut"))
220 setUniqueVersion(true)
Aurimas Liutikas6509a1a2017-05-09 16:25:43 -0700221 }
222
223 // Before the upload, make sure the repo is ready.
224 uploadTask.dependsOn rootProject.tasks.prepareRepo
225
Aurimas Liutikas6509a1a2017-05-09 16:25:43 -0700226 // Make the mainupload depend on this one.
227 mainUpload.dependsOn uploadTask
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800228 }
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800229 }
230 }
231
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800232 // Copy instrumentation test APKs and app APKs into the dist dir
233 // For test apks, they are uploaded only if we have java test sources.
234 // For regular app apks, they are uploaded only if they have java sources.
235 project.tasks.whenTaskAdded { task ->
236 if (task.name.startsWith("packageDebug")) {
237 def testApk = task.name.contains("AndroidTest")
238 task.doLast {
239 def source = testApk ? project.android.sourceSets.androidTest
240 : project.android.sourceSets.main
Yigit Boyare606d6d2017-09-07 12:37:36 -0700241 def hasKotlinSources = false
242 if (source.hasProperty('kotlin')) {
243 if (!source.kotlin.files.isEmpty()) {
244 hasKotlinSources = true
245 } else {
246 // kotlin files does not show in java sources due to the *.java filter
247 // so we need to check them manually
248 hasKotlinSources = source.java.sourceDirectoryTrees.any {
249 !fileTree(dir: it.dir, include:'**/*.kt').files.isEmpty()
250 }
251 }
252 }
253 def hasSourceCode = !source.java.sourceFiles.isEmpty() || hasKotlinSources
254 if (task.hasProperty("outputDirectory") && (hasSourceCode || !testApk)) {
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800255 copy {
Aurimas Liutikasef3b4922017-06-28 10:44:59 -0700256 from(task.outputDirectory)
257 include '*.apk'
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800258 into(rootProject.ext.testApkDistOut)
259 rename { String fileName ->
Hyundo Moon9938e172017-07-26 20:51:11 +0900260 // Exclude media-compat-test-* modules from existing support library
261 // presubmit tests.
262 if (fileName.contains("media-compat-test")) {
263 fileName.replace("-debug-androidTest", "")
Yigit Boyar96a0fcd2017-08-25 18:18:28 -0700264 } else {
265 // multiple modules may have the same name so prefix the name with
266 // the module's path to ensure it is unique.
267 // e.g. palette-v7-debug-androidTest.apk becomes
268 // support-palette-v7_palette-v7-debug-androidTest.apk
269 "${project.getPath().replace(':', '-').substring(1)}_${fileName}"
Hyundo Moon9938e172017-07-26 20:51:11 +0900270 }
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800271 }
272 }
273 }
274 }
275 }
276 }
277
278 // copy host side test results to DIST
279 project.tasks.whenTaskAdded { task ->
280 if (task instanceof org.gradle.api.tasks.testing.Test) {
281 def junitReport = task.reports.junitXml
282 if (junitReport.enabled) {
283 def zipTask = project.tasks.create(name : "zipResultsOf${task.name.capitalize()}", type : Zip) {
284 destinationDir(testResultsDistDir)
Yigit Boyar278676d2017-03-10 15:29:11 -0800285 // first one is always :, drop it.
286 archiveName("${project.getPath().split(":").join("_").substring(1)}.zip")
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800287 }
288 if (project.rootProject.ext.runningInBuildServer) {
289 task.ignoreFailures = true
290 }
291 task.finalizedBy zipTask
292 task.doFirst {
293 zipTask.from(junitReport.destination)
294 }
295 }
296 }
297 }
298
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800299 project.afterEvaluate { p ->
300 // remove dependency on the test so that we still get coverage even if some tests fail
301 p.tasks.findAll { it instanceof JacocoReportTask }.each { task ->
302 def toBeRemoved = new ArrayList()
303 def dependencyList = task.taskDependencies.values
304 dependencyList.each { dep ->
305 if (dep instanceof String) {
306 def t = tasks.findByName(dep)
307 if (t instanceof DeviceProviderInstrumentTestTask) {
308 toBeRemoved.add(dep)
309 task.mustRunAfter(t)
310 }
311 }
312 }
313 toBeRemoved.each { dep ->
314 dependencyList.remove(dep)
315 }
316 }
317 }
318 }
319}
320
321def setupRelease() {
322 apply from: "${ext.supportRootFolder}/buildSrc/release.gradle"
323}
324
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800325ext.init.enableDoclavaAndJDiff = this.&enableDoclavaAndJDiff
326ext.init.setSdkInLocalPropertiesFile = this.&setSdkInLocalPropertiesFile
327ext.init.setupRepoOutAndBuildNumber = this.&setupRepoOutAndBuildNumber
328ext.init.setupRelease = this.&setupRelease
Aurimas Liutikas38e8f4d92017-06-16 08:31:03 -0700329ext.init.configureSubProjects = this.&configureSubProjects
Yigit Boyare1bbf712017-03-08 13:52:37 -0800330ext.init.configureBuildOnServer = this.&configureBuildOnServer