1 /* <lambda>null2 * Copyright 2020 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 17 package androidx.build.resources 18 19 import androidx.build.AndroidXImplPlugin.Companion.TASK_GROUP_API 20 import androidx.build.addToBuildOnServer 21 import androidx.build.addToCheckTask 22 import androidx.build.checkapi.ApiLocation 23 import androidx.build.checkapi.getRequiredCompatibilityApiLocation 24 import androidx.build.metalava.UpdateApiTask 25 import androidx.build.uptodatedness.cacheEvenIfNoOutputs 26 import org.gradle.api.Project 27 import org.gradle.api.file.RegularFile 28 import org.gradle.api.provider.Provider 29 30 object ResourceTasks { 31 private const val GENERATE_RESOURCE_API_TASK = "generateResourceApi" 32 private const val CHECK_RESOURCE_API_RELEASE_TASK = "checkResourceApiRelease" 33 private const val CHECK_RESOURCE_API_TASK = "checkResourceApi" 34 private const val UPDATE_RESOURCE_API_TASK = "updateResourceApi" 35 36 fun setupProject( 37 project: Project, 38 builtApiFile: Provider<RegularFile>, 39 builtApiLocation: ApiLocation, 40 outputApiLocations: List<ApiLocation> 41 ) { 42 43 val outputApiFiles = outputApiLocations.map { location -> location.resourceFile } 44 45 val generateResourceApi = 46 project.tasks.register( 47 GENERATE_RESOURCE_API_TASK, 48 GenerateResourceApiTask::class.java 49 ) { task -> 50 task.group = "API" 51 task.description = "Generates resource API files from source" 52 task.builtApi.set(builtApiFile) 53 task.apiLocation.set(builtApiLocation) 54 } 55 56 // Policy: If the artifact has previously been released, e.g. has a beta or later API file 57 // checked in, then we must verify "release compatibility" against the work-in-progress 58 // API file. 59 val checkResourceApiRelease = 60 project.getRequiredCompatibilityApiLocation()?.let { lastReleasedApiFile -> 61 project.tasks.register( 62 CHECK_RESOURCE_API_RELEASE_TASK, 63 CheckResourceApiReleaseTask::class.java 64 ) { task -> 65 task.referenceApiFile.set(lastReleasedApiFile.resourceFile) 66 task.apiLocation.set(generateResourceApi.flatMap { it.apiLocation }) 67 // Since apiLocation isn't a File, we have to manually set up the dependency. 68 task.dependsOn(generateResourceApi) 69 task.cacheEvenIfNoOutputs() 70 } 71 } 72 73 // Policy: All changes to API surfaces for which compatibility is enforced must be 74 // explicitly confirmed by running the updateApi task. To enforce this, the implementation 75 // checks the "work-in-progress" built API file against the checked in current API file. 76 val checkResourceApi = 77 project.tasks.register(CHECK_RESOURCE_API_TASK, CheckResourceApiTask::class.java) { task 78 -> 79 task.group = TASK_GROUP_API 80 task.description = 81 "Checks that the resource API generated from source matches the " + 82 "checked in resource API file" 83 task.apiLocation.set(generateResourceApi.flatMap { it.apiLocation }) 84 // Since apiLocation isn't a File, we have to manually set up the dependency. 85 task.dependsOn(generateResourceApi) 86 task.cacheEvenIfNoOutputs() 87 task.checkedInApiFiles.set(outputApiFiles) 88 checkResourceApiRelease?.let { task.dependsOn(it) } 89 } 90 91 val updateResourceApi = 92 project.tasks.register(UPDATE_RESOURCE_API_TASK, UpdateResourceApiTask::class.java) { 93 task -> 94 task.group = TASK_GROUP_API 95 task.description = 96 "Updates the checked in resource API files to match source code API" 97 task.apiLocation.set(generateResourceApi.flatMap { it.apiLocation }) 98 // Since apiLocation isn't a File, we have to manually set up the dependency. 99 task.dependsOn(generateResourceApi) 100 task.outputApiLocations.set(outputApiLocations) 101 task.forceUpdate.set(project.providers.gradleProperty("force").isPresent) 102 checkResourceApiRelease?.let { 103 // If a developer (accidentally) makes a non-backwards compatible change to an 104 // API, the developer will want to be informed of it as soon as possible. 105 // So, whenever a developer updates an API, if backwards compatibility checks 106 // are 107 // enabled in the library, then we want to check that the changes are backwards 108 // compatible 109 task.dependsOn(it) 110 } 111 } 112 113 // Ensure that this task runs as part of "updateApi" task from MetalavaTasks. 114 project.tasks.withType(UpdateApiTask::class.java).configureEach { task -> 115 task.dependsOn(updateResourceApi) 116 } 117 118 project.addToCheckTask(checkResourceApi) 119 project.addToBuildOnServer(checkResourceApi) 120 } 121 } 122