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