xref: /aosp_15_r20/external/robolectric/build.gradle.kts (revision e6ba16074e6af37d123cb567d575f496bf0a58ee)

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