blob: b89bd929e15943e8fd696a1739fde3460c430baf [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.JacocoReportTask
21import com.android.build.gradle.internal.tasks.DeviceProviderInstrumentTestTask
Aurimas Liutikasa0150042017-04-21 09:46:12 -070022import org.gradle.api.logging.configuration.ShowStacktrace
Yigit Boyar88c16ce2017-02-08 16:06:14 -080023
Aurimas Liutikas419f9932017-12-18 12:53:17 -080024import javax.tools.ToolProvider
25
Yigit Boyar88c16ce2017-02-08 16:06:14 -080026def supportRoot = ext.supportRootFolder
27if (supportRoot == null) {
28 throw new RuntimeException("variable supportRootFolder is not set. you must set it before" +
29 " including this script")
30}
31def init = new Properties()
32ext.init = init
Aurimas Liutikas5f3a2772018-01-05 19:07:40 -080033rootProject.ext.versionChecker = new GMavenVersionChecker(rootProject.logger)
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"
Aurimas Liutikas62d3e1d2017-11-28 15:28:01 -080037apply from: "${supportRoot}/buildSrc/build_dependencies.gradle"
Aurimas Liutikasa2cbbfa2018-01-25 14:42:41 -080038apply from: "${supportRoot}/buildSrc/unbundled_check.gradle"
39
Yigit Boyar88c16ce2017-02-08 16:06:14 -080040
Sergey Vasilinets16385352017-12-13 16:56:47 -080041def enableDoclavaAndJDiff(p, dacOptions) {
Yigit Boyar88c16ce2017-02-08 16:06:14 -080042 p.configurations {
43 doclava
44 jdiff
45 }
46
47 p.dependencies {
Aurimas Liutikas419f9932017-12-18 12:53:17 -080048 doclava build_libs.doclava
49 // tools.jar required for com.sun.javadoc
50 doclava files(((URLClassLoader) ToolProvider.getSystemToolClassLoader()).getURLs())
51 jdiff build_libs.jdiff
Aurimas Liutikas62d3e1d2017-11-28 15:28:01 -080052 jdiff build_libs.xml_parser_apis
53 jdiff build_libs.xerces_impl
Yigit Boyar88c16ce2017-02-08 16:06:14 -080054 }
Sergey Vasilinets16385352017-12-13 16:56:47 -080055 def allChecks = DiffAndDocs.configureDiffAndDocs(rootProject, supportRootFolder, dacOptions)
56 createArchive.dependsOn(allChecks)
Yigit Boyar88c16ce2017-02-08 16:06:14 -080057}
58
Aurimas Liutikasbb78f3f2017-06-19 11:30:37 -070059def getFullSdkPath() {
Aurimas Liutikasa2cbbfa2018-01-25 14:42:41 -080060 if (isUnbundledBuild(ext.supportRootFolder)) {
61 Properties properties = new Properties()
62 File propertiesFile = new File('local.properties')
63 if (propertiesFile.exists()) {
64 propertiesFile.withInputStream {
65 properties.load(it)
66 }
67 }
68 File location = findSdkLocation(properties, supportRootFolder)
69 return location.getAbsolutePath()
70 } else {
71 final String osName = System.getProperty("os.name").toLowerCase();
72 final boolean isMacOsX =
73 osName.contains("mac os x") || osName.contains("darwin") || osName.contains("osx");
74 final String platform = isMacOsX ? 'darwin' : 'linux'
75 return "${repos.prebuiltsRoot}/fullsdk-${platform}"
76 }
77}
78
79/**
80 * Adapted from com.android.build.gradle.internal.SdkHandler
81 */
82public static File findSdkLocation(Properties properties, File rootDir) {
83 String sdkDirProp = properties.getProperty("sdk.dir");
84 if (sdkDirProp != null) {
85 File sdk = new File(sdkDirProp);
86 if (!sdk.isAbsolute()) {
87 sdk = new File(rootDir, sdkDirProp);
88 }
89 return sdk
90 }
91
92 sdkDirProp = properties.getProperty("android.dir");
93 if (sdkDirProp != null) {
94 return new File(rootDir, sdkDirProp);
95 }
96
97 String envVar = System.getenv("ANDROID_HOME");
98 if (envVar != null) {
99 return new File(envVar);
100 }
101
102 String property = System.getProperty("android.home");
103 if (property != null) {
104 return new File(property);
105 }
106 return null;
Aurimas Liutikasbb78f3f2017-06-19 11:30:37 -0700107}
108
109def setSdkInLocalPropertiesFile() {
Aurimas Liutikas3196ef12018-01-02 16:02:50 -0800110 final File fullSdkPath = file(getFullSdkPath())
111 if (fullSdkPath.exists()) {
112 project.ext.fullSdkPath = fullSdkPath
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800113 File props = file("local.properties")
Aurimas Liutikas3196ef12018-01-02 16:02:50 -0800114 props.write "sdk.dir=${fullSdkPath.getAbsolutePath()}"
Aurimas Liutikas3c666002017-03-08 19:30:28 -0800115 ext.usingFullSdk = true
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800116 } else {
Aurimas Liutikas3196ef12018-01-02 16:02:50 -0800117 throw Exception("You are using non ub-supportlib-* checkout. You need to check out "
118 + "ub-supportlib-* to work on support library. See go/supportlib for details.")
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800119 }
120}
121
122def setupRepoOutAndBuildNumber() {
Yigit Boyaref300662017-05-01 11:52:07 -0700123 // common support repo folder which works well for prebuilts.
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800124 ext.supportRepoOut = ''
Aurimas Liutikas76542da2017-06-29 17:00:29 -0700125 ext.buildNumber = "0"
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800126 /*
127 * With the build server you are given two env variables.
128 * The OUT_DIR is a temporary directory you can use to put things during the build.
129 * The DIST_DIR is where you want to save things from the build.
130 *
131 * The build server will copy the contents of DIST_DIR to somewhere and make it available.
132 */
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800133 if (ext.runningInBuildServer) {
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800134 buildDir = new File(System.env.OUT_DIR + '/gradle/frameworks/support/build')
135 .getCanonicalFile()
136 project.ext.distDir = new File(System.env.DIST_DIR).getCanonicalFile()
137
138 // the build server does not pass the build number so we infer it from the last folder of
139 // the dist path.
140 ext.buildNumber = project.ext.distDir.getName()
Aurimas Liutikasa0150042017-04-21 09:46:12 -0700141
142 // the build server should always print out full stack traces for any failures.
143 gradle.startParameter.showStacktrace = ShowStacktrace.ALWAYS
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800144 } else {
145 buildDir = file("${ext.supportRootFolder}/../../out/host/gradle/frameworks/support/build")
146 project.ext.distDir = new File("${ext.supportRootFolder}/../../out/dist")
147 }
148 subprojects {
149 // Change buildDir first so that all plugins pick up the new value.
150 project.buildDir = new File("$project.parent.buildDir/../$project.name/build")
151 }
152 ext.supportRepoOut = new File(buildDir, 'support_repo')
153 ext.testApkDistOut = ext.distDir
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800154 ext.testResultsDistDir = new File(distDir, "host-test-reports")
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800155 ext.docsDir = new File(buildDir, 'javadoc')
156}
157
Aurimas Liutikas38e8f4d92017-06-16 08:31:03 -0700158def configureBuildOnServer() {
159 def buildOnServerTask = rootProject.tasks.create("buildOnServer")
160 rootProject.tasks.whenTaskAdded { task ->
Aurimas Liutikas212905f2017-10-09 15:28:28 -0700161 if ("createArchive".equals(task.name) || "distDocs".equals(task.name)) {
Aurimas Liutikas38e8f4d92017-06-16 08:31:03 -0700162 buildOnServerTask.dependsOn task
163 }
164 }
165
166 subprojects {
167 project.tasks.whenTaskAdded { task ->
168 if ("assembleErrorProne".equals(task.name) || "assembleAndroidTest".equals(task.name)) {
169 buildOnServerTask.dependsOn task
170 }
171 }
172 }
Aurimas Liutikas7cf34972017-12-18 09:27:47 -0800173 buildOnServerTask.dependsOn createJacocoAntUberJarTask()
174}
175
176def createJacocoAntUberJarTask() {
177 def myJacoco = project.configurations.create('myJacoco')
178 project.dependencies.add('myJacoco', build_libs.jacoco_ant)
179
180 return project.tasks.create(
181 name: "JacocoAntUberJar",
182 type: Jar) {
183 inputs.files myJacoco
184 from {
185 myJacoco
186 .resolvedConfiguration
187 .resolvedArtifacts.collect{ zipTree(it.getFile()) }} {
188 // exclude all the signatures the jar might have
189 exclude "META-INF/*.SF"
190 exclude "META-INF/*.DSA"
191 exclude "META-INF/*.RSA"
192 }
193 destinationDir file(project.distDir)
194 archiveName "jacocoant.jar"
195 }
Aurimas Liutikas38e8f4d92017-06-16 08:31:03 -0700196}
197
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800198def configureSubProjects() {
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800199 subprojects {
Aurimas Liutikas6509a1a2017-05-09 16:25:43 -0700200 repos.addMavenRepositories(repositories)
201
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800202 // Only modify Android projects.
Aurimas Liutikas6319e4c2017-12-18 21:08:02 -0800203 if (project.name.equals('noto-emoji-compat')) {
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800204 // disable tests and return
205 project.tasks.whenTaskAdded { task ->
206 if (task instanceof org.gradle.api.tasks.testing.Test) {
207 task.enabled = false
208 }
209 }
210 return
211 }
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800212
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800213 project.plugins.whenPluginAdded { plugin ->
214 def isAndroidLibrary = "com.android.build.gradle.LibraryPlugin"
215 .equals(plugin.class.name)
216 def isAndroidApp = "com.android.build.gradle.AppPlugin".equals(plugin.class.name)
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800217
218 if (isAndroidLibrary || isAndroidApp) {
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800219 // Enable code coverage for debug builds only if we are not running inside the IDE,
220 // since enabling coverage reports breaks the method parameter resolution in the IDE
221 // debugger.
222 project.android.buildTypes.debug.testCoverageEnabled =
Sergey Vasilinetsac8e72b2017-04-26 15:55:17 -0700223 !project.hasProperty('android.injected.invoked.from.ide')
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800224
225 // Copy the class files in a jar to be later used to generate code coverage report
226 project.android.testVariants.all { v ->
227 // check if the variant has any source files
228 // and test coverage is enabled
229 if (v.buildType.testCoverageEnabled
230 && v.sourceSets.any { !it.java.sourceFiles.isEmpty() }) {
231 def jarifyTask = project.tasks.create(
232 name: "package${v.name.capitalize()}ClassFilesForCoverageReport",
233 type: Jar) {
234 from v.testedVariant.javaCompile.destinationDir
235 exclude "**/R.class"
236 exclude "**/R\$*.class"
237 exclude "**/BuildConfig.class"
238 destinationDir file(project.distDir)
Aurimas Liutikas76542da2017-06-29 17:00:29 -0700239 archiveName "${project.name}-${v.baseName}-allclasses.jar"
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800240 }
Aurimas Liutikas21b7fce2017-06-23 09:52:08 -0700241
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800242 jarifyTask.dependsOn v.getJavaCompiler()
Aurimas Liutikas7cf34972017-12-18 09:27:47 -0800243 v.assemble.dependsOn jarifyTask
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800244 }
245 }
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800246 }
247 }
248
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800249 // Copy instrumentation test APKs and app APKs into the dist dir
250 // For test apks, they are uploaded only if we have java test sources.
251 // For regular app apks, they are uploaded only if they have java sources.
252 project.tasks.whenTaskAdded { task ->
253 if (task.name.startsWith("packageDebug")) {
254 def testApk = task.name.contains("AndroidTest")
255 task.doLast {
256 def source = testApk ? project.android.sourceSets.androidTest
257 : project.android.sourceSets.main
Yigit Boyare606d6d2017-09-07 12:37:36 -0700258 def hasKotlinSources = false
259 if (source.hasProperty('kotlin')) {
260 if (!source.kotlin.files.isEmpty()) {
261 hasKotlinSources = true
262 } else {
263 // kotlin files does not show in java sources due to the *.java filter
264 // so we need to check them manually
265 hasKotlinSources = source.java.sourceDirectoryTrees.any {
266 !fileTree(dir: it.dir, include:'**/*.kt').files.isEmpty()
267 }
268 }
269 }
270 def hasSourceCode = !source.java.sourceFiles.isEmpty() || hasKotlinSources
271 if (task.hasProperty("outputDirectory") && (hasSourceCode || !testApk)) {
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800272 copy {
Aurimas Liutikasef3b4922017-06-28 10:44:59 -0700273 from(task.outputDirectory)
274 include '*.apk'
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800275 into(rootProject.ext.testApkDistOut)
276 rename { String fileName ->
Hyundo Moon9938e172017-07-26 20:51:11 +0900277 // Exclude media-compat-test-* modules from existing support library
278 // presubmit tests.
279 if (fileName.contains("media-compat-test")) {
280 fileName.replace("-debug-androidTest", "")
Yigit Boyar96a0fcd2017-08-25 18:18:28 -0700281 } else {
282 // multiple modules may have the same name so prefix the name with
283 // the module's path to ensure it is unique.
284 // e.g. palette-v7-debug-androidTest.apk becomes
285 // support-palette-v7_palette-v7-debug-androidTest.apk
286 "${project.getPath().replace(':', '-').substring(1)}_${fileName}"
Hyundo Moon9938e172017-07-26 20:51:11 +0900287 }
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800288 }
289 }
290 }
291 }
292 }
293 }
294
295 // copy host side test results to DIST
296 project.tasks.whenTaskAdded { task ->
297 if (task instanceof org.gradle.api.tasks.testing.Test) {
298 def junitReport = task.reports.junitXml
299 if (junitReport.enabled) {
300 def zipTask = project.tasks.create(name : "zipResultsOf${task.name.capitalize()}", type : Zip) {
301 destinationDir(testResultsDistDir)
Yigit Boyar278676d2017-03-10 15:29:11 -0800302 // first one is always :, drop it.
303 archiveName("${project.getPath().split(":").join("_").substring(1)}.zip")
Yigit Boyar7bfacb72017-03-02 14:27:41 -0800304 }
305 if (project.rootProject.ext.runningInBuildServer) {
306 task.ignoreFailures = true
307 }
308 task.finalizedBy zipTask
309 task.doFirst {
310 zipTask.from(junitReport.destination)
311 }
312 }
313 }
314 }
315
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800316 project.afterEvaluate { p ->
317 // remove dependency on the test so that we still get coverage even if some tests fail
318 p.tasks.findAll { it instanceof JacocoReportTask }.each { task ->
319 def toBeRemoved = new ArrayList()
320 def dependencyList = task.taskDependencies.values
321 dependencyList.each { dep ->
322 if (dep instanceof String) {
323 def t = tasks.findByName(dep)
324 if (t instanceof DeviceProviderInstrumentTestTask) {
325 toBeRemoved.add(dep)
326 task.mustRunAfter(t)
327 }
328 }
329 }
330 toBeRemoved.each { dep ->
331 dependencyList.remove(dep)
332 }
333 }
334 }
335 }
336}
337
338def setupRelease() {
339 apply from: "${ext.supportRootFolder}/buildSrc/release.gradle"
340}
341
Yigit Boyar88c16ce2017-02-08 16:06:14 -0800342ext.init.enableDoclavaAndJDiff = this.&enableDoclavaAndJDiff
343ext.init.setSdkInLocalPropertiesFile = this.&setSdkInLocalPropertiesFile
344ext.init.setupRepoOutAndBuildNumber = this.&setupRepoOutAndBuildNumber
345ext.init.setupRelease = this.&setupRelease
Aurimas Liutikas38e8f4d92017-06-16 08:31:03 -0700346ext.init.configureSubProjects = this.&configureSubProjects
Yigit Boyare1bbf712017-03-08 13:52:37 -0800347ext.init.configureBuildOnServer = this.&configureBuildOnServer