refactor: Migrate to Android Gradle Plugin 9.0 (#4072)

Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
James Rich 2025-12-28 07:47:12 -06:00 committed by GitHub
parent 2070c267c5
commit 9fd92691a9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
44 changed files with 646 additions and 168 deletions

View file

@ -255,7 +255,7 @@ dependencies {
dokka {
moduleName.set("Meshtastic App")
dokkaSourceSets.main {
dokkaSourceSets.register("main") {
sourceLink {
enableJdkDocumentationLink.set(true)
enableKotlinStdLibDocumentationLink.set(true)

View file

@ -40,10 +40,14 @@ kotlin {
}
dependencies {
// This allows the use of the 'libs' type-safe accessor in the Kotlin source of the plugins
implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
compileOnly(libs.android.gradleApiPlugin)
compileOnly(libs.serialization.gradlePlugin)
compileOnly(libs.android.tools.common)
compileOnly(libs.compose.gradlePlugin)
compileOnly(libs.compose.multiplatform.gradlePlugin)
compileOnly(libs.datadog.gradlePlugin)
compileOnly(libs.detekt.gradlePlugin)
compileOnly(libs.firebase.crashlytics.gradlePlugin)
@ -103,62 +107,67 @@ detekt {
gradlePlugin {
plugins {
register("androidApplication") {
id = libs.plugins.meshtastic.android.application.asProvider().get().pluginId
id = "meshtastic.android.application"
implementationClass = "AndroidApplicationConventionPlugin"
}
register("androidFlavors") {
id = libs.plugins.meshtastic.android.application.flavors.get().pluginId
id = "meshtastic.android.application.flavors"
implementationClass = "AndroidApplicationFlavorsConventionPlugin"
}
register("androidLibrary") {
id = libs.plugins.meshtastic.android.library.asProvider().get().pluginId
id = "meshtastic.android.library"
implementationClass = "AndroidLibraryConventionPlugin"
}
register("androidLint") {
id = libs.plugins.meshtastic.android.lint.get().pluginId
id = "meshtastic.android.lint"
implementationClass = "AndroidLintConventionPlugin"
}
register("androidLibraryCompose") {
id = libs.plugins.meshtastic.android.library.compose.get().pluginId
id = "meshtastic.android.library.compose"
implementationClass = "AndroidLibraryComposeConventionPlugin"
}
register("androidApplicationCompose") {
id = libs.plugins.meshtastic.android.application.compose.get().pluginId
id = "meshtastic.android.application.compose"
implementationClass = "AndroidApplicationComposeConventionPlugin"
}
register("kotlinXSerialization") {
id = libs.plugins.meshtastic.kotlinx.serialization.get().pluginId
id = "meshtastic.kotlinx.serialization"
implementationClass = "KotlinXSerializationConventionPlugin"
}
register("meshtasticAnalytics") {
id = libs.plugins.meshtastic.analytics.get().pluginId
id = "meshtastic.analytics"
implementationClass = "AnalyticsConventionPlugin"
}
register("meshtasticHilt") {
id = libs.plugins.meshtastic.hilt.get().pluginId
id = "meshtastic.hilt"
implementationClass = "HiltConventionPlugin"
}
register("meshtasticDetekt") {
id = libs.plugins.meshtastic.detekt.get().pluginId
id = "meshtastic.detekt"
implementationClass = "DetektConventionPlugin"
}
register("androidRoom") {
id = libs.plugins.meshtastic.android.room.get().pluginId
id = "meshtastic.android.room"
implementationClass = "AndroidRoomConventionPlugin"
}
register("meshtasticSpotless") {
id = libs.plugins.meshtastic.spotless.get().pluginId
id = "meshtastic.spotless"
implementationClass = "SpotlessConventionPlugin"
}
register("kmpLibrary") {
id = libs.plugins.meshtastic.kmp.library.get().pluginId
id = "meshtastic.kmp.library"
implementationClass = "KmpLibraryConventionPlugin"
}
register("kmpLibraryCompose") {
id = "meshtastic.kmp.library.compose"
implementationClass = "KmpLibraryComposeConventionPlugin"
}
register("root") {
id = libs.plugins.meshtastic.root.get().pluginId
id = "meshtastic.root"
implementationClass = "RootConventionPlugin"
}

View file

@ -24,6 +24,8 @@ 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.libs
import org.meshtastic.buildlogic.plugin
class AnalyticsConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
@ -33,9 +35,9 @@ class AnalyticsConventionPlugin : Plugin<Project> {
productFlavors {
all {
if (name == "google") {
apply(plugin = "com.google.gms.google-services")
apply(plugin = "com.google.firebase.crashlytics")
apply(plugin = "com.datadoghq.dd-sdk-android-gradle-plugin")
apply(plugin = libs.plugin("google-services").get().pluginId)
apply(plugin = libs.plugin("firebase-crashlytics").get().pluginId)
apply(plugin = libs.plugin("datadog").get().pluginId)
}
}
}
@ -58,7 +60,7 @@ class AnalyticsConventionPlugin : Plugin<Project> {
}
// Disable Analytics tasks for non-google flavors
val analyticsKeywords = listOf("crashlytics", "google", "datadog","buildId")
val analyticsKeywords = listOf("crashlytics", "google", "datadog", "buildId")
tasks.configureEach {
val taskName = name.lowercase()
val isAnalyticsTask = analyticsKeywords.any { taskName.contains(it, ignoreCase = true) }

View file

@ -15,22 +15,22 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import com.android.build.api.dsl.ApplicationExtension
import com.android.build.api.dsl.CommonExtension
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.configureAndroidCompose
import org.meshtastic.buildlogic.libs
import org.meshtastic.buildlogic.plugin
class AndroidApplicationComposeConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
apply(plugin = "com.android.application")
apply(plugin = "org.jetbrains.kotlin.plugin.compose")
extensions.configure<ApplicationExtension> {
apply(plugin = libs.plugin("compose-compiler").get().pluginId)
extensions.configure<CommonExtension> {
configureAndroidCompose(this)
}
}
}
}

View file

@ -27,7 +27,6 @@ class AndroidApplicationConventionPlugin : Plugin<Project> {
with(target) {
apply(plugin = "com.android.application")
apply(plugin = "org.jetbrains.kotlin.android")
apply(plugin = "meshtastic.android.lint")
apply(plugin = "meshtastic.detekt")
apply(plugin = "meshtastic.spotless")
@ -35,15 +34,14 @@ class AndroidApplicationConventionPlugin : Plugin<Project> {
extensions.configure<ApplicationExtension> {
configureKotlinAndroid(this)
defaultConfig.targetSdk = 36
testOptions.animationsDisabled = true
defaultConfig {
targetSdk = 36
testInstrumentationRunner = "com.geeksville.mesh.TestRunner"
vectorDrawables.useSupportLibrary = true
}
testOptions.animationsDisabled = true
buildTypes {
getByName("release") {
isMinifyEnabled = true

View file

@ -15,22 +15,22 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import com.android.build.api.dsl.LibraryExtension
import com.android.build.api.dsl.CommonExtension
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.configureAndroidCompose
import org.meshtastic.buildlogic.libs
import org.meshtastic.buildlogic.plugin
class AndroidLibraryComposeConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
apply(plugin = "com.android.library")
apply(plugin = "org.jetbrains.kotlin.plugin.compose")
extensions.configure<LibraryExtension> {
apply(plugin = libs.plugin("compose-compiler").get().pluginId)
extensions.configure<CommonExtension> {
configureAndroidCompose(this)
}
}
}
}

View file

@ -29,7 +29,6 @@ class AndroidLibraryConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
apply(plugin = "com.android.library")
apply(plugin = "org.jetbrains.kotlin.android")
apply(plugin = "meshtastic.android.lint")
apply(plugin = "meshtastic.detekt")
apply(plugin = "meshtastic.spotless")

View file

@ -16,12 +16,14 @@
*/
import com.android.build.api.dsl.ApplicationExtension
import com.android.build.api.dsl.KotlinMultiplatformAndroidLibraryTarget
import com.android.build.api.dsl.LibraryExtension
import com.android.build.api.dsl.Lint
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.findByType
class AndroidLintConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
@ -33,6 +35,13 @@ class AndroidLintConventionPlugin : Plugin<Project> {
pluginManager.hasPlugin("com.android.library") ->
configure<LibraryExtension> { lint { configure(project) } }
pluginManager.hasPlugin("com.android.kotlin.multiplatform.library") -> {
extensions.findByType<KotlinMultiplatformAndroidLibraryTarget>()?.apply {
@Suppress("UnstableApiUsage")
lint { configure(project) }
}
}
else -> {
apply(plugin = "com.android.lint")
configure<Lint> { configure(project) }

View file

@ -22,6 +22,8 @@ import org.gradle.api.Project
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.meshtastic.buildlogic.library
import org.meshtastic.buildlogic.libs
class AndroidRoomConventionPlugin : Plugin<Project> {
@ -42,10 +44,28 @@ class AndroidRoomConventionPlugin : Plugin<Project> {
schemaDirectory("$projectDir/schemas")
}
dependencies {
"implementation"(libs.findLibrary("androidx.room.runtime").get())
"ksp"(libs.findLibrary("androidx.room.compiler").get())
"androidTestImplementation"(libs.findLibrary("androidx-room-testing").get())
val roomRuntime = libs.library("androidx.room.runtime")
val roomCompiler = libs.library("androidx.room.compiler")
val roomTesting = libs.library("androidx-room-testing")
pluginManager.withPlugin("org.jetbrains.kotlin.multiplatform") {
extensions.configure<KotlinMultiplatformExtension> {
sourceSets.getByName("commonMain").dependencies {
implementation(roomRuntime)
}
}
dependencies {
"kspCommonMainMetadata"(roomCompiler)
"kspAndroid"(roomCompiler)
}
}
pluginManager.withPlugin("org.jetbrains.kotlin.android") {
dependencies {
"implementation"(roomRuntime)
"ksp"(roomCompiler)
"androidTestImplementation"(roomTesting)
}
}
}
}

View file

@ -18,19 +18,18 @@
import io.gitlab.arturbosch.detekt.extensions.DetektExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.getByType
import org.gradle.kotlin.dsl.configure
import org.meshtastic.buildlogic.configureDetekt
import org.meshtastic.buildlogic.configureKotlinJvm
import org.meshtastic.buildlogic.libs
import org.meshtastic.buildlogic.plugin
class DetektConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
configureKotlinJvm()
apply(plugin = libs.findPlugin("detekt").get().get().pluginId)
val extension = extensions.getByType<DetektExtension>()
configureDetekt(extension)
pluginManager.apply(libs.plugin("detekt").get().pluginId)
extensions.configure<DetektExtension> {
configureDetekt(this)
}
}
}
}

View file

@ -19,6 +19,7 @@ import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.dependencies
import org.meshtastic.buildlogic.library
import org.meshtastic.buildlogic.libs
class HiltConventionPlugin : Plugin<Project> {
@ -28,16 +29,16 @@ class HiltConventionPlugin : Plugin<Project> {
dependencies {
// fixme: remove when hilt supports kotlin 2.3.x
"ksp"(libs.findLibrary("kotlin-metadata-jvm").get())
"ksp"(libs.library("kotlin-metadata-jvm"))
"ksp"(libs.findLibrary("hilt.compiler").get())
"implementation"(libs.findLibrary("hilt-android").get())
"ksp"(libs.library("hilt.compiler"))
"implementation"(libs.library("hilt-android"))
}
// Add support for Jvm Module, base on org.jetbrains.kotlin.jvm
pluginManager.withPlugin("org.jetbrains.kotlin.jvm") {
dependencies {
"implementation"(libs.findLibrary("hilt.core").get())
"implementation"(libs.library("hilt-core"))
}
}

View file

@ -0,0 +1,43 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.configure
import org.jetbrains.compose.ComposeExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.meshtastic.buildlogic.libs
import org.meshtastic.buildlogic.plugin
class KmpLibraryComposeConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
apply(plugin = libs.plugin("compose-multiplatform").get().pluginId)
apply(plugin = libs.plugin("compose-compiler").get().pluginId)
val compose = extensions.getByType(ComposeExtension::class.java)
extensions.configure<KotlinMultiplatformExtension> {
sourceSets.getByName("commonMain").dependencies {
implementation(compose.dependencies.runtime)
// API because consuming modules will usually need the resource types
api(compose.dependencies.components.resources)
}
}
}
}
}

View file

@ -15,29 +15,23 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import com.android.build.api.dsl.KotlinMultiplatformAndroidLibraryTarget
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.plugins.ExtensionAware
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.configure
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.meshtastic.buildlogic.configProperties
import org.meshtastic.buildlogic.configureKotlinMultiplatform
import org.meshtastic.buildlogic.libs
import org.meshtastic.buildlogic.plugin
class KmpLibraryConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
apply(plugin = "org.jetbrains.kotlin.multiplatform")
apply(plugin = "com.android.kotlin.multiplatform.library")
apply(plugin = libs.plugin("kotlin-multiplatform").get().pluginId)
apply(plugin = libs.plugin("android-kotlin-multiplatform-library").get().pluginId)
apply(plugin = "meshtastic.android.lint")
apply(plugin = "meshtastic.detekt")
apply(plugin = "meshtastic.spotless")
extensions.configure<KotlinMultiplatformExtension> {
(this as ExtensionAware).extensions.configure<KotlinMultiplatformAndroidLibraryTarget>("android") {
compileSdk = this@with.configProperties.getProperty("COMPILE_SDK").toInt()
minSdk = this@with.configProperties.getProperty("MIN_SDK").toInt()
}
}
configureKotlinMultiplatform()
}
}
}

View file

@ -18,7 +18,10 @@
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.meshtastic.buildlogic.library
import org.meshtastic.buildlogic.libs
class KotlinXSerializationConventionPlugin : Plugin<Project> {
@ -26,8 +29,26 @@ class KotlinXSerializationConventionPlugin : Plugin<Project> {
with(target) {
apply(plugin = "org.jetbrains.kotlin.plugin.serialization")
dependencies {
"implementation"(libs.findLibrary("kotlinx-serialization-core").get())
val serializationLib = libs.library("kotlinx-serialization-core")
pluginManager.withPlugin("org.jetbrains.kotlin.multiplatform") {
extensions.configure<KotlinMultiplatformExtension> {
sourceSets.getByName("commonMain").dependencies {
implementation(serializationLib)
}
}
}
pluginManager.withPlugin("org.jetbrains.kotlin.android") {
dependencies {
"implementation"(serializationLib)
}
}
pluginManager.withPlugin("org.jetbrains.kotlin.jvm") {
dependencies {
"implementation"(serializationLib)
}
}
}
}

View file

@ -18,19 +18,18 @@
import com.diffplug.gradle.spotless.SpotlessExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.getByType
import org.meshtastic.buildlogic.configureKotlinJvm
import org.gradle.kotlin.dsl.configure
import org.meshtastic.buildlogic.configureSpotless
import org.meshtastic.buildlogic.libs
import org.meshtastic.buildlogic.plugin
class SpotlessConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
configureKotlinJvm()
apply(plugin = libs.findPlugin("spotless").get().get().pluginId)
val extension = extensions.getByType<SpotlessExtension>()
configureSpotless(extension)
pluginManager.apply(libs.plugin("spotless").get().pluginId)
extensions.configure<SpotlessExtension> {
configureSpotless(this)
}
}
}
}

View file

@ -17,7 +17,9 @@
package org.meshtastic.buildlogic
import com.android.build.api.dsl.ApplicationExtension
import com.android.build.api.dsl.CommonExtension
import com.android.build.api.dsl.LibraryExtension
import org.gradle.api.Project
import org.gradle.api.provider.Provider
import org.gradle.kotlin.dsl.configure
@ -28,22 +30,19 @@ import org.jetbrains.kotlin.compose.compiler.gradle.ComposeCompilerGradlePluginE
* Configure Compose-specific options
*/
internal fun Project.configureAndroidCompose(
commonExtension: CommonExtension<*, *, *, *, *, *>,
commonExtension: CommonExtension,
) {
commonExtension.apply {
buildFeatures {
compose = true
}
(commonExtension as? ApplicationExtension)?.buildFeatures?.compose = true
(commonExtension as? LibraryExtension)?.buildFeatures?.compose = true
dependencies {
val bom = libs.findLibrary("androidx-compose-bom").get()
"implementation"(platform(bom))
"androidTestImplementation"(platform(bom))
"implementation"(libs.findLibrary("androidx-compose-ui-tooling").get())
"implementation"(libs.findLibrary("androidx-compose-runtime").get())
"runtimeOnly"(libs.findLibrary("androidx-compose-runtime-tracing").get())
"debugImplementation"(libs.findLibrary("androidx-compose-ui-tooling").get())
}
dependencies {
val bom = libs.library("androidx-compose-bom")
"implementation"(platform(bom))
"androidTestImplementation"(platform(bom))
"implementation"(libs.library("androidx-compose-ui-tooling"))
"implementation"(libs.library("androidx-compose-runtime"))
"runtimeOnly"(libs.library("androidx-compose-runtime-tracing"))
"debugImplementation"(libs.library("androidx-compose-ui-tooling"))
}
extensions.configure<ComposeCompilerGradlePluginExtension> {

View file

@ -22,21 +22,24 @@ import io.gitlab.arturbosch.detekt.extensions.DetektExtension
import org.gradle.api.Project
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.named
import java.io.File
internal fun Project.configureDetekt(extension: DetektExtension) = extension.apply {
extension.apply {
toolVersion = libs.findVersion("detekt").get().toString()
config.setFrom("$rootDir/config/detekt/detekt.yml")
buildUponDefaultConfig = true
allRules = false
source.setFrom(
files(
"src/main/java",
"src/main/kotlin",
),
)
}
toolVersion = libs.version("detekt")
config.setFrom("$rootDir/config/detekt/detekt.yml")
buildUponDefaultConfig = true
allRules = false
// Default sources
source.setFrom(
files(
"src/main/java",
"src/main/kotlin",
"src/commonMain/kotlin",
"src/androidMain/kotlin",
"src/jvmMain/kotlin",
),
)
tasks.named<Detekt>("detekt") {
reports {
xml.required.set(true)
@ -45,14 +48,15 @@ internal fun Project.configureDetekt(extension: DetektExtension) = extension.app
sarif.required.set(true)
md.required.set(true)
}
reports.xml.outputLocation.set(File("$rootDir/build/reports/detekt/detekt.xml"))
reports.html.outputLocation.set(File("$rootDir/build/reports/detekt/detekt.html"))
reports.txt.outputLocation.set(File("$rootDir/build/reports/detekt/detekt.txt"))
reports.sarif.outputLocation.set(File("$rootDir/build/reports/detekt/detekt.sarif"))
reports.md.outputLocation.set(File("$rootDir/build/reports/detekt/detekt.md"))
// Use project-specific build directory for reports to avoid conflicts
reports.xml.outputLocation.set(layout.buildDirectory.file("reports/detekt/detekt.xml"))
reports.html.outputLocation.set(layout.buildDirectory.file("reports/detekt/detekt.html"))
reports.txt.outputLocation.set(layout.buildDirectory.file("reports/detekt/detekt.txt"))
reports.sarif.outputLocation.set(layout.buildDirectory.file("reports/detekt/detekt.sarif"))
reports.md.outputLocation.set(layout.buildDirectory.file("reports/detekt/detekt.md"))
}
dependencies {
"detektPlugins"(libs.findLibrary("detekt-formatting").get())
"detektPlugins"(libs.findLibrary("detekt-compose").get())
"detektPlugins"(libs.library("detekt-formatting"))
"detektPlugins"(libs.library("detekt-compose"))
}
}

View file

@ -17,43 +17,42 @@
package org.meshtastic.buildlogic
import com.android.build.api.dsl.ApplicationExtension
import com.android.build.api.dsl.CommonExtension
import com.android.build.api.dsl.KotlinMultiplatformAndroidLibraryTarget
import org.gradle.api.JavaVersion
import org.gradle.api.Project
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.jvm.toolchain.JavaLanguageVersion
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.findByType
import org.gradle.kotlin.dsl.withType
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinBaseExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.io.FileInputStream
import java.util.Properties
/**
* Configure base Kotlin with Android options
*/
internal fun Project.configureKotlinAndroid(
commonExtension: CommonExtension<*, *, *, *, *, *>,
commonExtension: CommonExtension,
) {
val configPropertiesFile = rootProject.file("config.properties")
val configProperties = Properties()
if (configPropertiesFile.exists()) {
FileInputStream(configPropertiesFile).use { configProperties.load(it) }
}
commonExtension.apply {
compileSdk = configProperties.get("COMPILE_SDK").toString().toInt()
compileSdk = configProperties.getProperty("COMPILE_SDK").toInt()
defaultConfig {
minSdk = configProperties.get("MIN_SDK").toString().toInt()
defaultConfig.apply {
minSdk = configProperties.getProperty("MIN_SDK").toInt()
if (commonExtension is ApplicationExtension) {
commonExtension.defaultConfig.targetSdk = configProperties.getProperty("TARGET_SDK").toInt()
}
}
compileOptions {
compileOptions.apply {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
isCoreLibraryDesugaringEnabled = true
@ -63,10 +62,33 @@ internal fun Project.configureKotlinAndroid(
configureKotlin<KotlinAndroidProjectExtension>()
dependencies {
"coreLibraryDesugaring"(libs.findLibrary("android.desugarJdkLibs").get())
"coreLibraryDesugaring"(libs.library("android.desugarJdkLibs"))
}
}
/**
* Configure Kotlin Multiplatform options
*/
internal fun Project.configureKotlinMultiplatform() {
extensions.configure<KotlinMultiplatformExtension> {
// Configure the Android target if the plugin is applied
pluginManager.withPlugin("com.android.kotlin.multiplatform.library") {
extensions.findByType<KotlinMultiplatformAndroidLibraryTarget>()?.apply {
compileSdk = configProperties.getProperty("COMPILE_SDK").toInt()
minSdk = configProperties.getProperty("MIN_SDK").toInt()
// Set the namespace automatically if not already set
if (namespace == null) {
val pkg = this@configureKotlinMultiplatform.path.removePrefix(":").replace(":", ".")
namespace = "org.meshtastic.$pkg"
}
}
}
}
configureKotlin<KotlinMultiplatformExtension>()
}
/**
* Configure base Kotlin options for JVM (non-Android)
*/

View file

@ -20,6 +20,7 @@ package org.meshtastic.buildlogic
import com.android.build.api.dsl.ApplicationExtension
import com.android.build.api.dsl.ApplicationProductFlavor
import com.android.build.api.dsl.CommonExtension
import com.android.build.api.dsl.LibraryExtension
import com.android.build.api.dsl.ProductFlavor
@Suppress("EnumEntryName")
@ -29,15 +30,34 @@ enum class FlavorDimension {
@Suppress("EnumEntryName")
enum class MeshtasticFlavor(val dimension: FlavorDimension, val default: Boolean = false) {
fdroid(FlavorDimension.marketplace, ),
fdroid(FlavorDimension.marketplace),
google(FlavorDimension.marketplace, default = true),
}
fun configureFlavors(
commonExtension: CommonExtension<*, *, *, *, *, *>,
commonExtension: CommonExtension,
flavorConfigurationBlock: ProductFlavor.(flavor: MeshtasticFlavor) -> Unit = {},
) {
commonExtension.apply {
(commonExtension as? ApplicationExtension)?.apply {
FlavorDimension.entries.forEach { flavorDimension ->
flavorDimensions += flavorDimension.name
}
productFlavors {
MeshtasticFlavor.entries.forEach { meshtasticFlavor ->
register(meshtasticFlavor.name) {
dimension = meshtasticFlavor.dimension.name
flavorConfigurationBlock(this, meshtasticFlavor)
if (this@apply is ApplicationExtension && this is ApplicationProductFlavor) {
if (meshtasticFlavor.default) {
isDefault = true
}
}
}
}
}
}
(commonExtension as? LibraryExtension)?.apply {
FlavorDimension.entries.forEach { flavorDimension ->
flavorDimensions += flavorDimension.name
}

View file

@ -18,15 +18,31 @@
package org.meshtastic.buildlogic
import org.gradle.api.Project
import org.gradle.api.artifacts.ExternalModuleDependencyBundle
import org.gradle.api.artifacts.MinimalExternalModuleDependency
import org.gradle.api.artifacts.VersionCatalog
import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.api.provider.Provider
import org.gradle.kotlin.dsl.getByType
import org.gradle.plugin.use.PluginDependency
import java.io.FileInputStream
import java.util.Properties
val Project.libs
get(): VersionCatalog = extensions.getByType<VersionCatalogsExtension>().named("libs")
fun VersionCatalog.library(alias: String): Provider<MinimalExternalModuleDependency> =
findLibrary(alias).get()
fun VersionCatalog.bundle(alias: String): Provider<ExternalModuleDependencyBundle> =
findBundle(alias).get()
fun VersionCatalog.plugin(alias: String): Provider<PluginDependency> =
findPlugin(alias).get()
fun VersionCatalog.version(alias: String): String =
findVersion(alias).get().requiredVersion
val Project.configProperties: Properties
get() {
val properties = Properties()
@ -35,4 +51,4 @@ val Project.configProperties: Properties
FileInputStream(propertiesFile).use { properties.load(it) }
}
return properties
}
}

View file

@ -20,21 +20,22 @@ package org.meshtastic.buildlogic
import com.diffplug.gradle.spotless.SpotlessExtension
import org.gradle.api.Project
internal fun Project.configureSpotless(extension: SpotlessExtension) = extension.apply {
internal fun Project.configureSpotless(extension: SpotlessExtension) {
val ktlintVersion = libs.version("ktlint")
extension.apply {
ratchetFrom("origin/main")
kotlin {
target("src/*/kotlin/**/*.kt", "src/*/java/**/*.kt")
targetExclude("**/build/**/*.kt")
ktfmt().kotlinlangStyle().configure { it.setMaxWidth(120) }
ktlint(libs.findVersion("ktlint").get().requiredVersion)
ktlint(ktlintVersion)
.setEditorConfigPath(rootProject.file("config/spotless/.editorconfig").path)
licenseHeaderFile(rootProject.file("config/spotless/copyright.kt"))
}
kotlinGradle {
target("**/*.gradle.kts")
ktfmt().kotlinlangStyle().configure { it.setMaxWidth(120) }
ktlint(libs.findVersion("ktlint").get().requiredVersion)
ktlint(ktlintVersion)
.setEditorConfigPath(rootProject.file("config/spotless/.editorconfig").path)
licenseHeaderFile(
rootProject.file("config/spotless/copyright.kts"),

View file

@ -20,7 +20,6 @@
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.android.kotlin.multiplatform.library) apply false
alias(libs.plugins.android.library) apply false
alias(libs.plugins.compose.compiler) apply false
alias(libs.plugins.compose.multiplatform) apply false
alias(libs.plugins.datadog) apply false

View file

@ -1,3 +1,21 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
import com.android.build.api.dsl.LibraryExtension
/*
* Copyright (c) 2025 Meshtastic LLC
*
@ -43,7 +61,7 @@ dependencies {
googleApi(libs.firebase.crashlytics)
}
android {
configure<LibraryExtension> {
buildFeatures { buildConfig = true }
namespace = "org.meshtastic.core.analytics"
}

View file

@ -22,7 +22,7 @@ plugins {
kotlin {
@Suppress("UnstableApiUsage")
androidLibrary { namespace = "org.meshtastic.core.common" }
androidLibrary {}
sourceSets { androidMain.dependencies { implementation(libs.androidx.core.ktx) } }
}

View file

@ -1,3 +1,21 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
import com.android.build.api.dsl.LibraryExtension
/*
* Copyright (c) 2025 Meshtastic LLC
*
@ -22,7 +40,7 @@ plugins {
alias(libs.plugins.kover)
}
android { namespace = "org.meshtastic.core.data" }
configure<LibraryExtension> { namespace = "org.meshtastic.core.data" }
dependencies {
implementation(projects.core.analytics)
@ -38,6 +56,8 @@ dependencies {
implementation(libs.androidx.room.runtime)
implementation(libs.androidx.room.paging)
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime)
implementation(libs.androidx.core.location.altitude)
implementation(libs.androidx.paging.common)
implementation(libs.kotlinx.serialization.json)

View file

@ -1,3 +1,21 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
import com.android.build.api.dsl.LibraryExtension
/*
* Copyright (c) 2025 Meshtastic LLC
*
@ -22,7 +40,7 @@ plugins {
alias(libs.plugins.meshtastic.kotlinx.serialization)
}
android {
configure<LibraryExtension> {
namespace = "org.meshtastic.core.database"
sourceSets {
// Adds exported schema location as test app assets.
@ -39,6 +57,8 @@ dependencies {
implementation(libs.kotlinx.serialization.json)
implementation(libs.timber)
ksp(libs.androidx.room.compiler)
androidTestImplementation(libs.androidx.test.runner)
androidTestImplementation(libs.androidx.test.ext.junit)
}

View file

@ -1,3 +1,21 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
import com.android.build.api.dsl.LibraryExtension
/*
* Copyright (c) 2025 Meshtastic LLC
*
@ -22,7 +40,7 @@ plugins {
alias(libs.plugins.kover)
}
android { namespace = "org.meshtastic.core.datastore" }
configure<LibraryExtension> { namespace = "org.meshtastic.core.datastore" }
dependencies {
implementation(projects.core.proto)

View file

@ -1,3 +1,21 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
import com.android.build.api.dsl.LibraryExtension
/*
* Copyright (c) 2025 Meshtastic LLC
*
@ -20,6 +38,6 @@ plugins {
alias(libs.plugins.meshtastic.hilt)
}
android { namespace = "org.meshtastic.core.di" }
configure<LibraryExtension> { namespace = "org.meshtastic.core.di" }
dependencies {}

View file

@ -1,3 +1,21 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
import com.android.build.api.dsl.LibraryExtension
/*
* Copyright (c) 2025 Meshtastic LLC
*
@ -22,7 +40,7 @@ plugins {
alias(libs.plugins.kotlin.parcelize)
}
android {
configure<LibraryExtension> {
buildFeatures {
buildConfig = true
aidl = true

View file

@ -1,3 +1,21 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
import com.android.build.api.dsl.LibraryExtension
/*
* Copyright (c) 2025 Meshtastic LLC
*
@ -21,6 +39,6 @@ plugins {
alias(libs.plugins.kover)
}
android { namespace = "org.meshtastic.core.navigation" }
configure<LibraryExtension> { namespace = "org.meshtastic.core.navigation" }
dependencies {}
dependencies { implementation(libs.kotlinx.serialization.core) }

View file

@ -1,3 +1,21 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
import com.android.build.api.dsl.LibraryExtension
/*
* Copyright (c) 2025 Meshtastic LLC
*
@ -24,7 +42,7 @@ plugins {
alias(libs.plugins.protobuf)
}
android {
configure<LibraryExtension> {
buildFeatures { buildConfig = true }
namespace = "org.meshtastic.core.network"
}

View file

@ -1,3 +1,21 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
import com.android.build.api.dsl.LibraryExtension
/*
* Copyright (c) 2025 Meshtastic LLC
*
@ -21,6 +39,6 @@ plugins {
alias(libs.plugins.kover)
}
android { namespace = "org.meshtastic.core.prefs" }
configure<LibraryExtension> { namespace = "org.meshtastic.core.prefs" }
dependencies { googleImplementation(libs.maps.compose) }

View file

@ -1,3 +1,21 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
import com.android.build.api.dsl.LibraryExtension
/*
* Copyright (c) 2025 Meshtastic LLC
*
@ -20,7 +38,7 @@ plugins {
alias(libs.plugins.protobuf)
}
android { namespace = "org.meshtastic.core.proto" }
configure<LibraryExtension> { namespace = "org.meshtastic.core.proto" }
// per protobuf-gradle-plugin docs, this is recommended for android
protobuf {

View file

@ -1,3 +1,21 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
import com.android.build.api.dsl.LibraryExtension
/*
* Copyright (c) 2025 Meshtastic LLC
*
@ -17,7 +35,7 @@
plugins { alias(libs.plugins.meshtastic.android.library) }
android {
configure<LibraryExtension> {
buildFeatures { aidl = true }
namespace = "org.meshtastic.core.service"
}

View file

@ -14,28 +14,15 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import com.android.build.api.dsl.androidLibrary
plugins {
alias(libs.plugins.meshtastic.kmp.library)
alias(libs.plugins.compose.multiplatform)
alias(libs.plugins.compose.compiler)
id("meshtastic.kmp.library.compose")
}
kotlin {
@Suppress("UnstableApiUsage")
androidLibrary {
namespace = "org.meshtastic.core.strings"
androidResources.enable = true
}
sourceSets {
commonMain.dependencies {
implementation(compose.runtime)
// API because consuming modules will always need this dependency
api(compose.components.resources)
}
}
androidLibrary { androidResources.enable = true }
}
compose.resources {

View file

@ -1,3 +1,21 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
import com.android.build.api.dsl.LibraryExtension
/*
* Copyright (c) 2025 Meshtastic LLC
*
@ -22,7 +40,7 @@ plugins {
alias(libs.plugins.kover)
}
android { namespace = "org.meshtastic.core.ui" }
configure<LibraryExtension> { namespace = "org.meshtastic.core.ui" }
dependencies {
implementation(projects.core.data)

View file

@ -1,3 +1,21 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
import com.android.build.api.dsl.LibraryExtension
/*
* Copyright (c) 2025 Meshtastic LLC
*
@ -22,7 +40,7 @@ plugins {
alias(libs.plugins.meshtastic.hilt)
}
android { namespace = "org.meshtastic.feature.firmware" }
configure<LibraryExtension> { namespace = "org.meshtastic.feature.firmware" }
dependencies {
implementation(projects.core.common)

View file

@ -1,3 +1,21 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
import com.android.build.api.dsl.LibraryExtension
/*
* Copyright (c) 2025 Meshtastic LLC
*
@ -22,7 +40,7 @@ plugins {
alias(libs.plugins.meshtastic.kotlinx.serialization)
}
android { namespace = "org.meshtastic.feature.intro" }
configure<LibraryExtension> { namespace = "org.meshtastic.feature.intro" }
dependencies {
implementation(projects.core.strings)

View file

@ -1,3 +1,21 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
import com.android.build.api.dsl.LibraryExtension
/*
* Copyright (c) 2025 Meshtastic LLC
*
@ -22,7 +40,7 @@ plugins {
alias(libs.plugins.meshtastic.hilt)
}
android { namespace = "org.meshtastic.feature.map" }
configure<LibraryExtension> { namespace = "org.meshtastic.feature.map" }
dependencies {
implementation(projects.core.common)

View file

@ -1,3 +1,21 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
import com.android.build.api.dsl.LibraryExtension
/*
* Copyright (c) 2025 Meshtastic LLC
*
@ -22,7 +40,7 @@ plugins {
alias(libs.plugins.meshtastic.hilt)
}
android { namespace = "org.meshtastic.feature.messaging" }
configure<LibraryExtension> { namespace = "org.meshtastic.feature.messaging" }
dependencies {
implementation(projects.core.data)

View file

@ -1,3 +1,21 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
import com.android.build.api.dsl.LibraryExtension
/*
* Copyright (c) 2025 Meshtastic LLC
*
@ -22,7 +40,7 @@ plugins {
alias(libs.plugins.meshtastic.hilt)
}
android { namespace = "org.meshtastic.feature.node" }
configure<LibraryExtension> { namespace = "org.meshtastic.feature.node" }
dependencies {
implementation(projects.core.data)

View file

@ -1,3 +1,21 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
import com.android.build.api.dsl.LibraryExtension
/*
* Copyright (c) 2025 Meshtastic LLC
*
@ -22,7 +40,7 @@ plugins {
alias(libs.plugins.meshtastic.hilt)
}
android { namespace = "org.meshtastic.feature.settings" }
configure<LibraryExtension> { namespace = "org.meshtastic.feature.settings" }
dependencies {
implementation(projects.core.common)

View file

@ -60,4 +60,6 @@ org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true
dependency.analysis.print.build.health=true
ksp.incremental=true
ksp.incremental.classpath=true
ksp.incremental.classpath=true
android.newDsl=false

View file

@ -1,6 +1,6 @@
[versions]
# Android
agp = "8.13.2"
agp = "9.0.0-rc01"
appcompat = "1.7.1"
accompanist = "0.37.3"
@ -20,6 +20,9 @@ kotlinx-coroutines-android = "1.10.2"
kotlinx-serialization = "1.9.0"
ktlint = "1.7.1"
# Compose Multiplatform
compose-multiplatform = "1.9.3"
# Google
hilt = "2.57.2"
maps-compose = "7.0.0"
@ -41,7 +44,7 @@ protobuf = "4.33.2"
[libraries]
# AndroidX
androidx-activity = { module = "androidx.activity:activity" }
androidx-activity-compose = { module = "androidx.activity:activity-compose" }
androidx-activity-compose = { module = "androidx.activity:activity-compose", version = "1.12.2" }
androidx-annotation = { module = "androidx.annotation:annotation", version = "1.9.1" }
androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompat" }
androidx-constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version = "2.2.1" }
@ -54,6 +57,7 @@ androidx-emoji2-emojipicker = { module = "androidx.emoji2:emoji2-emojipicker", v
androidx-hilt-lifecycle-viewmodel-compose = { module = "androidx.hilt:hilt-lifecycle-viewmodel-compose", version = "1.3.0" }
androidx-lifecycle-livedata-ktx = { module = "androidx.lifecycle:lifecycle-livedata-ktx", version.ref = "lifecycle" }
androidx-lifecycle-process = { module = "androidx.lifecycle:lifecycle-process", version.ref = "lifecycle" }
androidx-lifecycle-runtime = { module = "androidx.lifecycle:lifecycle-runtime", version.ref = "lifecycle" }
androidx-lifecycle-runtime-compose = { module = "androidx.lifecycle:lifecycle-runtime-compose", version.ref = "lifecycle" }
androidx-lifecycle-viewmodel-compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycle" }
androidx-navigation-common = { module = "androidx.navigation:navigation-common", version.ref = "navigation" }
@ -71,7 +75,6 @@ androidx-room-testing = { module = "androidx.room:room-testing", version.ref = "
androidx-work-runtime-ktx = { module = "androidx.work:work-runtime-ktx", version = "2.11.0" }
# AndroidX Compose
accompanist-permissions = { module = "com.google.accompanist:accompanist-permissions", version.ref = "accompanist" }
androidx-compose-bom = { module = "androidx.compose:compose-bom-alpha", version = "2025.12.01" }
androidx-compose-material-iconsExtended = { module = "androidx.compose.material:material-icons-extended" }
androidx-compose-material3 = { module = "androidx.compose.material3:material3" }
@ -97,6 +100,7 @@ guava = { module = "com.google.guava:guava", version = "33.5.0-jre" }
hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" }
hilt-android-testing = { module = "com.google.dagger:hilt-android-testing", version.ref = "hilt" }
hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" }
hilt-core = { module = "com.google.dagger:hilt-core", version.ref = "hilt" }
location-services = { module = "com.google.android.gms:play-services-location", version = "21.3.0" }
maps-compose = { module = "com.google.maps.android:maps-compose", version.ref = "maps-compose" }
maps-compose-utils = { module = "com.google.maps.android:maps-compose-utils", version.ref = "maps-compose" }
@ -132,6 +136,7 @@ junit = { module = "junit:junit", version = "4.13.2" }
# Other
aboutlibraries-compose-m3 = { module = "com.mikepenz:aboutlibraries-compose-m3", version.ref = "aboutlibraries" }
accompanist-permissions = { module = "com.google.accompanist:accompanist-permissions", version.ref = "accompanist" }
coil = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil" }
coil-network-core = { module = "io.coil-kt.coil3:coil-network-core", version.ref = "coil" }
coil-network-okhttp = { module = "io.coil-kt.coil3:coil-network-okhttp", version.ref = "coil" }
@ -168,6 +173,7 @@ android-gradleApiPlugin = { module = "com.android.tools.build:gradle-api", versi
android-tools-common = { module = "com.android.tools:common", version = "31.13.2" }
androidx-room-gradlePlugin = { module = "androidx.room:room-gradle-plugin", version.ref = "room" }
compose-gradlePlugin = { module = "org.jetbrains.kotlin:compose-compiler-gradle-plugin", version.ref = "kotlin" }
compose-multiplatform-gradlePlugin = { module = "org.jetbrains.compose:compose-gradle-plugin", version.ref = "compose-multiplatform" }
datadog-gradlePlugin = { module = "com.datadoghq.dd-sdk-android-gradle-plugin:com.datadoghq.dd-sdk-android-gradle-plugin.gradle.plugin", version = "1.21.0" }
detekt-compose = { module = "io.nlopez.compose.rules:detekt", version = "0.5.3" }
detekt-formatting = { module = "io.gitlab.arturbosch.detekt:detekt-formatting", version.ref = "detekt" }
@ -184,7 +190,6 @@ spotless-gradlePlugin = { module = "com.diffplug.spotless:spotless-plugin-gradle
# Android
android-application = { id = "com.android.application", version.ref = "agp" }
android-kotlin-multiplatform-library = { id = "com.android.kotlin.multiplatform.library", version.ref = "agp" }
android-library = { id = "com.android.library", version.ref = "agp" }
android-lint = { id = "com.android.lint", version.ref = "agp" }
# Jetbrains
@ -231,5 +236,6 @@ meshtastic-detekt = { id = "meshtastic.detekt" }
meshtastic-hilt = { id = "meshtastic.hilt" }
meshtastic-kotlinx-serialization = { id = "meshtastic.kotlinx.serialization" }
meshtastic-kmp-library = { id = "meshtastic.kmp.library" }
meshtastic-kmp-library-compose = { id = "meshtastic.kmp.library.compose" }
meshtastic-root = { id = "meshtastic.root" }
meshtastic-spotless = { id = "meshtastic.spotless" }