From 3eefa801d673968a874f7c697359144563e2ed35 Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Wed, 4 Feb 2026 16:01:09 -0600 Subject: [PATCH] refactor(build): Introduce AndroidLibraryFlavors convention plugin (#4449) --- build-logic/convention/build.gradle.kts | 10 ++++-- .../kotlin/AndroidLibraryConventionPlugin.kt | 8 +++-- .../AndroidLibraryFlavorsConventionPlugin.kt | 32 +++++++++++++++++++ core/analytics/build.gradle.kts | 19 ++--------- core/api/build.gradle.kts | 6 ++-- core/data/build.gradle.kts | 1 + core/model/build.gradle.kts | 6 ++-- core/network/build.gradle.kts | 18 +---------- core/prefs/build.gradle.kts | 18 +---------- feature/intro/build.gradle.kts | 18 +---------- feature/map/build.gradle.kts | 1 + feature/node/build.gradle.kts | 1 + gradle/libs.versions.toml | 1 + 13 files changed, 60 insertions(+), 79 deletions(-) create mode 100644 build-logic/convention/src/main/kotlin/AndroidLibraryFlavorsConventionPlugin.kt diff --git a/build-logic/convention/build.gradle.kts b/build-logic/convention/build.gradle.kts index 3be1b7057..1208de17f 100644 --- a/build-logic/convention/build.gradle.kts +++ b/build-logic/convention/build.gradle.kts @@ -112,7 +112,7 @@ gradlePlugin { id = "meshtastic.android.application" implementationClass = "AndroidApplicationConventionPlugin" } - register("androidFlavors") { + register("androidApplicationFlavors") { id = "meshtastic.android.application.flavors" implementationClass = "AndroidApplicationFlavorsConventionPlugin" } @@ -120,6 +120,10 @@ gradlePlugin { id = "meshtastic.android.library" implementationClass = "AndroidLibraryConventionPlugin" } + register("androidLibraryFlavors") { + id = "meshtastic.android.library.flavors" + implementationClass = "AndroidLibraryFlavorsConventionPlugin" + } register("androidLint") { id = "meshtastic.android.lint" implementationClass = "AndroidLintConventionPlugin" @@ -167,12 +171,12 @@ gradlePlugin { id = "meshtastic.kmp.library.compose" implementationClass = "KmpLibraryComposeConventionPlugin" } - + register("dokka") { id = "meshtastic.dokka" implementationClass = "DokkaConventionPlugin" } - + register("kover") { id = "meshtastic.kover" implementationClass = "KoverConventionPlugin" diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt index 6d4610354..3a0dfd7ca 100644 --- a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt @@ -21,7 +21,6 @@ import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.configure -import org.meshtastic.buildlogic.configureFlavors import org.meshtastic.buildlogic.configureKotlinAndroid import org.meshtastic.buildlogic.configureTestOptions import org.meshtastic.buildlogic.disableUnnecessaryAndroidTests @@ -41,7 +40,12 @@ class AndroidLibraryConventionPlugin : Plugin { configureKotlinAndroid(this) defaultConfig.testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testOptions.animationsDisabled = true - configureFlavors(this) + + defaultConfig { + // When flavorless modules depend on flavored modules (like :core:data), + // they need a strategy to pick a variant. We default to 'google'. + missingDimensionStrategy("marketplace", "google") + } buildTypes { getByName("debug") { diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryFlavorsConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryFlavorsConventionPlugin.kt new file mode 100644 index 000000000..c01b1e61c --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryFlavorsConventionPlugin.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Meshtastic LLC + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import com.android.build.api.dsl.LibraryExtension +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure +import org.meshtastic.buildlogic.configureFlavors + +class AndroidLibraryFlavorsConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + extensions.configure { + configureFlavors(this) + } + } + } +} diff --git a/core/analytics/build.gradle.kts b/core/analytics/build.gradle.kts index 7d23198df..bb860fcda 100644 --- a/core/analytics/build.gradle.kts +++ b/core/analytics/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 Meshtastic LLC + * Copyright (c) 2025-2026 Meshtastic LLC * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,24 +16,9 @@ */ import com.android.build.api.dsl.LibraryExtension -/* - * Copyright (c) 2025 Meshtastic LLC - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ plugins { alias(libs.plugins.meshtastic.android.library) + alias(libs.plugins.meshtastic.android.library.flavors) alias(libs.plugins.meshtastic.android.library.compose) alias(libs.plugins.meshtastic.hilt) alias(libs.plugins.secrets) diff --git a/core/api/build.gradle.kts b/core/api/build.gradle.kts index 8b22bf473..1378e7500 100644 --- a/core/api/build.gradle.kts +++ b/core/api/build.gradle.kts @@ -30,15 +30,15 @@ configure { minSdk = 21 } - publishing { singleVariant("googleRelease") { withSourcesJar() } } + publishing { singleVariant("release") { withSourcesJar() } } } // Map the Android component to a Maven publication afterEvaluate { publishing { publications { - create("googleRelease") { - from(components["googleRelease"]) + create("release") { + from(components["release"]) artifactId = "core-api" } } diff --git a/core/data/build.gradle.kts b/core/data/build.gradle.kts index b2397489e..fd66699b7 100644 --- a/core/data/build.gradle.kts +++ b/core/data/build.gradle.kts @@ -18,6 +18,7 @@ import com.android.build.api.dsl.LibraryExtension plugins { alias(libs.plugins.meshtastic.android.library) + alias(libs.plugins.meshtastic.android.library.flavors) alias(libs.plugins.meshtastic.hilt) alias(libs.plugins.meshtastic.kotlinx.serialization) } diff --git a/core/model/build.gradle.kts b/core/model/build.gradle.kts index 053f8af54..1a428d823 100644 --- a/core/model/build.gradle.kts +++ b/core/model/build.gradle.kts @@ -39,14 +39,14 @@ configure { testOptions { unitTests { isIncludeAndroidResources = true } } - publishing { singleVariant("googleRelease") { withSourcesJar() } } + publishing { singleVariant("release") { withSourcesJar() } } } afterEvaluate { publishing { publications { - create("googleRelease") { - from(components["googleRelease"]) + create("release") { + from(components["release"]) artifactId = "core-model" } } diff --git a/core/network/build.gradle.kts b/core/network/build.gradle.kts index 4687c5aee..c7bf1e86d 100644 --- a/core/network/build.gradle.kts +++ b/core/network/build.gradle.kts @@ -16,25 +16,9 @@ */ import com.android.build.api.dsl.LibraryExtension -/* - * Copyright (c) 2025 Meshtastic LLC - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - plugins { alias(libs.plugins.meshtastic.android.library) + alias(libs.plugins.meshtastic.android.library.flavors) alias(libs.plugins.meshtastic.hilt) alias(libs.plugins.kotlin.serialization) } diff --git a/core/prefs/build.gradle.kts b/core/prefs/build.gradle.kts index e34c0daf2..84e01f587 100644 --- a/core/prefs/build.gradle.kts +++ b/core/prefs/build.gradle.kts @@ -16,25 +16,9 @@ */ import com.android.build.api.dsl.LibraryExtension -/* - * Copyright (c) 2025 Meshtastic LLC - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - plugins { alias(libs.plugins.meshtastic.android.library) + alias(libs.plugins.meshtastic.android.library.flavors) alias(libs.plugins.meshtastic.hilt) } diff --git a/feature/intro/build.gradle.kts b/feature/intro/build.gradle.kts index 627bcaa7d..5eae220b4 100644 --- a/feature/intro/build.gradle.kts +++ b/feature/intro/build.gradle.kts @@ -16,25 +16,9 @@ */ import com.android.build.api.dsl.LibraryExtension -/* - * Copyright (c) 2025 Meshtastic LLC - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - plugins { alias(libs.plugins.meshtastic.android.library) + alias(libs.plugins.meshtastic.android.library.flavors) alias(libs.plugins.meshtastic.android.library.compose) alias(libs.plugins.meshtastic.kotlinx.serialization) } diff --git a/feature/map/build.gradle.kts b/feature/map/build.gradle.kts index 8380bc81c..03be3de20 100644 --- a/feature/map/build.gradle.kts +++ b/feature/map/build.gradle.kts @@ -18,6 +18,7 @@ import com.android.build.api.dsl.LibraryExtension plugins { alias(libs.plugins.meshtastic.android.library) + alias(libs.plugins.meshtastic.android.library.flavors) alias(libs.plugins.meshtastic.android.library.compose) alias(libs.plugins.meshtastic.hilt) } diff --git a/feature/node/build.gradle.kts b/feature/node/build.gradle.kts index fae12946a..4c3e6e849 100644 --- a/feature/node/build.gradle.kts +++ b/feature/node/build.gradle.kts @@ -18,6 +18,7 @@ import com.android.build.api.dsl.LibraryExtension plugins { alias(libs.plugins.meshtastic.android.library) + alias(libs.plugins.meshtastic.android.library.flavors) alias(libs.plugins.meshtastic.android.library.compose) alias(libs.plugins.meshtastic.hilt) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e309a7f61..1ae357716 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -246,6 +246,7 @@ meshtastic-android-application-compose = { id = "meshtastic.android.application. meshtastic-android-application-flavors = { id = "meshtastic.android.application.flavors" } meshtastic-android-library = { id = "meshtastic.android.library" } meshtastic-android-library-compose = { id = "meshtastic.android.library.compose" } +meshtastic-android-library-flavors = { id = "meshtastic.android.library.flavors" } meshtastic-android-lint = { id = "meshtastic.android.lint" } meshtastic-android-room = { id = "meshtastic.android.room" } meshtastic-android-test = { id = "meshtastic.android.test" }