xref: /aosp_15_r20/external/robolectric/build.gradle.kts (revision e6ba16074e6af37d123cb567d575f496bf0a58ee)
1*e6ba1607SAndroid Build Coastguard Worker import groovy.util.Node
2*e6ba1607SAndroid Build Coastguard Worker import org.gradle.plugins.ide.idea.model.IdeaModel
3*e6ba1607SAndroid Build Coastguard Worker import org.robolectric.gradle.ShadowsPlugin.ShadowsPluginExtension
4*e6ba1607SAndroid Build Coastguard Worker 
5*e6ba1607SAndroid Build Coastguard Worker // https://github.com/gradle/gradle/issues/21267
6*e6ba1607SAndroid Build Coastguard Worker val axtCoreVersion by project.extra { libs.versions.androidx.test.core.get() }
7*e6ba1607SAndroid Build Coastguard Worker val axtJunitVersion by project.extra { libs.versions.androidx.test.ext.junit.get() }
8*e6ba1607SAndroid Build Coastguard Worker val axtMonitorVersion by project.extra { libs.versions.androidx.test.monitor.get() }
9*e6ba1607SAndroid Build Coastguard Worker val axtRunnerVersion by project.extra { libs.versions.androidx.test.runner.get() }
10*e6ba1607SAndroid Build Coastguard Worker val axtTruthVersion by project.extra { libs.versions.androidx.test.ext.truth.get() }
11*e6ba1607SAndroid Build Coastguard Worker val espressoVersion by project.extra { libs.versions.androidx.test.espresso.get() }
12*e6ba1607SAndroid Build Coastguard Worker 
13*e6ba1607SAndroid Build Coastguard Worker // For use of external initialization scripts...
14*e6ba1607SAndroid Build Coastguard Worker val allSdks by project.extra(AndroidSdk.ALL_SDKS)
15*e6ba1607SAndroid Build Coastguard Worker val configAnnotationProcessing by project.extra(emptyList<Project>())
16*e6ba1607SAndroid Build Coastguard Worker 
17*e6ba1607SAndroid Build Coastguard Worker val thisVersion: String by project
18*e6ba1607SAndroid Build Coastguard Worker 
19*e6ba1607SAndroid Build Coastguard Worker plugins {
20*e6ba1607SAndroid Build Coastguard Worker   alias(libs.plugins.android.library) apply false
21*e6ba1607SAndroid Build Coastguard Worker   alias(libs.plugins.detekt) apply false
22*e6ba1607SAndroid Build Coastguard Worker   alias(libs.plugins.error.prone)
23*e6ba1607SAndroid Build Coastguard Worker   alias(libs.plugins.idea)
24*e6ba1607SAndroid Build Coastguard Worker   alias(libs.plugins.kotlin.android) apply false
25*e6ba1607SAndroid Build Coastguard Worker   alias(libs.plugins.kotlin.jvm) apply false
26*e6ba1607SAndroid Build Coastguard Worker   alias(libs.plugins.robolectric.spotless)
27*e6ba1607SAndroid Build Coastguard Worker   alias(libs.plugins.robolectric.javadoc)
28*e6ba1607SAndroid Build Coastguard Worker   alias(libs.plugins.roborazzi) apply false
29*e6ba1607SAndroid Build Coastguard Worker }
30*e6ba1607SAndroid Build Coastguard Worker 
31*e6ba1607SAndroid Build Coastguard Worker allprojects {
32*e6ba1607SAndroid Build Coastguard Worker   group = "org.robolectric"
33*e6ba1607SAndroid Build Coastguard Worker   version = thisVersion
34*e6ba1607SAndroid Build Coastguard Worker }
35*e6ba1607SAndroid Build Coastguard Worker 
36*e6ba1607SAndroid Build Coastguard Worker project.afterEvaluate {
37*e6ba1607SAndroid Build Coastguard Worker   val ideaProject = rootProject.extensions.getByType<IdeaModel>().project
38*e6ba1607SAndroid Build Coastguard Worker   ideaProject.ipr.withXml {
39*e6ba1607SAndroid Build Coastguard Worker     val compilerConfiguration =
40*e6ba1607SAndroid Build Coastguard Worker       asNode().children().filterIsInstance<Node>().first {
41*e6ba1607SAndroid Build Coastguard Worker         it.name() == "component" && it.attribute("name") == "CompilerConfiguration"
42*e6ba1607SAndroid Build Coastguard Worker       }
43*e6ba1607SAndroid Build Coastguard Worker 
44*e6ba1607SAndroid Build Coastguard Worker     // Prevent compiler from complaining about duplicate classes...
45*e6ba1607SAndroid Build Coastguard Worker     val excludeFromCompile = compilerConfiguration.appendNode("excludeFromCompile")
46*e6ba1607SAndroid Build Coastguard Worker     configAnnotationProcessing.forEach { subproject ->
47*e6ba1607SAndroid Build Coastguard Worker       val buildDirectory = subproject.layout.buildDirectory.get().asFile
48*e6ba1607SAndroid Build Coastguard Worker       excludeFromCompile.appendNode(
49*e6ba1607SAndroid Build Coastguard Worker         "directory",
50*e6ba1607SAndroid Build Coastguard Worker         mapOf(
51*e6ba1607SAndroid Build Coastguard Worker           "url" to "file://$buildDirectory/classes/java/main/generated",
52*e6ba1607SAndroid Build Coastguard Worker           "includeSubdirectories" to "true",
53*e6ba1607SAndroid Build Coastguard Worker         ),
54*e6ba1607SAndroid Build Coastguard Worker       )
55*e6ba1607SAndroid Build Coastguard Worker     }
56*e6ba1607SAndroid Build Coastguard Worker 
57*e6ba1607SAndroid Build Coastguard Worker     // Replace the existing "annotationProcessing" tag with a new one...
58*e6ba1607SAndroid Build Coastguard Worker     val annotationProcessingNode = Node(compilerConfiguration, "annotationProcessing")
59*e6ba1607SAndroid Build Coastguard Worker     configAnnotationProcessing.forEach { subproject ->
60*e6ba1607SAndroid Build Coastguard Worker       val profileNode =
61*e6ba1607SAndroid Build Coastguard Worker         Node(
62*e6ba1607SAndroid Build Coastguard Worker           annotationProcessingNode,
63*e6ba1607SAndroid Build Coastguard Worker           "profile",
64*e6ba1607SAndroid Build Coastguard Worker           mapOf("name" to "${subproject.name}_main", "enabled" to "true"),
65*e6ba1607SAndroid Build Coastguard Worker         )
66*e6ba1607SAndroid Build Coastguard Worker       profileNode.appendNode("module", mapOf("name" to "${subproject.name}_main"))
67*e6ba1607SAndroid Build Coastguard Worker       profileNode.appendNode(
68*e6ba1607SAndroid Build Coastguard Worker         "option",
69*e6ba1607SAndroid Build Coastguard Worker         mapOf(
70*e6ba1607SAndroid Build Coastguard Worker           "name" to "org.robolectric.annotation.processing.shadowPackage",
71*e6ba1607SAndroid Build Coastguard Worker           "value" to project.extensions.getByType<ShadowsPluginExtension>().packageName,
72*e6ba1607SAndroid Build Coastguard Worker         ),
73*e6ba1607SAndroid Build Coastguard Worker       )
74*e6ba1607SAndroid Build Coastguard Worker       profileNode.appendNode(
75*e6ba1607SAndroid Build Coastguard Worker         "processor",
76*e6ba1607SAndroid Build Coastguard Worker         mapOf("name" to "org.robolectric.annotation.processing.RobolectricProcessor"),
77*e6ba1607SAndroid Build Coastguard Worker       )
78*e6ba1607SAndroid Build Coastguard Worker 
79*e6ba1607SAndroid Build Coastguard Worker       val processorPathNode = Node(profileNode, "processorPath", mapOf("useClasspath" to "false"))
80*e6ba1607SAndroid Build Coastguard Worker       project.project(":processor").configurations.named("runtime").configure {
81*e6ba1607SAndroid Build Coastguard Worker         allArtifacts.forEach { artifact ->
82*e6ba1607SAndroid Build Coastguard Worker           processorPathNode.appendNode("entry", mapOf("name" to artifact.file))
83*e6ba1607SAndroid Build Coastguard Worker         }
84*e6ba1607SAndroid Build Coastguard Worker         files.forEach { file -> processorPathNode.appendNode("entry", mapOf("name" to file)) }
85*e6ba1607SAndroid Build Coastguard Worker       }
86*e6ba1607SAndroid Build Coastguard Worker 
87*e6ba1607SAndroid Build Coastguard Worker       profileNode.appendNode(processorPathNode)
88*e6ba1607SAndroid Build Coastguard Worker       annotationProcessingNode.appendNode(profileNode)
89*e6ba1607SAndroid Build Coastguard Worker     }
90*e6ba1607SAndroid Build Coastguard Worker 
91*e6ba1607SAndroid Build Coastguard Worker     compilerConfiguration.replaceNode(annotationProcessingNode)
92*e6ba1607SAndroid Build Coastguard Worker   }
93*e6ba1607SAndroid Build Coastguard Worker }
94*e6ba1607SAndroid Build Coastguard Worker 
95*e6ba1607SAndroid Build Coastguard Worker rootProject.gradle.projectsEvaluated {
96*e6ba1607SAndroid Build Coastguard Worker   rootProject.tasks.named<Javadoc>("aggregateJavadocs").configure { isFailOnError = false }
97*e6ba1607SAndroid Build Coastguard Worker }
98*e6ba1607SAndroid Build Coastguard Worker 
99*e6ba1607SAndroid Build Coastguard Worker gradle.projectsEvaluated {
100*e6ba1607SAndroid Build Coastguard Worker   val headerHtml =
101*e6ba1607SAndroid Build Coastguard Worker     """
102*e6ba1607SAndroid Build Coastguard Worker     <ul class="navList" style="font-size: 1.5em;">
103*e6ba1607SAndroid Build Coastguard Worker       <li>
104*e6ba1607SAndroid Build Coastguard Worker         Robolectric $thisVersion |&nbsp;
105*e6ba1607SAndroid Build Coastguard Worker         <a href="/" target="_top">
106*e6ba1607SAndroid Build Coastguard Worker           <img src="https://robolectric.org/images/logo-with-bubbles-down.png" style="max-height: 18pt; vertical-align: sub;"/>
107*e6ba1607SAndroid Build Coastguard Worker         </a>
108*e6ba1607SAndroid Build Coastguard Worker       </li>
109*e6ba1607SAndroid Build Coastguard Worker     </ul>
110*e6ba1607SAndroid Build Coastguard Worker     """
111*e6ba1607SAndroid Build Coastguard Worker       .trimIndent()
112*e6ba1607SAndroid Build Coastguard Worker 
113*e6ba1607SAndroid Build Coastguard Worker   project.allprojects {
114*e6ba1607SAndroid Build Coastguard Worker     tasks.withType<Javadoc> {
115*e6ba1607SAndroid Build Coastguard Worker       options {
116*e6ba1607SAndroid Build Coastguard Worker         this as StandardJavadocDocletOptions
117*e6ba1607SAndroid Build Coastguard Worker 
118*e6ba1607SAndroid Build Coastguard Worker         noTimestamp(true)
119*e6ba1607SAndroid Build Coastguard Worker         links(
120*e6ba1607SAndroid Build Coastguard Worker           "https://docs.oracle.com/javase/8/docs/api/",
121*e6ba1607SAndroid Build Coastguard Worker           "https://developer.android.com/reference/",
122*e6ba1607SAndroid Build Coastguard Worker         )
123*e6ba1607SAndroid Build Coastguard Worker         // Set Javadoc source to JDK 8 to avoid unnamed module problem
124*e6ba1607SAndroid Build Coastguard Worker         // when running 'aggregateJavadocs' with OpenJDK 13+.
125*e6ba1607SAndroid Build Coastguard Worker         source("8")
126*e6ba1607SAndroid Build Coastguard Worker         header = headerHtml
127*e6ba1607SAndroid Build Coastguard Worker         footer = headerHtml
128*e6ba1607SAndroid Build Coastguard Worker       }
129*e6ba1607SAndroid Build Coastguard Worker     }
130*e6ba1607SAndroid Build Coastguard Worker   }
131*e6ba1607SAndroid Build Coastguard Worker 
132*e6ba1607SAndroid Build Coastguard Worker   val aggregateJsondocs by
133*e6ba1607SAndroid Build Coastguard Worker     tasks.registering(Copy::class) {
134*e6ba1607SAndroid Build Coastguard Worker       project.subprojects
135*e6ba1607SAndroid Build Coastguard Worker         .filter { it.pluginManager.hasPlugin(libs.plugins.robolectric.shadows.get().pluginId) }
136*e6ba1607SAndroid Build Coastguard Worker         .forEach { subproject ->
137*e6ba1607SAndroid Build Coastguard Worker           dependsOn(subproject.tasks.named("compileJava"))
138*e6ba1607SAndroid Build Coastguard Worker           from(subproject.layout.buildDirectory.dir("docs/json"))
139*e6ba1607SAndroid Build Coastguard Worker         }
140*e6ba1607SAndroid Build Coastguard Worker 
141*e6ba1607SAndroid Build Coastguard Worker       into(layout.buildDirectory.dir("docs/json"))
142*e6ba1607SAndroid Build Coastguard Worker     }
143*e6ba1607SAndroid Build Coastguard Worker }
144*e6ba1607SAndroid Build Coastguard Worker 
145*e6ba1607SAndroid Build Coastguard Worker val aggregateDocs by tasks.registering { dependsOn(":aggregateJavadocs", ":aggregateJsondocs") }
146*e6ba1607SAndroid Build Coastguard Worker 
147*e6ba1607SAndroid Build Coastguard Worker val prefetchSdks by
148*e6ba1607SAndroid Build Coastguard Worker   tasks.registering {
149*e6ba1607SAndroid Build Coastguard Worker     allSdks.forEach { androidSdk ->
150*e6ba1607SAndroid Build Coastguard Worker       doLast {
151*e6ba1607SAndroid Build Coastguard Worker         prefetchSdk(
152*e6ba1607SAndroid Build Coastguard Worker           apiLevel = androidSdk.apiLevel,
153*e6ba1607SAndroid Build Coastguard Worker           coordinates = androidSdk.coordinates,
154*e6ba1607SAndroid Build Coastguard Worker           groupId = androidSdk.groupId,
155*e6ba1607SAndroid Build Coastguard Worker           artifactId = androidSdk.artifactId,
156*e6ba1607SAndroid Build Coastguard Worker           version = androidSdk.version,
157*e6ba1607SAndroid Build Coastguard Worker         )
158*e6ba1607SAndroid Build Coastguard Worker       }
159*e6ba1607SAndroid Build Coastguard Worker     }
160*e6ba1607SAndroid Build Coastguard Worker   }
161*e6ba1607SAndroid Build Coastguard Worker 
162*e6ba1607SAndroid Build Coastguard Worker val prefetchInstrumentedSdks by
163*e6ba1607SAndroid Build Coastguard Worker   tasks.registering {
164*e6ba1607SAndroid Build Coastguard Worker     allSdks.forEach { androidSdk ->
165*e6ba1607SAndroid Build Coastguard Worker       doLast {
166*e6ba1607SAndroid Build Coastguard Worker         prefetchSdk(
167*e6ba1607SAndroid Build Coastguard Worker           apiLevel = androidSdk.apiLevel,
168*e6ba1607SAndroid Build Coastguard Worker           coordinates = androidSdk.preinstrumentedCoordinates,
169*e6ba1607SAndroid Build Coastguard Worker           groupId = androidSdk.groupId,
170*e6ba1607SAndroid Build Coastguard Worker           artifactId = androidSdk.preinstrumentedArtifactId,
171*e6ba1607SAndroid Build Coastguard Worker           version = androidSdk.preinstrumentedVersion,
172*e6ba1607SAndroid Build Coastguard Worker         )
173*e6ba1607SAndroid Build Coastguard Worker       }
174*e6ba1607SAndroid Build Coastguard Worker     }
175*e6ba1607SAndroid Build Coastguard Worker   }
176*e6ba1607SAndroid Build Coastguard Worker 
177*e6ba1607SAndroid Build Coastguard Worker fun prefetchSdk(
178*e6ba1607SAndroid Build Coastguard Worker   apiLevel: Int,
179*e6ba1607SAndroid Build Coastguard Worker   coordinates: String,
180*e6ba1607SAndroid Build Coastguard Worker   groupId: String,
181*e6ba1607SAndroid Build Coastguard Worker   artifactId: String,
182*e6ba1607SAndroid Build Coastguard Worker   version: String,
183*e6ba1607SAndroid Build Coastguard Worker ) {
184*e6ba1607SAndroid Build Coastguard Worker   println("Prefetching $coordinates...")
185*e6ba1607SAndroid Build Coastguard Worker 
186*e6ba1607SAndroid Build Coastguard Worker   // Prefetch into Maven local repo...
187*e6ba1607SAndroid Build Coastguard Worker   project.exec {
188*e6ba1607SAndroid Build Coastguard Worker     val mvnCommand =
189*e6ba1607SAndroid Build Coastguard Worker       "mvn -q dependency:get -DrepoUrl=https://maven.google.com " +
190*e6ba1607SAndroid Build Coastguard Worker         "-DgroupId=$groupId -DartifactId=$artifactId -Dversion=$version"
191*e6ba1607SAndroid Build Coastguard Worker 
192*e6ba1607SAndroid Build Coastguard Worker     commandLine(mvnCommand.split(" "))
193*e6ba1607SAndroid Build Coastguard Worker   }
194*e6ba1607SAndroid Build Coastguard Worker 
195*e6ba1607SAndroid Build Coastguard Worker   // Prefetch into Gradle local cache...
196*e6ba1607SAndroid Build Coastguard Worker   val config = configurations.create("sdk$apiLevel")
197*e6ba1607SAndroid Build Coastguard Worker   dependencies.add("sdk$apiLevel", coordinates)
198*e6ba1607SAndroid Build Coastguard Worker 
199*e6ba1607SAndroid Build Coastguard Worker   // Causes dependencies to be resolved:
200*e6ba1607SAndroid Build Coastguard Worker   config.files
201*e6ba1607SAndroid Build Coastguard Worker }
202*e6ba1607SAndroid Build Coastguard Worker 
203*e6ba1607SAndroid Build Coastguard Worker val prefetchDependencies by
204*e6ba1607SAndroid Build Coastguard Worker   tasks.registering {
205*e6ba1607SAndroid Build Coastguard Worker     doLast {
206*e6ba1607SAndroid Build Coastguard Worker       allprojects.forEach { p ->
207*e6ba1607SAndroid Build Coastguard Worker         p.configurations.forEach { config ->
208*e6ba1607SAndroid Build Coastguard Worker           // Causes dependencies to be resolved:
209*e6ba1607SAndroid Build Coastguard Worker           if (config.isCanBeResolved) {
210*e6ba1607SAndroid Build Coastguard Worker             try {
211*e6ba1607SAndroid Build Coastguard Worker               config.files
212*e6ba1607SAndroid Build Coastguard Worker             } catch (e: ResolveException) {
213*e6ba1607SAndroid Build Coastguard Worker               // Ignore resolution issues for the ':integration_tests' and ':testapp' projects, sigh
214*e6ba1607SAndroid Build Coastguard Worker               if (!p.path.startsWith(":integration_tests:") && !p.path.startsWith(":testapp")) {
215*e6ba1607SAndroid Build Coastguard Worker                 throw e
216*e6ba1607SAndroid Build Coastguard Worker               }
217*e6ba1607SAndroid Build Coastguard Worker             }
218*e6ba1607SAndroid Build Coastguard Worker           } // End config resolution
219*e6ba1607SAndroid Build Coastguard Worker         } // End configurations
220*e6ba1607SAndroid Build Coastguard Worker       } // End allprojects
221*e6ba1607SAndroid Build Coastguard Worker     } // End doLast
222*e6ba1607SAndroid Build Coastguard Worker   } // End task registration
223