xref: /aosp_15_r20/tools/metalava/integration/build.gradle.kts (revision 115816f9299ab6ddd6b9673b81f34e707f6bacab)
1*115816f9SAndroid Build Coastguard Worker /*
<lambda>null2*115816f9SAndroid Build Coastguard Worker  * Copyright (C) 2023 The Android Open Source Project
3*115816f9SAndroid Build Coastguard Worker  *
4*115816f9SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*115816f9SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*115816f9SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*115816f9SAndroid Build Coastguard Worker  *
8*115816f9SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*115816f9SAndroid Build Coastguard Worker  *
10*115816f9SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*115816f9SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*115816f9SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*115816f9SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*115816f9SAndroid Build Coastguard Worker  * limitations under the License.
15*115816f9SAndroid Build Coastguard Worker  */
16*115816f9SAndroid Build Coastguard Worker 
17*115816f9SAndroid Build Coastguard Worker // Integration test project that analyzes an external dependency: see libraryToRunAgainst.
18*115816f9SAndroid Build Coastguard Worker // Set INTEGRATION=true to enable.
19*115816f9SAndroid Build Coastguard Worker 
20*115816f9SAndroid Build Coastguard Worker import com.android.build.api.attributes.BuildTypeAttr
21*115816f9SAndroid Build Coastguard Worker 
22*115816f9SAndroid Build Coastguard Worker plugins {
23*115816f9SAndroid Build Coastguard Worker     id("com.android.library") // needed for bootClasspath and AAR transforms to work
24*115816f9SAndroid Build Coastguard Worker }
25*115816f9SAndroid Build Coastguard Worker 
<lambda>null26*115816f9SAndroid Build Coastguard Worker repositories {
27*115816f9SAndroid Build Coastguard Worker     google()
28*115816f9SAndroid Build Coastguard Worker     mavenCentral()
29*115816f9SAndroid Build Coastguard Worker }
30*115816f9SAndroid Build Coastguard Worker 
31*115816f9SAndroid Build Coastguard Worker // Create two configurations used in dependencies {} block.
32*115816f9SAndroid Build Coastguard Worker val runner: Configuration by configurations.creating
<lambda>null33*115816f9SAndroid Build Coastguard Worker val libraryToRunAgainst: Configuration by configurations.creating {
34*115816f9SAndroid Build Coastguard Worker     isCanBeResolved = false
35*115816f9SAndroid Build Coastguard Worker     isCanBeConsumed = false
36*115816f9SAndroid Build Coastguard Worker }
37*115816f9SAndroid Build Coastguard Worker 
<lambda>null38*115816f9SAndroid Build Coastguard Worker dependencies {
39*115816f9SAndroid Build Coastguard Worker     libraryToRunAgainst("androidx.compose.foundation:foundation:1.4.3")
40*115816f9SAndroid Build Coastguard Worker     runner(project(":metalava"))
41*115816f9SAndroid Build Coastguard Worker }
42*115816f9SAndroid Build Coastguard Worker 
<lambda>null43*115816f9SAndroid Build Coastguard Worker android { // minimal set up to make com.android.library plugin work
44*115816f9SAndroid Build Coastguard Worker     compileSdkVersion = "android-33"
45*115816f9SAndroid Build Coastguard Worker     namespace = "com.android.tools.metalava.integration"
46*115816f9SAndroid Build Coastguard Worker }
47*115816f9SAndroid Build Coastguard Worker 
48*115816f9SAndroid Build Coastguard Worker /**
49*115816f9SAndroid Build Coastguard Worker  * Configuration used to resolve source jars for projects in libraryToRunAgainst
50*115816f9SAndroid Build Coastguard Worker  */
<lambda>null51*115816f9SAndroid Build Coastguard Worker val sources: Configuration by configurations.creating {
52*115816f9SAndroid Build Coastguard Worker     extendsFrom(libraryToRunAgainst)
53*115816f9SAndroid Build Coastguard Worker     attributes {
54*115816f9SAndroid Build Coastguard Worker         attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_RUNTIME))
55*115816f9SAndroid Build Coastguard Worker         attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.DOCUMENTATION))
56*115816f9SAndroid Build Coastguard Worker         attribute(DocsType.DOCS_TYPE_ATTRIBUTE, project.objects.named(DocsType.SOURCES))
57*115816f9SAndroid Build Coastguard Worker         attribute(
58*115816f9SAndroid Build Coastguard Worker             LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE,
59*115816f9SAndroid Build Coastguard Worker             project.objects.named(LibraryElements.JAR)
60*115816f9SAndroid Build Coastguard Worker         )
61*115816f9SAndroid Build Coastguard Worker     }
62*115816f9SAndroid Build Coastguard Worker }
63*115816f9SAndroid Build Coastguard Worker 
Configurationnull64*115816f9SAndroid Build Coastguard Worker fun Configuration.setResolveClasspathForUsage(usage: String) {
65*115816f9SAndroid Build Coastguard Worker     isCanBeConsumed = false
66*115816f9SAndroid Build Coastguard Worker     attributes {
67*115816f9SAndroid Build Coastguard Worker         attribute(Usage.USAGE_ATTRIBUTE, project.objects.named<Usage>(usage))
68*115816f9SAndroid Build Coastguard Worker         attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named<Category>(Category.LIBRARY))
69*115816f9SAndroid Build Coastguard Worker         attribute(BuildTypeAttr.ATTRIBUTE, project.objects.named<BuildTypeAttr>("release"))
70*115816f9SAndroid Build Coastguard Worker     }
71*115816f9SAndroid Build Coastguard Worker     extendsFrom(sources)
72*115816f9SAndroid Build Coastguard Worker }
73*115816f9SAndroid Build Coastguard Worker 
74*115816f9SAndroid Build Coastguard Worker /**
75*115816f9SAndroid Build Coastguard Worker  * Configuration used to resolve compile classpath for projects in libraryToRunAgainst
76*115816f9SAndroid Build Coastguard Worker  */
<lambda>null77*115816f9SAndroid Build Coastguard Worker val sourcesCompileClasspath: Configuration by configurations.creating {
78*115816f9SAndroid Build Coastguard Worker     setResolveClasspathForUsage(Usage.JAVA_API)
79*115816f9SAndroid Build Coastguard Worker }
80*115816f9SAndroid Build Coastguard Worker /**
81*115816f9SAndroid Build Coastguard Worker  * Configuration used to resolve runtime classpath for projects in libraryToRunAgainst
82*115816f9SAndroid Build Coastguard Worker  */
<lambda>null83*115816f9SAndroid Build Coastguard Worker val sourcesRuntimeClasspath: Configuration by configurations.creating {
84*115816f9SAndroid Build Coastguard Worker     setResolveClasspathForUsage(Usage.JAVA_RUNTIME)
85*115816f9SAndroid Build Coastguard Worker }
86*115816f9SAndroid Build Coastguard Worker /**
87*115816f9SAndroid Build Coastguard Worker  * Full classpath of all the dependencies needed to analyze projects in libraryToRunAgainst
88*115816f9SAndroid Build Coastguard Worker  * This includes android.jar, compile and runtime jars
89*115816f9SAndroid Build Coastguard Worker  */
90*115816f9SAndroid Build Coastguard Worker val sourceDependencyClasspath: FileCollection = files(android.bootClasspath) +
<lambda>null91*115816f9SAndroid Build Coastguard Worker     sourcesCompileClasspath.incoming.artifactView {
92*115816f9SAndroid Build Coastguard Worker         attributes {
93*115816f9SAndroid Build Coastguard Worker             attribute(Attribute.of("artifactType", String::class.java), "android-classes")
94*115816f9SAndroid Build Coastguard Worker         }
95*115816f9SAndroid Build Coastguard Worker     }.files + sourcesRuntimeClasspath.incoming.artifactView {
<lambda>null96*115816f9SAndroid Build Coastguard Worker         attributes {
97*115816f9SAndroid Build Coastguard Worker             attribute(Attribute.of("artifactType", String::class.java), "android-classes")
98*115816f9SAndroid Build Coastguard Worker         }
99*115816f9SAndroid Build Coastguard Worker     }.files
100*115816f9SAndroid Build Coastguard Worker 
101*115816f9SAndroid Build Coastguard Worker @CacheableTask
102*115816f9SAndroid Build Coastguard Worker abstract class MetalavaRunner : DefaultTask() {
103*115816f9SAndroid Build Coastguard Worker     @get:Inject
104*115816f9SAndroid Build Coastguard Worker     abstract val execOperations: ExecOperations
105*115816f9SAndroid Build Coastguard Worker     @get:[InputFiles PathSensitive(PathSensitivity.NONE)]
106*115816f9SAndroid Build Coastguard Worker     abstract var sources: File
107*115816f9SAndroid Build Coastguard Worker     @get:[InputFile PathSensitive(PathSensitivity.NONE)]
108*115816f9SAndroid Build Coastguard Worker     abstract val apiLintBaseline: RegularFileProperty
109*115816f9SAndroid Build Coastguard Worker     @get:Classpath
110*115816f9SAndroid Build Coastguard Worker     abstract val dependencyClasspath: ConfigurableFileCollection
111*115816f9SAndroid Build Coastguard Worker     @get:Classpath
112*115816f9SAndroid Build Coastguard Worker     abstract val metalavaClasspath: ConfigurableFileCollection
113*115816f9SAndroid Build Coastguard Worker     @get:OutputFile
114*115816f9SAndroid Build Coastguard Worker     abstract val signatureFile: RegularFileProperty
115*115816f9SAndroid Build Coastguard Worker 
116*115816f9SAndroid Build Coastguard Worker     @TaskAction
doThingsnull117*115816f9SAndroid Build Coastguard Worker     fun doThings() {
118*115816f9SAndroid Build Coastguard Worker         // An approximation of AndroidX usage of metalava for tracking public
119*115816f9SAndroid Build Coastguard Worker         // api surface of a library and running API lint against it.
120*115816f9SAndroid Build Coastguard Worker         execOperations.javaexec {
121*115816f9SAndroid Build Coastguard Worker             mainClass.set("com.android.tools.metalava.Driver")
122*115816f9SAndroid Build Coastguard Worker             classpath = metalavaClasspath
123*115816f9SAndroid Build Coastguard Worker             args = listOf(
124*115816f9SAndroid Build Coastguard Worker                 "--source-path",
125*115816f9SAndroid Build Coastguard Worker                 sources.absolutePath,
126*115816f9SAndroid Build Coastguard Worker                 "--api",
127*115816f9SAndroid Build Coastguard Worker                 signatureFile.get().asFile.absolutePath,
128*115816f9SAndroid Build Coastguard Worker                 "--classpath",
129*115816f9SAndroid Build Coastguard Worker                 dependencyClasspath.files.joinToString(File.pathSeparator),
130*115816f9SAndroid Build Coastguard Worker                 "--hide-annotation",
131*115816f9SAndroid Build Coastguard Worker                 "androidx.annotation.RestrictTo",
132*115816f9SAndroid Build Coastguard Worker                 "--show-unannotated",
133*115816f9SAndroid Build Coastguard Worker                 "--api-lint",
134*115816f9SAndroid Build Coastguard Worker                 "--baseline",
135*115816f9SAndroid Build Coastguard Worker                 apiLintBaseline.get().asFile.absolutePath,
136*115816f9SAndroid Build Coastguard Worker                 "--hide",
137*115816f9SAndroid Build Coastguard Worker                 listOf(
138*115816f9SAndroid Build Coastguard Worker                     "Enum",
139*115816f9SAndroid Build Coastguard Worker                     "StartWithLower",
140*115816f9SAndroid Build Coastguard Worker                     "MissingJvmstatic",
141*115816f9SAndroid Build Coastguard Worker                     "ArrayReturn",
142*115816f9SAndroid Build Coastguard Worker                     "UserHandleName",
143*115816f9SAndroid Build Coastguard Worker                 ).joinToString(),
144*115816f9SAndroid Build Coastguard Worker             )
145*115816f9SAndroid Build Coastguard Worker         }
146*115816f9SAndroid Build Coastguard Worker     }
147*115816f9SAndroid Build Coastguard Worker }
148*115816f9SAndroid Build Coastguard Worker 
149*115816f9SAndroid Build Coastguard Worker interface Injected {
150*115816f9SAndroid Build Coastguard Worker     @get:Inject val archiveOperations: ArchiveOperations
151*115816f9SAndroid Build Coastguard Worker }
152*115816f9SAndroid Build Coastguard Worker 
153*115816f9SAndroid Build Coastguard Worker /**
154*115816f9SAndroid Build Coastguard Worker  * A task that will extract all of the source jars that are added to libraryToRunAgainst
155*115816f9SAndroid Build Coastguard Worker  * configuration.
156*115816f9SAndroid Build Coastguard Worker  */
<lambda>null157*115816f9SAndroid Build Coastguard Worker val copyInputSources = tasks.register<Sync>("copyInputSources") {
158*115816f9SAndroid Build Coastguard Worker     // Store archiveOperations into a local variable to prevent access to project object
159*115816f9SAndroid Build Coastguard Worker     // during the task execution, as that breaks configuration caching.
160*115816f9SAndroid Build Coastguard Worker     val archiveOperations = project.objects.newInstance<Injected>().archiveOperations
161*115816f9SAndroid Build Coastguard Worker     from(
162*115816f9SAndroid Build Coastguard Worker         sources.incoming.artifactView { }.files.elements.map { jars ->
163*115816f9SAndroid Build Coastguard Worker             jars.map { jar ->
164*115816f9SAndroid Build Coastguard Worker                 archiveOperations.zipTree(jar)
165*115816f9SAndroid Build Coastguard Worker             }
166*115816f9SAndroid Build Coastguard Worker         }
167*115816f9SAndroid Build Coastguard Worker     )
168*115816f9SAndroid Build Coastguard Worker     into(layout.buildDirectory.dir("inputSources"))
169*115816f9SAndroid Build Coastguard Worker }
170*115816f9SAndroid Build Coastguard Worker 
<lambda>null171*115816f9SAndroid Build Coastguard Worker tasks.register<MetalavaRunner>("run") {
172*115816f9SAndroid Build Coastguard Worker     dependsOn(copyInputSources)
173*115816f9SAndroid Build Coastguard Worker     sources = copyInputSources.get().destinationDir
174*115816f9SAndroid Build Coastguard Worker     dependencyClasspath.from(sourceDependencyClasspath)
175*115816f9SAndroid Build Coastguard Worker     metalavaClasspath.from(runner)
176*115816f9SAndroid Build Coastguard Worker     signatureFile.set(layout.buildDirectory.file("current.txt"))
177*115816f9SAndroid Build Coastguard Worker     apiLintBaseline.set(layout.projectDirectory.file("api_lint.ignore"))
178*115816f9SAndroid Build Coastguard Worker     outputs.upToDateWhen { false }
179*115816f9SAndroid Build Coastguard Worker }
180