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.checkapi.ApiLocation
20 import java.io.File
21 import org.gradle.api.DefaultTask
22 import org.gradle.api.GradleException
23 import org.gradle.api.file.RegularFileProperty
24 import org.gradle.api.provider.Property
25 import org.gradle.api.tasks.CacheableTask
26 import org.gradle.api.tasks.InputFiles
27 import org.gradle.api.tasks.Internal
28 import org.gradle.api.tasks.OutputFile
29 import org.gradle.api.tasks.PathSensitive
30 import org.gradle.api.tasks.PathSensitivity
31 import org.gradle.api.tasks.TaskAction
32 
33 /** Generates a resource API file for consumption by other API tasks. */
34 @CacheableTask
35 abstract class GenerateResourceApiTask : DefaultTask() {
36     /**
37      * Public resources text file generated by AAPT.
38      *
39      * This file must be defined, but the file may not exist on the filesystem if the library has no
40      * resources. In that case, we will generate an empty API signature file.
41      */
42     @get:InputFiles // InputFiles allows non-existent files, whereas InputFile does not.
43     @get:PathSensitive(PathSensitivity.RELATIVE)
44     abstract val builtApi: RegularFileProperty
45 
46     /** Source files against which API signatures will be validated. */
47     @get:[InputFiles PathSensitive(PathSensitivity.RELATIVE)]
48     var sourcePaths: Collection<File> = emptyList()
49 
50     /** Text file to which API signatures will be written. */
51     @get:Internal abstract val apiLocation: Property<ApiLocation>
52 
53     @OutputFile
54     fun getTaskOutput(): File {
55         return apiLocation.get().resourceFile
56     }
57 
58     @TaskAction
59     fun generateResourceApi() {
60         val builtApiFile = builtApi.get().asFile
61         val sortedApiLines =
62             if (builtApiFile.exists()) {
63                 builtApiFile.readLines().toSortedSet()
64             } else {
65                 val errorMessage =
66                     """No public resources defined
67 
68 At least one public resource must be defined to prevent all resources from
69 appearing public by  default.
70 
71 This exception should never occur for AndroidX projects, as a <public />
72 resource is added by default to all library project. Please contact the
73 AndroidX Core team for assistance."""
74                 throw GradleException(errorMessage)
75             }
76 
77         val outputApiFile = apiLocation.get().resourceFile
78         outputApiFile.bufferedWriter().use { out ->
79             sortedApiLines.forEach {
80                 out.write(it)
81                 out.newLine()
82             }
83         }
84     }
85 }
86