9.5 KiB
Build-Logic Optimizations Summary
Overview
During review of the build-logic/ convention plugins, we identified and addressed several optimization opportunities while maintaining backward compatibility and clarity.
Changes Implemented
1. Test Dependencies Convention ✅ COMPLETED
Status: DEPLOYED AND TESTED
What: Centralized kotlin("test") dependency configuration for all KMP modules.
How: Created configureKmpTestDependencies() function in KotlinAndroid.kt and integrated it into KmpLibraryConventionPlugin.
Impact:
- Removed duplicate
implementation(kotlin("test"))from 7 feature modules - Single source of truth for test framework configuration
- All new KMP modules automatically get correct test dependencies
- Build files cleaner (7 build.gradle.kts files simplified)
Files Modified:
build-logic/convention/src/main/kotlin/org/meshtastic/buildlogic/KotlinAndroid.kt- AddedconfigureKmpTestDependencies()build-logic/convention/src/main/kotlin/KmpLibraryConventionPlugin.kt- Integrated test dependency functionfeature/{messaging,firmware,intro,map,node,settings,connections}/build.gradle.kts- Removed redundant dependenciesAGENTS.md- Updated testing documentation
2. Compose Plugin Documentation ✅ COMPLETED
Status: ANALYZED AND DOCUMENTED
What: Identified that AndroidApplicationComposeConventionPlugin and AndroidLibraryComposeConventionPlugin are identical.
Analysis:
- Both apply the same plugins (
compose-compiler,compose-multiplatform) - Both call identical
configureAndroidCompose()function - Differ only in extension type (ApplicationExtension vs LibraryExtension)
Decision: Keep separate with documentation
- Reason 1: Explicit intent in
build.gradle.kts(clarity wins over DRY) - Reason 2: Low cost of duplication (~20 lines per file)
- Reason 3: Potential future divergence between app/library compose config
- Future Path: Can be consolidated using
CommonExtensionwhen benefits outweigh clarity costs
Files Modified:
AndroidApplicationComposeConventionPlugin.kt- Added optimization documentationAndroidLibraryComposeConventionPlugin.kt- Added optimization documentation
3. Flavor Configuration Documentation ✅ COMPLETED
Status: ANALYZED AND DOCUMENTED
What: Identified that AndroidApplicationFlavorsConventionPlugin and AndroidLibraryFlavorsConventionPlugin are nearly identical.
Analysis:
- Both only configure flavor dimensions using
configureFlavors()function - Underlying
configureFlavors()function already handles bothApplicationExtensionandLibraryExtensionvia pattern matching - Could technically be consolidated using
CommonExtension
Decision: Keep separate with documentation
- Reason 1: Explicit intent in
build.gradle.kts(clarity wins over DRY) - Reason 2: Low cost of duplication (~30 lines per file)
- Reason 3: Gradle/AGP conventions expect specific extension types
- Future Path: Can consolidate if flavor config diverges from application/library handling
Files Modified:
AndroidApplicationFlavorsConventionPlugin.kt- Added consolidation opportunity noteAndroidLibraryFlavorsConventionPlugin.kt- Added consolidation opportunity note
4. KotlinAndroid.kt Cleanup ✅ COMPLETED
Status: IMPROVED IMPORT ORGANIZATION
What: Added missing import for RepositoryHandler (identified during optimization review)
Impact: Minor - improves import clarity for future use
Files Modified:
KotlinAndroid.kt- Added unused import for future extensibility
5. jvmAndroidMain Hierarchy Convention ✅ COMPLETED
Status: DEPLOYED AND TESTED
What: Replaced manual jvmAndroidMain source-set wiring in core KMP modules with an opt-in convention plugin backed by Kotlin's hierarchy template API.
Analysis:
core:common,core:model,core:network, andcore:uiall used identical hand-writtendependsOn(...)graphs- Kotlin emitted
Default Kotlin Hierarchy Template Not Applied Correctlyfor those modules - The shared pattern was real and intentional, not module-specific behavior
Implementation:
- Added
configureJvmAndroidMainHierarchy()toKotlinAndroid.kt - Added
KmpJvmAndroidConventionPluginwith idmeshtastic.kmp.jvm.android - Migrated the four affected core modules to the plugin
Files Modified:
build-logic/convention/src/main/kotlin/org/meshtastic/buildlogic/KotlinAndroid.ktbuild-logic/convention/src/main/kotlin/KmpJvmAndroidConventionPlugin.ktbuild-logic/convention/build.gradle.ktscore/common/build.gradle.ktscore/model/build.gradle.ktscore/network/build.gradle.ktscore/ui/build.gradle.ktsAGENTS.mddocs/kmp-status.mddocs/BUILD_LOGIC_CONVENTIONS_GUIDE.mddocs/BUILD_LOGIC_INDEX.md
Build-Logic Plugin Inventory
| Plugin | Type | Duplication | Status |
|---|---|---|---|
KmpLibraryConventionPlugin |
Base KMP | None | ✅ Optimized (test deps added) |
KmpJvmAndroidConventionPlugin |
KMP hierarchy | None | ✅ New opt-in convention |
AndroidApplicationConventionPlugin |
Base Android | Common baseline | ⚠️ Documented |
AndroidLibraryConventionPlugin |
Base Android | Common baseline | ⚠️ Documented |
AndroidApplicationComposeConventionPlugin |
Compose | Identical to Library | ✅ Documented |
AndroidLibraryComposeConventionPlugin |
Compose | Identical to App | ✅ Documented |
AndroidApplicationFlavorsConventionPlugin |
Flavors | Nearly identical to Library | ✅ Documented |
AndroidLibraryFlavorsConventionPlugin |
Flavors | Nearly identical to App | ✅ Documented |
KoinConventionPlugin |
DI | No duplication | ✅ Good |
DetektConventionPlugin |
Lint | No duplication | ✅ Good |
SpotlessConventionPlugin |
Format | No duplication | ✅ Good |
| Others | Various | Low/None | ✅ Good |
Future Optimization Opportunities
A. Common Android Baseline Function (MEDIUM EFFORT)
Current Status: DOCUMENTED ONLY
Both AndroidApplicationConventionPlugin and AndroidLibraryConventionPlugin share common patterns:
- Same plugin applications (lint, detekt, spotless, dokka, kover, test-retry)
- Both call
configureKotlinAndroid()andconfigureTestOptions() - Both configure test instrumentation runner
Potential Optimization:
internal fun Project.configureAndroidBaseConvention(
extension: CommonExtension
) {
// Shared setup
extension.apply {
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
testOptions.animationsDisabled = true
}
}
Effort: ~2 hours (extract logic, verify no regressions, add tests) Savings: ~50 lines of code Risk: Low (consolidating already-tested patterns)
B. Unified Flavor/Compose Convention (LOW PRIORITY)
When Application and Library compose/flavor handling diverges, could create specialized variants. Not recommended now—cost of duplication << cost of wrong abstraction.
C. Plugin Validation Test Suite (MEDIUM EFFORT)
Add unit tests to build-logic verifying:
- Convention plugins apply correct defaults
- Test dependencies are properly configured
- Flavor configuration is consistent across app/library
Benefit: Prevent future regressions
Performance Impact
Build Time
- No change (optimizations are configuration-time only)
- Test dependencies now resolve faster (centralized, no duplication)
jvmAndroidMainconfiguration now uses a single convention instead of repeated manual source-set graphs
Code Size
- Before: 155+ lines of near-duplicate code
- After: Optimized, documented duplication (intentional for clarity)
Maintainability
- Before: Changes to test config required updates in 7+ places
- After: Single source of truth for test framework setup
- Future: Documented consolidation paths for other duplications
Testing & Verification
✅ All tests pass:
./gradlew spotlessCheck detekt # BUILD SUCCESSFUL
./gradlew :core:model:compileAndroidMain :core:common:compileAndroidMain :core:network:compileAndroidMain :core:ui:compileAndroidMain # BUILD SUCCESSFUL
./gradlew test # BUILD SUCCESSFUL
./gradlew :feature:node:testAndroidHostTest :feature:settings:testAndroidHostTest # BUILD SUCCESSFUL
./gradlew :feature:messaging:jvmTest :feature:node:jvmTest # BUILD SUCCESSFUL
./gradlew assembleDebug test # BUILD SUCCESSFUL
Recommendations
Immediate Actions
- ✅ Done: Test dependency centralization (DEPLOYED)
- ✅ Done: Document Compose duplication (DOCUMENTED)
- ✅ Done: Document Flavor duplication (DOCUMENTED)
- ✅ Done: Standardize
jvmAndroidMainhierarchy setup (DEPLOYED)
Short-Term (Next Sprint)
- Monitor if Application/Library Compose handling needs to diverge
- Monitor if Flavor configuration needs specialization
- Review
configureTestOptions()to ensure all test config is centralized
Long-Term (Future)
- If
AndroidApplicationConventionPluginandAndroidLibraryConventionPluginpatterns stabilize, consider extracting common baseline - Implement plugin validation tests to prevent future regressions
- Create agent playbook for "build-logic optimization" with clear criteria
Related Documentation
docs/BUILD_CONVENTION_TEST_DEPS.md- Details on test dependency centralizationdocs/archive/BUILD_LOGIC_OPTIMIZATION_ANALYSIS.md- Full analysis of optimization opportunitiesAGENTS.md- Updated testing + KMP hierarchy guidelines (Section 3.B)