xref: /aosp_15_r20/external/accompanist/build.gradle (revision fa44fe6ae8e729aa3cfe5c03eedbbf98fb44e2c6)
1/*
2 * Copyright 2020 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 *      https://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 */
16
17buildscript {
18    repositories {
19        google()
20        mavenCentral()
21        gradlePluginPortal()
22    }
23
24    dependencies {
25        classpath libs.android.tools.build.gradle
26        classpath libs.android.gradlePlugin
27        classpath libs.kotlin.gradlePlugin
28
29        classpath libs.gradleMavenPublishPlugin
30
31        classpath libs.metalavaGradle
32
33        classpath libs.affectedmoduledetector
34    }
35}
36
37plugins {
38    id "com.diffplug.spotless" version "6.5.2"
39    alias(libs.plugins.jetbrains.dokka)
40}
41
42apply plugin: 'com.dropbox.affectedmoduledetector'
43apply plugin: 'com.diffplug.spotless'
44
45tasks.withType(org.jetbrains.dokka.gradle.DokkaMultiModuleTask).configureEach {
46    outputDirectory = rootProject.file('docs/api')
47    failOnWarning = true
48}
49
50affectedModuleDetector {
51    baseDir = "${project.rootDir}"
52    pathsAffectingAllModules = [
53            "gradle/libs.versions.toml",
54    ]
55    excludedModules = [
56            "sample"
57    ]
58
59    logFilename = "output.log"
60    logFolder = "${rootProject.buildDir}/affectedModuleDetector"
61
62    String baseRef = findProperty("affected_base_ref")
63    // If we have a base ref to diff against, extract the branch name and use it
64    if (baseRef != null && !baseRef.isEmpty()) {
65        // Remove the prefix from the head.
66        // TODO: need to support other types of git refs
67        specifiedBranch = baseRef.replace('refs/heads/', '')
68        compareFrom = "SpecifiedBranchCommit"
69    } else {
70        // Otherwise we use the previous commit. This is mostly used for commits to main.
71        compareFrom = "PreviousCommit"
72    }
73}
74
75allprojects {
76    repositories {
77        google()
78        mavenCentral()
79
80        def composeSnapshot = libs.versions.composesnapshot.get()
81        if (composeSnapshot.length() > 1) {
82            maven { url "https://androidx.dev/snapshots/builds/$composeSnapshot/artifacts/repository/" }
83        }
84    }
85}
86
87subprojects {
88    apply plugin: 'com.diffplug.spotless'
89
90    spotless {
91        kotlin {
92            target "**/*.kt"
93            ktlint(libs.versions.ktlint.get())
94            licenseHeaderFile rootProject.file('spotless/copyright.txt')
95        }
96
97        groovyGradle {
98            target '**/*.gradle'
99            greclipse().configFile(rootProject.file('spotless/greclipse.properties'))
100            licenseHeaderFile rootProject.file('spotless/copyright.txt'),
101                    '(buildscript|apply|import|plugins)'
102        }
103    }
104
105    // Remove all test apps after running UI tests.
106    // This is specially important in CI so that test emulators don't run out of space.
107    tasks.whenTaskAdded { task ->
108        if (task.name == 'connectedDebugAndroidTest') {
109            task.finalizedBy 'uninstallDebugAndroidTest'
110        }
111    }
112
113    configurations.configureEach {
114        resolutionStrategy.eachDependency { DependencyResolveDetails details ->
115            // Make sure that we're using the Android version of Guava
116            if (details.requested.group == 'com.google.guava'
117                    && details.requested.module.name == 'guava'
118                    && details.requested.version.contains('jre')) {
119                details.useVersion details.requested.version.replace('jre', 'android')
120            }
121        }
122    }
123
124    tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach { compile ->
125        kotlinOptions {
126            // Treat all Kotlin warnings as errors
127            allWarningsAsErrors = true
128            // Set JVM target to 1.8
129            jvmTarget = "1.8"
130            // Allow use of @OptIn
131            freeCompilerArgs += "-opt-in=kotlin.RequiresOptIn"
132            // Enable default methods in interfaces
133            freeCompilerArgs += "-Xjvm-default=all"
134        }
135    }
136
137    // Read in the signing.properties file if it is exists
138    def signingPropsFile = rootProject.file('release/signing.properties')
139    if (signingPropsFile.exists()) {
140        def localProperties = new Properties()
141        signingPropsFile.withInputStream { is -> localProperties.load(is) }
142        localProperties.each { prop ->
143            if (prop.key == "signing.secretKeyRingFile") {
144                // If this is the key ring, treat it as a relative path
145                project.ext.set(prop.key, rootProject.file(prop.value).absolutePath)
146            } else {
147                project.ext.set(prop.key, prop.value)
148            }
149        }
150    }
151
152    // Must be afterEvaluate or else com.vanniktech.maven.publish will overwrite our
153    // dokka and version configuration.
154    afterEvaluate {
155        if (tasks.findByName('dokkaHtmlPartial') == null) {
156            // If dokka isn't enabled on this module, skip
157            return
158        }
159
160        tasks.named('dokkaHtmlPartial') {
161            dokkaSourceSets.configureEach {
162                reportUndocumented.set(true)
163                skipEmptyPackages.set(true)
164                skipDeprecated.set(true)
165                jdkVersion.set(8)
166
167                // Add Android SDK packages
168                noAndroidSdkLink.set(false)
169
170                // Add samples from :sample module
171                samples.from(rootProject.file("sample/src/main/java/"))
172
173                // AndroidX + Compose docs
174                externalDocumentationLink {
175                    url.set(new URL("https://developer.android.com/reference/"))
176                    packageListUrl.set(new URL("https://developer.android.com/reference/androidx/package-list"))
177                }
178                externalDocumentationLink {
179                    url.set(new URL("https://developer.android.com/reference/kotlin/"))
180                    packageListUrl.set(new URL("https://developer.android.com/reference/kotlin/androidx/package-list"))
181                }
182
183                sourceLink {
184                    localDirectory.set(project.file("src/main/java"))
185                    // URL showing where the source code can be accessed through the web browser
186                    remoteUrl.set(new URL("https://github.com/google/accompanist/blob/main/${project.name}/src/main/java"))
187                    // Suffix which is used to append the line number to the URL. Use #L for GitHub
188                    remoteLineSuffix.set("#L")
189                }
190            }
191        }
192    }
193
194    afterEvaluate {
195        def composeSnapshot = libs.versions.composesnapshot.get()
196        if (composeSnapshot.length() > 1) {
197            // We're depending on a Jetpack Compose snapshot, update the library version name
198            // to indicate it's from a Compose snapshot
199            def versionName = project.properties.get('VERSION_NAME')
200            if (versionName.contains("SNAPSHOT")) {
201                version = versionName.replace('-SNAPSHOT', ".compose-${composeSnapshot}-SNAPSHOT")
202            }
203        }
204
205        if (!version.endsWith('SNAPSHOT')) {
206            // If we're not a SNAPSHOT library version, we fail the build if we're relying on
207            // any snapshot dependencies
208            configurations.configureEach { configuration ->
209                configuration.dependencies.configureEach { dependency ->
210                    if (dependency instanceof ProjectDependency) {
211                        // We don't care about internal project dependencies
212                        return
213                    }
214
215                    def depVersion = dependency.version
216                    if (depVersion != null && depVersion.endsWith('SNAPSHOT')) {
217                        throw new IllegalArgumentException(
218                                "Using SNAPSHOT dependency with non-SNAPSHOT library version: $dependency"
219                        )
220                    }
221                }
222            }
223        }
224    }
225}
226