Skip to content

Commit 15c4ae6

Browse files
committed
build: Introduce API Gradle Convention Plugin
Likely only one consumer: `:api`, added to standardize .kts files The API has separate requirements, but these are noise in the main gradle.kts file. Issue 20775 Assisted-by: Claude Opus 4.7 - full refactor
1 parent e18d235 commit 15c4ae6

4 files changed

Lines changed: 97 additions & 31 deletions

File tree

api/build.gradle.kts

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,15 @@ import com.android.build.api.dsl.LibraryExtension
22
import com.android.build.gradle.internal.tasks.factory.dependsOn
33

44
plugins {
5-
// Use `id` to avoid classpath conflicts. Versions are pinned by buildSrc/.
6-
id("com.android.library")
5+
id("ankidroid.android.api")
76
id("maven-publish")
87
}
98

109
group = "com.ichi2.anki"
1110
version = "2.0.0"
1211

13-
kotlin {
14-
explicitApi()
15-
compilerOptions {
16-
// enable explicit api mode for additional checks related to the public api
17-
// see https://kotlinlang.org/docs/whatsnew14.html#explicit-api-mode-for-library-authors
18-
freeCompilerArgs.add("-Xexplicit-api=strict")
19-
}
20-
}
21-
2212
configure<LibraryExtension> {
2313
namespace = "com.ichi2.anki.api"
24-
compileSdk =
25-
libs.versions.compileSdk
26-
.get()
27-
.toInt()
2814

2915
buildFeatures {
3016
buildConfig = true
@@ -56,11 +42,6 @@ configure<LibraryExtension> {
5642
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
5743
}
5844
}
59-
compileOptions {
60-
// API remains on VERSION_11 for compatibility
61-
sourceCompatibility = JavaVersion.VERSION_11
62-
targetCompatibility = JavaVersion.VERSION_11
63-
}
6445

6546
publishing {
6647
singleVariant("release") {
@@ -70,8 +51,6 @@ configure<LibraryExtension> {
7051
}
7152
}
7253

73-
apply(from = "../lint.gradle")
74-
7554
dependencies {
7655
implementation(libs.androidx.annotation)
7756
implementation(libs.kotlin.stdlib)
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright (c) 2026 David Allison <davidallisongithub@gmail.com>
3+
*
4+
* This program is free software; you can redistribute it and/or modify it under
5+
* the terms of the GNU General Public License as published by the Free Software
6+
* Foundation; either version 3 of the License, or (at your option) any later
7+
* version.
8+
*
9+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
10+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
11+
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
12+
*
13+
* You should have received a copy of the GNU General Public License along with
14+
* this program. If not, see <http://www.gnu.org/licenses/>.
15+
*/
16+
17+
// Convention plugin: Android library published as a public API artifact.
18+
//
19+
// Distinct from ankidroid.android-library:
20+
// * Java source/target compat is 11 (not 17) for consumer compatibility.
21+
// * Kotlin explicit-API strict mode is enabled (library-author quality check).
22+
// * minSdk is not set.
23+
//
24+
// Publishing (maven-publish, singleVariant setup, POM metadata) is left to
25+
// the consuming module — it's intrinsically per-module configuration.
26+
27+
import com.android.build.api.dsl.LibraryExtension
28+
import com.ichi2.anki.gradle.libsVersionFor
29+
import org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension
30+
31+
plugins {
32+
id("com.android.library")
33+
}
34+
35+
extensions.configure<LibraryExtension> {
36+
compileSdk = libsVersionFor("compileSdk").toInt()
37+
38+
compileOptions {
39+
// API remains on VERSION_11 for consumer compatibility.
40+
sourceCompatibility = JavaVersion.VERSION_11
41+
targetCompatibility = JavaVersion.VERSION_11
42+
}
43+
}
44+
45+
extensions.configure<KotlinAndroidProjectExtension> {
46+
explicitApi()
47+
compilerOptions {
48+
// Stricter checks on public API shape for library authors.
49+
// See https://kotlinlang.org/docs/whatsnew14.html#explicit-api-mode-for-library-authors
50+
freeCompilerArgs.add("-Xexplicit-api=strict")
51+
}
52+
}
53+
54+
// Shared project-wide lint configuration.
55+
apply(from = "${rootDir}/lint.gradle")

buildSrc/src/main/kotlin/ankidroid.android.library.gradle.kts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,17 @@
2222
*/
2323

2424
import com.android.build.api.dsl.LibraryExtension
25-
import org.gradle.api.artifacts.VersionCatalogsExtension
25+
import com.ichi2.anki.gradle.libsVersionFor
2626

2727
plugins {
2828
id("com.android.library")
2929
}
3030

31-
// Type-safe `libs` accessors aren't available in precompiled script plugins,
32-
// so read versions from the catalog explicitly.
33-
val libs = extensions.getByType<VersionCatalogsExtension>().named("libs")
34-
fun versionInt(alias: String): Int =
35-
libs.findVersion(alias).get().requiredVersion.toInt()
36-
3731
extensions.configure<LibraryExtension> {
38-
compileSdk = versionInt("compileSdk")
32+
compileSdk = libsVersionFor("compileSdk").toInt()
3933

4034
defaultConfig {
41-
minSdk = versionInt("minSdk")
35+
minSdk = libsVersionFor("minSdk").toInt()
4236
}
4337

4438
compileOptions {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (c) 2026 David Allison <davidallisongithub@gmail.com>
3+
*
4+
* This program is free software; you can redistribute it and/or modify it under
5+
* the terms of the GNU General Public License as published by the Free Software
6+
* Foundation; either version 3 of the License, or (at your option) any later
7+
* version.
8+
*
9+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
10+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
11+
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
12+
*
13+
* You should have received a copy of the GNU General Public License along with
14+
* this program. If not, see <http://www.gnu.org/licenses/>.
15+
*/
16+
17+
package com.ichi2.anki.gradle
18+
19+
import org.gradle.api.Project
20+
import org.gradle.api.artifacts.VersionCatalog
21+
import org.gradle.api.artifacts.VersionCatalogsExtension
22+
import org.gradle.kotlin.dsl.getByType
23+
24+
// Type-safe `libs` accessors aren't available in precompiled script plugins,
25+
// so read versions from the `libs` catalog explicitly.
26+
27+
@Volatile
28+
private var cachedLibs: VersionCatalog? = null
29+
30+
// A Project reference is required, so this can't be `by lazy { }`
31+
private fun Project.libs(): VersionCatalog =
32+
cachedLibs ?: extensions
33+
.getByType<VersionCatalogsExtension>()
34+
.named("libs")
35+
.also { cachedLibs = it }
36+
37+
fun Project.libsVersionFor(alias: String): String =
38+
libs().findVersion(alias).get().requiredVersion

0 commit comments

Comments
 (0)