blob: 36606040f93921be47606ab074533a5366cafd92 [file] [log] [blame]
Yigit Boyar19b41102016-11-20 10:46:32 -08001/*
2 * Copyright (C) 2016 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 */
Aurimas Liutikas7f40a7e2017-10-27 17:55:06 -070016
Owen Gray74cc2592020-09-24 15:05:40 -040017import androidx.build.BuildOnServerKt
Owen Gray74cc2592020-09-24 15:05:40 -040018import androidx.build.LibraryType
19import androidx.build.SupportConfig
20import androidx.build.SdkHelperKt
Aurimas Liutikas04a624d2021-08-10 14:12:14 -070021import java.util.zip.ZipEntry
22import java.util.zip.ZipFile
Yigit Boyar9b3d20b2020-07-05 10:48:05 -070023import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
24
Aurimas Liutikas526389b2018-02-27 14:01:24 -080025plugins {
Aurimas Liutikas65d3d602019-04-01 23:08:13 -070026 id("AndroidXPlugin")
27 id("kotlin")
Yigit Boyar562a37d2020-03-16 13:00:36 -070028 id("com.github.johnrengelman.shadow")
Aurimas Liutikas526389b2018-02-27 14:01:24 -080029}
Yigit Boyar19b41102016-11-20 10:46:32 -080030
31def antlrOut = "$buildDir/generated/antlr/grammar-gen/"
32sourceSets {
Jim Sproch9e38b4f2021-01-06 14:21:06 -080033 main.java.srcDirs += "src/main/grammar-gen"
Yigit Boyar19b41102016-11-20 10:46:32 -080034 main.java.srcDirs += antlrOut
35}
Sergey Vasilinets0af2c3f2017-07-20 12:48:16 -070036
Yigit Boyar562a37d2020-03-16 13:00:36 -070037configurations {
38 /**
39 * shadowed is used for dependencies which we jarjar into the library jar instead of adding it
40 * as a pom dependency
41 */
42 shadowed
43 // make sure shadowed dependencies show up as compileOnly so that normal compilation works
44 compileOnly.extendsFrom(shadowed)
45 // compiler tests run w/o shadowed classes so we should add those dependencies into test
46 // configuration
47 testCompile.extendsFrom(shadowed)
48 // for downstream tests, provide a configuration that includes the shadow output + other
49 // dependencies that are not shadowed
50 shadowAndImplementation.extendsFrom(shadow)
51 shadowAndImplementation.extendsFrom(implementation)
52}
53
54shadowJar {
55 // set classifier to empty string so that it doesn't append anything to the jar.
Jim Sproch9e38b4f2021-01-06 14:21:06 -080056 archiveClassifier = ""
Yigit Boyar562a37d2020-03-16 13:00:36 -070057 configurations = [project.configurations.shadowed]
58 dependencies {
59 // antlr has dependencies on unrelated projects for its gui stuff, do not include them
Jim Sproch9e38b4f2021-01-06 14:21:06 -080060 exclude(dependency("org.abego.treelayout:.*"))
61 exclude(dependency("org.glassfish:.*"))
62 exclude(dependency("com.ibm.icu:.*"))
Yigit Boyar562a37d2020-03-16 13:00:36 -070063 }
Aurimas Liutikas04a624d2021-08-10 14:12:14 -070064 relocate("org.antlr", "androidx.room.jarjarred.org.antlr")
65 relocate("org.stringtemplate", "androidx.room.jarjarred.org.stringtemplate")
Yigit Boyar562a37d2020-03-16 13:00:36 -070066}
67
68jar {
69 // set a classifier on this one so that the output does not clash with the output from
70 // shadowJar task. We should never use this directly as it won't have the shadowed classes that
71 // are necessary to run.
Jim Sproch9e38b4f2021-01-06 14:21:06 -080072 archiveClassifier = "before-jarjar"
Yigit Boyar562a37d2020-03-16 13:00:36 -070073}
74
Yigit Boyar562a37d2020-03-16 13:00:36 -070075configurations {
76 // replace the standard jar with the one built by 'shadowJar' in both api and runtime variants
77 apiElements.outgoing.artifacts.clear()
78 apiElements.outgoing.artifact(shadowJar) {
79 builtBy shadowJar
80 }
81 runtimeElements.outgoing.artifacts.clear()
82 runtimeElements.outgoing.artifact(shadowJar) {
83 builtBy shadowJar
84 }
85}
86
Ember Rosec662e1a2022-09-16 14:37:50 -040087androidx.configureAarAsJarForConfiguration("testImplementation")
Aurimas Liutikas7d0ea3322022-09-13 18:47:56 -070088
Yigit Boyar19b41102016-11-20 10:46:32 -080089dependencies {
Aurimas Liutikas8a1c0392019-12-02 11:31:04 -080090 implementation(project(":room:room-common"))
91 implementation(project(":room:room-migration"))
Yigit Boyar16d78292020-08-03 16:00:18 -070092 implementation(project(":room:room-compiler-processing"))
Aurimas Liutikas1a0e7b12021-05-04 12:55:40 -070093 implementation(libs.kotlinStdlib)
94 implementation(libs.autoCommon)
95 implementation(libs.autoValueAnnotations)
96 implementation(libs.javapoet)
Aurimas Liutikase1b84582021-04-23 14:17:30 -070097 implementation(libs.kspApi)
Aurimas Liutikas1a0e7b12021-05-04 12:55:40 -070098 shadowed(libs.antlr4)
99 implementation(libs.sqliteJdbc)
100 implementation(libs.kotlinMetadataJvm)
101 implementation(libs.apacheCommonsCodec)
102 implementation(libs.intellijAnnotations)
103 testImplementation(libs.truth)
104 testImplementation(libs.autoValue) // to access the processor in tests
Daniel Santiago Rivera7cb40412021-09-02 13:57:38 -0700105 testImplementation(libs.autoServiceAnnotations)
106 testImplementation(libs.autoService) // to access the processor in tests
Jim Sproch9e38b4f2021-01-06 14:21:06 -0800107 testImplementation(projectOrArtifact(":paging:paging-common"))
Yigit Boyarf1dce272020-12-07 22:29:16 -0800108 testImplementation(project(":room:room-compiler-processing-testing"))
Aurimas Liutikas1a0e7b12021-05-04 12:55:40 -0700109 testImplementation(libs.junit)
110 testImplementation(libs.jsr250)
111 testImplementation(libs.mockitoCore)
112 testImplementation(libs.antlr4)
Yigit Boyar577a3a62021-09-13 18:40:16 -0700113 testImplementation(libs.kotlinCompilerEmbeddable)
Jim Sproch9e38b4f2021-01-06 14:21:06 -0800114 testImplementation(fileTree(
Alan Viverettebb04f2e2020-04-09 17:13:37 -0400115 dir: "${SdkHelperKt.getSdkPath(project)}/platforms/$SupportConfig.COMPILE_SDK_VERSION/",
116 include : "android.jar"
Jim Sproch9e38b4f2021-01-06 14:21:06 -0800117 ))
Ember Rosec662e1a2022-09-16 14:37:50 -0400118 testImplementationAarAsJar(project(":room:room-runtime"))
119 testImplementationAarAsJar(project(":sqlite:sqlite"))
Kuan-Ying Choufa34a942021-12-20 18:34:56 +0000120 testImplementation(project(":internal-testutils-common"))
Yigit Boyar19b41102016-11-20 10:46:32 -0800121}
122
Aurimas Liutikas6f9301c2021-11-05 10:28:38 -0700123def generateAntlrTask = task("generateAntlrGrammar", type: GenerateAntlrGrammar) {
Aurimas Liutikas6f9301c2021-11-05 10:28:38 -0700124 sqliteFile = file("$projectDir/SQLite.g4")
Daz DeBoer0b80c762021-11-17 09:26:31 -0700125 antlrClasspath = configurations.compileClasspath
126 outputDirectory = file(antlrOut)
Yigit Boyar19b41102016-11-20 10:46:32 -0800127}
128
Aurimas Liutikas6f9301c2021-11-05 10:28:38 -0700129@CacheableTask
Daz DeBoer0b80c762021-11-17 09:26:31 -0700130abstract class GenerateAntlrGrammar extends DefaultTask {
Aurimas Liutikas6f9301c2021-11-05 10:28:38 -0700131 @PathSensitive(PathSensitivity.NONE)
132 @InputFile
133 File sqliteFile
134
Daz DeBoer0b80c762021-11-17 09:26:31 -0700135 @Classpath
136 FileCollection antlrClasspath
137
Aurimas Liutikas6f9301c2021-11-05 10:28:38 -0700138 @OutputDirectory
139 File outputDirectory
140
Daz DeBoer0b80c762021-11-17 09:26:31 -0700141 @Inject
142 abstract ExecOperations getExecOperations()
143
144 @Inject
Aurimas Liutikas6f9301c2021-11-05 10:28:38 -0700145 public GenerateAntlrGrammar() {
146 description("Generates Antlr Grammar used by room")
147 group("build")
Daz DeBoer0b80c762021-11-17 09:26:31 -0700148 }
149
150 @TaskAction
151 void generateAntlrGrammar() {
152 execOperations.javaexec {
153 mainClass.set("org.antlr.v4.Tool")
154 classpath = antlrClasspath
155 args "SQLite.g4",
156 "-visitor",
157 "-o", new File(outputDirectory, "androidx/room/parser").path,
158 "-package", "androidx.room.parser"
159 }
Aurimas Liutikas6f9301c2021-11-05 10:28:38 -0700160 }
161}
162
Yigit Boyar562a37d2020-03-16 13:00:36 -0700163/**
164 * Room compiler jarjars some dependencies. This task validates the published artifacts of room
165 * compiler to ensure dependencies are properly jarjarred.
166 */
167class CheckArtifactTask extends DefaultTask {
168 @InputFiles
169 FileCollection artifactInputs = project.objects.fileCollection()
170 @InputFile
171 File pomFile
172 @OutputFile
173 File result = new File(project.buildDir, "checkArtifactOutput.txt")
174 /**
175 * Checks the publish task's artifacts to make sure the classes.jar does include jarjarred
176 * antlr classes.
177 */
178 def validatePublishTaskOutputs() {
179 if (artifactInputs.files.isEmpty()) {
180 throw new GradleException("Couldn't find the classes.jar for the room-compiler " +
181 "artifact. Ensure that publish is setup properly.")
182 }
183 artifactInputs.forEach {
184 validateJarContents(it)
185 }
186 }
187
188 /**
189 * Traverses the given jar file, looks for the classes that should be jarjarred and validates
190 * their location.
191 */
192 def validateJarContents(File jarFile) {
Aurimas Liutikas04a624d2021-08-10 14:12:14 -0700193 Boolean found = false
194 ZipFile zip = new ZipFile(jarFile)
195 try {
196 for (Enumeration list = zip.entries(); list.hasMoreElements(); ) {
197 String entry = ((ZipEntry) list.nextElement()).name
198 if (!entry.endsWith(".class")) continue
199 if (entry.contains("org/antlr")) {
200 found = true
201 if (!entry.contains("androidx/room/jarjarred/org/antlr")) {
202 throw new GradleException("Any Antlr class included in the Room Compiler's" +
203 " jar file should be moved into androidx/room/jarjarred.\n" +
204 "Looks like $entry has not been moved")
205 }
206 }
Daniel Santiago Rivera399f8f42021-08-11 07:33:45 -0700207 if (!entry.startsWith("androidx/room/")) {
Aurimas Liutikas04a624d2021-08-10 14:12:14 -0700208 throw new GradleException("Found a class that is not in androidx.room " +
209 "package: $entry")
Yigit Boyar562a37d2020-03-16 13:00:36 -0700210 }
211 }
Aurimas Liutikas04a624d2021-08-10 14:12:14 -0700212 } finally {
213 zip.close()
Yigit Boyar562a37d2020-03-16 13:00:36 -0700214 }
215 if (!found) {
216 throw new GradleException("Couldn't find any Antlr classes in room-compiler artifact" +
217 ".\n Antlr is jarjarred into room-compiler so there should be some files")
218 }
219 }
220
221 /**
222 * Checks the generated pom file to ensure it does not depend on any jarjarred dependencies
223 * but still depends on others.
224 */
225 def validatePomTaskOutputs() {
226 if (!pomFile.canRead()) {
227 throw new GradleException("Cannot find the pom file for room-compiler")
228 }
229 def pomContents = pomFile.newReader().text
230 if (pomContents.contains("antlr")) {
231 throw new GradleException("Room-compiler pom file should not depend on antlr.\n" +
232 "Pom Contents:\n $pomContents")
233 }
234 if(!pomContents.contains("<artifactId>kotlin-stdlib</artifactId>")) {
235 throw new GradleException("room-compiler should depend on kotlin stdlib.\n" +
236 "Pom Contents:\n $pomContents")
237 }
238 }
239
240 @TaskAction
241 def validate() {
242 result.write("fail\n")
243 validatePublishTaskOutputs()
244 validatePomTaskOutputs()
Daniel Santiago Riverad8d57ba2020-07-30 10:47:26 -0700245 // have a no-op output to make gradle happy w/ input/output checking.
Yigit Boyar562a37d2020-03-16 13:00:36 -0700246 result.write("ok\n")
247 }
248}
249
250def checkArtifactContentsTask = tasks.register("checkArtifactTask", CheckArtifactTask) {
Aurimas Liutikas816e3872022-07-19 11:33:48 -0700251 def pomTask = (GenerateMavenPom) project.tasks.named("generatePomFileForMavenPublication").get()
252 it.pomFile = pomTask.destination
253}
254
255afterEvaluate {
256 def publishTaskProvider = project.tasks.named("publishMavenPublicationToMavenRepository")
257 checkArtifactContentsTask.configure {
258 it.artifactInputs.from {
259 publishTaskProvider.map {
260 ((PublishToMavenRepository) it).getPublication().artifacts.matching {
261 it.classifier == null
262 }.collect {
263 it.file
264 }
265 }
Yigit Boyar562a37d2020-03-16 13:00:36 -0700266 }
267 }
Yigit Boyar562a37d2020-03-16 13:00:36 -0700268}
269
270// make sure we validate published artifacts on the build server.
271BuildOnServerKt.addToBuildOnServer(project, checkArtifactContentsTask)
272
Yigit Boyar19b41102016-11-20 10:46:32 -0800273tasks.findByName("compileKotlin").dependsOn(generateAntlrTask)
Jeff Gaston787e3c32020-08-10 16:51:40 -0400274tasks.findByName("sourceJar").dependsOn(generateAntlrTask)
Yigit Boyar19b41102016-11-20 10:46:32 -0800275
Yigit Boyar9b3d20b2020-07-05 10:48:05 -0700276tasks.withType(KotlinCompile).configureEach {
277 kotlinOptions {
Daniel Santiago Riveraceb65a62021-06-09 10:03:57 -0700278 freeCompilerArgs += [
Daniel Santiago Riveradc6ad792022-04-21 14:16:43 +0000279 "-Xjvm-default=all",
Jim Sprochbcbd33a2022-01-12 14:45:37 -0800280 "-opt-in=kotlin.contracts.ExperimentalContracts",
281 "-opt-in=androidx.room.compiler.processing.ExperimentalProcessingApi"
Daniel Santiago Riveraceb65a62021-06-09 10:03:57 -0700282 ]
Yigit Boyar9b3d20b2020-07-05 10:48:05 -0700283 }
284}
285
Yigit Boyar40b5cb32021-01-25 22:47:35 -0800286tasks.withType(Test).configureEach {
287 it.systemProperty("androidx.room.compiler.processing.strict", "true")
Aurimas Liutikasf58a25f2022-03-07 11:09:56 -0800288 it.maxParallelForks(3)
Dustin Lam10b44a62022-04-06 00:14:47 +0000289 if (project.providers.environmentVariable("GITHUB_ACTIONS").present) {
290 // limit memory usage to avoid running out of memory in the docker container.
291 it.maxHeapSize("512m")
292 }
Yigit Boyar40b5cb32021-01-25 22:47:35 -0800293}
294
Aurimas Liutikas2ad31612019-04-01 04:23:03 -0700295androidx {
Aurimas Liutikasea5ee822017-11-06 12:52:28 -0800296 name = "Android Room Compiler"
Daniel Santiago Rivera565946b2022-08-01 11:49:07 -0700297 type = LibraryType.ANNOTATION_PROCESSOR
Aurimas Liutikas7f40a7e2017-10-27 17:55:06 -0700298 mavenGroup = LibraryGroups.ROOM
Aurimas Liutikasea5ee822017-11-06 12:52:28 -0800299 inceptionYear = "2017"
300 description = "Android Room annotation processor"
Yigit Boyard809f482017-09-13 16:02:16 -0700301}