blob: 32d2f1ef1c5456c5738df419587915eb5d0aa4e6 [file] [log] [blame]
Jeff Gastond72edf22021-08-24 11:53:54 -04001import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
2
3apply plugin: "kotlin"
4apply from: "../kotlin-dsl-dependency.gradle"
Jeff Gaston5e3e7de2022-04-21 14:49:47 -04005apply plugin: "java-gradle-plugin"
Jeff Gastond72edf22021-08-24 11:53:54 -04006
7buildscript {
8 project.ext.supportRootFolder = project.projectDir.getParentFile().getParentFile()
9 apply from: "../repos.gradle"
10 repos.addMavenRepositories(repositories)
11 dependencies {
12 classpath(libs.kotlinGradlePluginz)
13 }
14}
15
16configurations {
17 // Dependencies added to these configurations get copied into the corresponding configuration
18 // (cacheableApi gets copied into api, etc).
19 // Because we cache the resolutions of these configurations, performance is faster when
20 // artifacts are put into these configurations than when those artifacts are put into their
21 // corresponding configuration.
22 cacheableApi
23 cacheableImplementation {
24 extendsFrom(project.configurations.cacheableApi)
25 }
26 cacheableRuntimeOnly
27}
28
29dependencies {
Aurimas Liutikasd084e362021-11-19 09:25:43 -080030 cacheableApi(libs.toml)
Alan Viverettefdbce5c2022-03-14 17:00:52 +000031 cacheableImplementation(libs.gson)
Alan Viverette6b52a142022-03-21 16:49:27 -040032 cacheableImplementation(libs.dom4j) {
33 // Optional dependency where Ivy fails to parse the POM file.
34 exclude(group:"net.java.dev.msv", module:"xsdlib")
35 }
Jeff Gastond72edf22021-08-24 11:53:54 -040036 cacheableApi(libs.androidGradlePluginz)
37 cacheableImplementation(libs.dexMemberList)
38 cacheableApi(libs.kotlinGradlePluginz)
39 cacheableImplementation(gradleApi())
40 cacheableApi(libs.dokkaGradlePluginz)
41 // needed by inspection plugin
42 cacheableImplementation(libs.protobufGradlePluginz)
43 cacheableImplementation(libs.wireGradlePluginz)
44 cacheableImplementation(libs.shadow)
45 // dependencies that aren't used by buildSrc directly but that we resolve here so that the
46 // root project doesn't need to re-resolve them and their dependencies on every build
47 cacheableRuntimeOnly(libs.hiltAndroidGradlePluginz)
48 // room kotlintestapp uses the ksp plugin but it does not publish a plugin marker yet
49 cacheableApi(libs.kspGradlePluginz)
50 cacheableApi(libs.japicmpPluginz)
51 // dependencies whose resolutions we don't need to cache
52 compileOnly(findGradleKotlinDsl()) // Only one file in this configuration, no need to cache it
53 implementation(project(":jetpad-integration")) // Doesn't have a .pom, so not slow to load
54}
55
56// Exclude dokka coming from AGP. We don't need it and it conflicts with dackka: b/195305339
57configurations.configureEach { conf ->
58 conf.exclude(group:"org.jetbrains.dokka", module:"dokka-core")
59}
60
Jeff Gastond72edf22021-08-24 11:53:54 -040061// Saves configuration into destFile
62// Each line of destFile will be the absolute filepath of one of the files in configuration
63def saveConfigurationResolution(configuration, destFile) {
64 def resolvedConfiguration = configuration.resolvedConfiguration
65 def files = resolvedConfiguration.files
66 def paths = files.collect { f -> f.toString() }
67 def serialized = paths.join("\n")
68 destFile.text = serialized
69}
70
71// Parses a file into a list of Dependency objects representing a ResolvedConfiguration
72def parseConfigurationResolution(savedFile, throwOnError) {
73 def savedText = savedFile.text
74 def filenames = savedText.split("\n")
75 def valid = true
76 def dependencies = filenames.collect { filename ->
77 if (!project.file(filename).exists()) {
78 if (throwOnError) {
79 throw new GradleException("\nFile " + filename + " listed as a resolved dependency in " + savedFile + " does not exist!\n\nFor more information, see b/187075069")
80 } else {
81 valid = false
82 }
83 }
84 project.dependencies.create(project.files(filename))
85 }
86 if (!valid) {
87 return null
88 }
89 return dependencies
90}
91
92// Resolves a Configuration into a list of Dependency objects
93def resolveConfiguration(configuration) {
94 def resolvedName = configuration.name
95 def cacheDir = new File(project.buildDir, "/" + resolvedName)
96 def inputsFile = new File(cacheDir, "/deps")
97 def outputsFile = new File(cacheDir, "/result")
98
99 def inputText = fingerprintConfiguration(configuration)
100 def parsed = null
101 if (inputsFile.exists() && inputsFile.text == inputText) {
102 // Try to parse the previously resolved configuration, but don't give up if it mentions a
103 // nonexistent file. If something has since deleted one of the referenced files, we will
104 // try to reresolve that file later
105 parsed = parseConfigurationResolution(outputsFile, false)
106 }
107 // If the configuration has changed or if any of its files have been deleted, reresolve it
108 if (parsed == null) {
109 cacheDir.mkdirs()
110 saveConfigurationResolution(configuration, outputsFile)
111 inputsFile.text = inputText
112 // confirm that the resolved configuration parses successfully
113 parsed = parseConfigurationResolution(outputsFile, true)
114 }
115 return parsed
116}
117
118// Computes a unique string from a Configuration based on its dependencies
119// This is used for up-to-date checks
120def fingerprintConfiguration(configuration) {
121 def dependencies = configuration.allDependencies
122 def dependencyTexts = dependencies.collect { dep -> dep.group + ":" + dep.name + ":" + dep.version }
123 return dependencyTexts.join("\n")
124}
125
126// Imports the contents of fromConf into toConf
127// Uses caching to often short-circuit the resolution of fromConf
128def loadConfigurationQuicklyInto(fromConf, toConf) {
129 def resolved = resolveConfiguration(fromConf)
130 resolved.each { dep ->
131 project.dependencies.add(toConf.name, dep)
132 }
133}
134
135loadConfigurationQuicklyInto(configurations.cacheableApi, configurations.api)
136loadConfigurationQuicklyInto(configurations.cacheableImplementation, configurations.implementation)
137loadConfigurationQuicklyInto(configurations.cacheableRuntimeOnly, configurations.runtimeOnly)
138
139project.tasks.withType(Jar) { task ->
140 task.reproducibleFileOrder = true
141 task.preserveFileTimestamps = false
142}
Jeff Gaston5e3e7de2022-04-21 14:49:47 -0400143
144validatePlugins {
145 enableStricterValidation = true
146}