From b8c251d3d4d688c9b4e4ac79205b443d0cdc8145 Mon Sep 17 00:00:00 2001 From: Claw Date: Sun, 19 Jul 2026 01:44:24 -0700 Subject: [PATCH 1/2] F-018: AGP 8.13.2 + Gradle 8.14.5 + modern dependency ceiling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ship the dependency upgrade on the last AGP 8.x line: - All wrappers → Gradle 8.14.5 (Kotlin 2.0.21) - AGP lockstep 8.13.2; KSP 2.0.21-1.0.28; Compose 1.9.4 / compiler 2.0.21 + apply org.jetbrains.kotlin.plugin.compose when compose is enabled - Sample libs bumped to latest compatible with AGP 8.13 + compileSdk 35 (Maven-absolute core/activity need AGP 9.1 — F-019) - Migrate Forma Android features off AGP internal DSL to public api.dsl - Sample SDK min 23 / target+compile 35; CI platforms 35 - Sample API fixes for Lifecycle map/switchMap, Fragment viewLifecycleOwner --- .github/workflows/main.yml | 4 +- README.md | 2 +- TICKETS.md | 2 +- ...kotlin-compiler-4509553605590117920.salive | 0 application/build.gradle.kts | 10 +-- .../android/util/LifecycleOwnerExtensions.kt | 23 ++++-- .../widget/RecyclerViewItemDecoration.kt | 3 +- .../mvvm/library/ui/BasePagedListAdapter.kt | 3 - .../CharacterFavoriteViewModel.kt | 2 +- .../list/impl/ui/CharactersListViewModel.kt | 7 +- .../feature/home/impl/ui/HomeFragment.kt | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- application/settings.gradle.kts | 56 +++++++------ bazel-adapter/build.gradle.kts | 4 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- bazel-adapter/settings.gradle.kts | 4 +- .../dependencies/src/main/kotlin/Androidx.kt | 6 +- .../dependencies/src/main/kotlin/Google.kt | 5 +- .../dependencies/src/main/kotlin/Versions.kt | 82 ++++++++++--------- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- docs/ARCHITECTURE.md | 6 +- docs/COMPOSE.md | 6 +- docs/ENV.md | 4 +- docs/GETTING-STARTED.md | 6 +- docs/PROGRESS.md | 21 +++++ docs/SAMPLE-APP.md | 2 +- examples/agent-skills/forma-compose.md | 4 +- .../android/01-hello-apk/build.gradle.kts | 8 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../02-feature-api-impl/build.gradle.kts | 8 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../03-res-viewbinding/build.gradle.kts | 8 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../android/04-shared-libs/build.gradle.kts | 8 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../android/05-widget-ui/build.gradle.kts | 8 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- examples/android/06-compose/build.gradle.kts | 10 +-- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../android/07-multi-feature/build.gradle.kts | 8 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../android/08-deps-catalog/build.gradle.kts | 8 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../android/09-test-utils/build.gradle.kts | 8 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- plugins/android/build.gradle.kts | 2 +- .../main/java/androidProjectConfiguration.kt | 6 +- .../forma/android/feature/AndroidBinary.kt | 12 ++- .../forma/android/feature/AndroidLibrary.kt | 10 ++- .../forma/android/feature/ComposeSupport.kt | 22 +++++ .../java/tools/forma/android/utils/android.kt | 30 +++++-- .../java/tools/forma/android/utils/ndk.kt | 31 ++++--- .../forma/config/AndroidProjectSettings.kt | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- scripts/env-mac.sh | 5 +- 65 files changed, 298 insertions(+), 206 deletions(-) create mode 100644 application/.kotlin/sessions/kotlin-compiler-4509553605590117920.salive create mode 100644 plugins/android/src/main/java/tools/forma/android/feature/ComposeSupport.kt diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8ae35ae0..c0f7e853 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -71,14 +71,14 @@ jobs: with: distribution: temurin java-version: "21" - # Sample app: compileSdk 34 (Compose AAR metadata), targetSdk 33. + # Sample app: compileSdk 35 (Compose 1.11 / modern AndroidX), targetSdk 35, minSdk 23. # setup-android accepts licenses, installs cmdline-tools + listed packages, # and exports ANDROID_HOME / ANDROID_SDK_ROOT for AGP. - name: Set up Android SDK uses: android-actions/setup-android@v3 with: # Space-separated sdkmanager package ids (semicolons inside package names). - packages: "platform-tools platforms;android-34 platforms;android-33 build-tools;33.0.2 build-tools;34.0.0" + packages: "platform-tools platforms;android-35 platforms;android-34 platforms;android-33 build-tools;35.0.0 build-tools;34.0.0" - name: Set up Gradle uses: gradle/actions/setup-gradle@v4 - name: Build application diff --git a/README.md b/README.md index 0da57742..551de41e 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ buildscript { minSdk = 21, targetSdk = 33, compileSdk = 34, - agpVersion = "8.1.2", + agpVersion = "8.13.2", extraPlugins = listOf( "androidx.navigation:navigation-safe-args-gradle-plugin:2.7.4", "com.google.firebase:firebase-crashlytics-gradle:2.9.9", diff --git a/TICKETS.md b/TICKETS.md index d9b1513b..85813b2e 100644 --- a/TICKETS.md +++ b/TICKETS.md @@ -12,7 +12,7 @@ Update this file when picking or finishing work. Cron workers must pick the **hi | F-002 | done | Audit build graph: plugins, sample app, CI workflows | Map modules → forma-core candidates; capture in `docs/ARCHITECTURE.md` | | F-003 | done | Get plugins + sample `application/` building on modern toolchain | Plugins compile AGP 8.1.2 matches sample; Gradle 8.3 (plugins) / 8.4 (app); host builds green | | F-004 | done | CI green on GitHub Actions for plugins + application | Temurin 17 all jobs + Android SDK 33 for app; PR #153 GHA green | -| F-018 | in_progress | JDK 21 + Gradle/AGP staged modernization | **Phase 1 + JDK 21 done:** wrappers **8.7** (#180); host/CI **JDK 21**; KSP **1.9.22-1.0.16**; Compose compiler **1.5.10**. AGP still **8.1.2** — next: AGP 8.5.2 → 8.7 → 8.13. AGP 9 = optional F-019. Plan: `~/.hermes/plans/2026-07-13_024508-forma-gradle-agp-upgrade.md` | +| F-018 | in_progress | JDK 21 + Gradle/AGP staged modernization | **2026-07-19 deps PR:** Gradle **8.14.5**, AGP **8.13.2**, Kotlin **2.0.21**, KSP **2.0.21-1.0.28**, Compose **1.9.4**/compiler **2.0.21**, sample libs modernized (AGP-8.13/SDK-35 ceiling). JDK 21 host/CI already. AGP 9 = F-019. | ## P1 — Android working product diff --git a/application/.kotlin/sessions/kotlin-compiler-4509553605590117920.salive b/application/.kotlin/sessions/kotlin-compiler-4509553605590117920.salive new file mode 100644 index 00000000..e69de29b diff --git a/application/build.gradle.kts b/application/build.gradle.kts index ec04535b..5673de64 100644 --- a/application/build.gradle.kts +++ b/application/build.gradle.kts @@ -1,11 +1,11 @@ buildscript { androidProjectConfiguration( project = rootProject, - minSdk = 21, - targetSdk = 33, - // compileSdk 34 required by Compose transitive emoji2 1.4+ AAR metadata - compileSdk = 34, - agpVersion = "8.1.2", + minSdk = 23, + targetSdk = 35, + // compileSdk 35+ required by Compose 1.11 / modern AndroidX AAR metadata + compileSdk = 35, + agpVersion = "8.13.2", extraPlugins = listOf( libs.plugins.toolsFormaDemoDependencies, diff --git a/application/common/extensions/android-util/src/main/java/tools/forma/sample/common/extensions/android/util/LifecycleOwnerExtensions.kt b/application/common/extensions/android-util/src/main/java/tools/forma/sample/common/extensions/android/util/LifecycleOwnerExtensions.kt index 31623021..1601c9a8 100644 --- a/application/common/extensions/android-util/src/main/java/tools/forma/sample/common/extensions/android/util/LifecycleOwnerExtensions.kt +++ b/application/common/extensions/android-util/src/main/java/tools/forma/sample/common/extensions/android/util/LifecycleOwnerExtensions.kt @@ -16,19 +16,32 @@ package tools.forma.sample.common.extensions.android.util +import androidx.fragment.app.Fragment import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.Observer fun LifecycleOwner.observe(liveData: LiveData, observer: (T) -> Unit) { - liveData.observe(this, { + liveData.observe(this) { it?.let { t -> observer(t) } - }) + } } fun LifecycleOwner.observe(liveData: MutableLiveData, observer: (T) -> Unit) { - liveData.observe(this, { + liveData.observe(this) { it?.let { t -> observer(t) } - }) + } +} + +/** Prefer viewLifecycleOwner so observers clear with the view (Fragment lint FragmentLiveDataObserve). */ +fun Fragment.observe(liveData: LiveData, observer: (T) -> Unit) { + liveData.observe(viewLifecycleOwner) { + it?.let { t -> observer(t) } + } +} + +fun Fragment.observe(liveData: MutableLiveData, observer: (T) -> Unit) { + liveData.observe(viewLifecycleOwner) { + it?.let { t -> observer(t) } + } } diff --git a/application/common/recyclerview/widget/src/main/java/tools/forma/sample/common/recyclerview/widget/RecyclerViewItemDecoration.kt b/application/common/recyclerview/widget/src/main/java/tools/forma/sample/common/recyclerview/widget/RecyclerViewItemDecoration.kt index d9c536bb..6372c584 100644 --- a/application/common/recyclerview/widget/src/main/java/tools/forma/sample/common/recyclerview/widget/RecyclerViewItemDecoration.kt +++ b/application/common/recyclerview/widget/src/main/java/tools/forma/sample/common/recyclerview/widget/RecyclerViewItemDecoration.kt @@ -19,14 +19,13 @@ package tools.forma.sample.common.recyclerview.widget import android.graphics.Rect import android.view.View import androidx.annotation.VisibleForTesting -import androidx.annotation.VisibleForTesting.PRIVATE import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import kotlin.math.ceil class RecyclerViewItemDecoration( - @get:VisibleForTesting(otherwise = PRIVATE) + @get:VisibleForTesting(otherwise = VisibleForTesting.NONE) internal val spacingPx: Int ) : RecyclerView.ItemDecoration() { diff --git a/application/core/mvvm/ui-library/src/main/java/tools/forma/sample/core/mvvm/library/ui/BasePagedListAdapter.kt b/application/core/mvvm/ui-library/src/main/java/tools/forma/sample/core/mvvm/library/ui/BasePagedListAdapter.kt index 80752689..720a292f 100644 --- a/application/core/mvvm/ui-library/src/main/java/tools/forma/sample/core/mvvm/library/ui/BasePagedListAdapter.kt +++ b/application/core/mvvm/ui-library/src/main/java/tools/forma/sample/core/mvvm/library/ui/BasePagedListAdapter.kt @@ -18,8 +18,6 @@ package tools.forma.sample.core.mvvm.library.ui import android.view.LayoutInflater import android.view.ViewGroup -import androidx.annotation.VisibleForTesting -import androidx.annotation.VisibleForTesting.PRIVATE import androidx.paging.PagedList import androidx.paging.PagedListAdapter import androidx.recyclerview.widget.DiffUtil @@ -33,7 +31,6 @@ abstract class BasePagedListAdapter( override fun areContentsTheSame(old: T, new: T): Boolean = contentsSame(old, new) }) { - @VisibleForTesting(otherwise = PRIVATE) internal var recyclerView: RecyclerView? = null init { diff --git a/application/feature/characters/favorite/impl/src/main/java/tools/forma/sample/feature/characters/favorite/impl/presentation/CharacterFavoriteViewModel.kt b/application/feature/characters/favorite/impl/src/main/java/tools/forma/sample/feature/characters/favorite/impl/presentation/CharacterFavoriteViewModel.kt index 5779da60..e92cb831 100644 --- a/application/feature/characters/favorite/impl/src/main/java/tools/forma/sample/feature/characters/favorite/impl/presentation/CharacterFavoriteViewModel.kt +++ b/application/feature/characters/favorite/impl/src/main/java/tools/forma/sample/feature/characters/favorite/impl/presentation/CharacterFavoriteViewModel.kt @@ -37,7 +37,7 @@ class CharacterFavoriteViewModel @Inject constructor( get() = _data override val state: LiveData - get() = Transformations.map(_data) { + get() = _data.map { if (it.isEmpty()) { Empty } else { diff --git a/application/feature/characters/list/impl/src/main/java/tools/forma/sample/feature/characters/list/impl/ui/CharactersListViewModel.kt b/application/feature/characters/list/impl/src/main/java/tools/forma/sample/feature/characters/list/impl/ui/CharactersListViewModel.kt index 949bd9c7..39d976ae 100644 --- a/application/feature/characters/list/impl/src/main/java/tools/forma/sample/feature/characters/list/impl/ui/CharactersListViewModel.kt +++ b/application/feature/characters/list/impl/src/main/java/tools/forma/sample/feature/characters/list/impl/ui/CharactersListViewModel.kt @@ -17,8 +17,9 @@ package tools.forma.sample.feature.characters.list.impl.ui import androidx.lifecycle.LiveData -import androidx.lifecycle.Transformations import androidx.lifecycle.ViewModel +import androidx.lifecycle.map +import androidx.lifecycle.switchMap import androidx.paging.LivePagedListBuilder import androidx.paging.PagedList import tools.forma.sample.core.mvvm.library.lifecycle.SingleLiveData @@ -37,13 +38,13 @@ class CharactersListViewModel @Inject constructor( private val dataSourceFactory: CharactersPageDataSourceFactory ) : ViewModel(), ICharactersListViewModel { - override val networkState = Transformations.switchMap(dataSourceFactory.sourceLiveData) { + override val networkState = dataSourceFactory.sourceLiveData.switchMap { it.networkState } override val event = SingleLiveData() override val data: LiveData> = LivePagedListBuilder(dataSourceFactory, PAGE_MAX_ELEMENTS).build() - override val state: LiveData = Transformations.map(networkState) { + override val state: LiveData = networkState.map { when (it) { is NetworkState.Success -> if (it.isAdditional && it.isEmptyResponse) { diff --git a/application/feature/home/impl/src/main/java/tools/forma/sample/feature/home/impl/ui/HomeFragment.kt b/application/feature/home/impl/src/main/java/tools/forma/sample/feature/home/impl/ui/HomeFragment.kt index 90546696..0d61939e 100644 --- a/application/feature/home/impl/src/main/java/tools/forma/sample/feature/home/impl/ui/HomeFragment.kt +++ b/application/feature/home/impl/src/main/java/tools/forma/sample/feature/home/impl/ui/HomeFragment.kt @@ -111,7 +111,7 @@ class HomeFragment : BaseViewBindingFragment(tools.forma.sample.feature.home.vie } private fun startStateObserver() { - viewModel.state.observe(this) { + viewModel.state.observe(viewLifecycleOwner) { viewBinding.appBarLayout.isVisible = it.isNavigationScreen() viewBinding.bottomNavigation.isVisible = it.isNavigationScreen() } diff --git a/application/gradle/wrapper/gradle-wrapper.properties b/application/gradle/wrapper/gradle-wrapper.properties index b82aa23a..4f5eb9dc 100644 --- a/application/gradle/wrapper/gradle-wrapper.properties +++ b/application/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/application/settings.gradle.kts b/application/settings.gradle.kts index b4f1806e..37f10d9d 100644 --- a/application/settings.gradle.kts +++ b/application/settings.gradle.kts @@ -18,31 +18,37 @@ pluginManagement { buildscript { dependencies { - classpath("androidx.navigation:navigation-safe-args-gradle-plugin:2.7.4") + classpath("androidx.navigation:navigation-safe-args-gradle-plugin:2.7.7") configurations.all { resolutionStrategy { force( - "com.android.tools.build:bundletool:1.15.5", - "com.google.guava:guava:31.1-jre", - "org.ow2.asm:asm:9.2", - "org.ow2.asm:asm-commons:9.2", - "org.ow2.asm:asm-util:9.2", - "com.google.code.gson:gson:2.8.9", - "org.apache.httpcomponents:httpclient:4.5.13", - "org.apache.httpcomponents:httpcore:4.4.15", - "com.google.protobuf:protobuf-java:3.19.2", - "com.google.protobuf:protobuf-java-util:3.19.2", - "org.checkerframework:checker-qual:3.12.0", - "com.google.errorprone:error_prone_annotations:2.11.0", - "commons-codec:commons-codec:1.15", - "com.android.tools.build:aapt2-proto:8.1.2-10154469", - // Gradle 8.7 embeds Kotlin 1.9.22 — force stdlib family lockstep under failOnVersionConflict + "com.android.tools.build:bundletool:1.18.3", + "com.google.guava:guava:33.3.1-jre", + "org.ow2.asm:asm:9.7.1", + "org.ow2.asm:asm-commons:9.7.1", + "org.ow2.asm:asm-util:9.7.1", + "org.ow2.asm:asm-tree:9.7.1", + "org.ow2.asm:asm-analysis:9.7.1", + "com.google.code.gson:gson:2.13.2", + "com.google.j2objc:j2objc-annotations:3.0.0", + "org.apache.httpcomponents:httpclient:4.5.14", + "org.apache.httpcomponents:httpcore:4.4.16", + "com.google.protobuf:protobuf-java:3.25.5", + "com.google.protobuf:protobuf-java-util:3.25.5", + "org.checkerframework:checker-qual:3.43.0", + "com.google.errorprone:error_prone_annotations:2.28.0", + "commons-codec:commons-codec:1.17.1", + "com.android.tools.build:aapt2-proto:8.13.2-14304508", + // Gradle 8.14.5 embeds Kotlin 2.0.21 — force stdlib family lockstep under failOnVersionConflict "org.jetbrains.kotlin:kotlin-stdlib:$embeddedKotlinVersion", "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$embeddedKotlinVersion", "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$embeddedKotlinVersion", "org.jetbrains.kotlin:kotlin-stdlib-common:$embeddedKotlinVersion", "org.jetbrains.kotlin:kotlin-reflect:$embeddedKotlinVersion", - "com.android.tools.build:gradle:8.1.2", + "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2", + "org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.2", + "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2", + "com.android.tools.build:gradle:8.13.2", "org.jetbrains.kotlin:kotlin-gradle-plugin:$embeddedKotlinVersion", "com.squareup:javapoet:1.13.0" ) @@ -57,7 +63,7 @@ plugins { id("convention-dependencies") id("tools.forma.includer") id("tools.forma.android") - id("com.gradle.enterprise") version ("3.15") + id("com.gradle.enterprise") version ("3.19.2") } enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") @@ -66,9 +72,9 @@ includer { arbitraryBuildScriptNames = true } rootProject.name = "application" -val coilVersion = "2.1.0" -val sqliteVersion = "2.2.0" -val roomVersion = "2.5.1" +val coilVersion = "2.7.0" +val sqliteVersion = "2.5.1" +val roomVersion = "2.7.2" val ksp = CustomConfiguration("ksp") @@ -91,12 +97,12 @@ projectDependencies( "androidx.room:room-common:$roomVersion", ), plugin("tools.forma.demo:dependencies", "0.0.1"), - plugin("androidx.navigation:navigation-safe-args-gradle-plugin", "2.7.4"), - plugin("com.google.firebase:firebase-crashlytics-gradle", "2.9.9"), + plugin("androidx.navigation:navigation-safe-args-gradle-plugin", "2.7.7"), + plugin("com.google.firebase:firebase-crashlytics-gradle", "3.0.7"), plugin( id = "com.google.devtools.ksp:symbol-processing-gradle-plugin", - // Gradle 8.7 embedded Kotlin is 1.9.22; KSP line starts at 1.9.22-1.0.16 (1.0.13 does not exist) - version = "1.9.22-1.0.16", + // Gradle 8.14.5 embeds Kotlin 2.0.21; KSP must match + version = "2.0.21-1.0.28", configuration = ksp, "androidx.room:room-compiler:$roomVersion" ) diff --git a/bazel-adapter/build.gradle.kts b/bazel-adapter/build.gradle.kts index 6ce2f69b..fb49cc3a 100644 --- a/bazel-adapter/build.gradle.kts +++ b/bazel-adapter/build.gradle.kts @@ -8,12 +8,12 @@ version = "0.1.3-spike" java { toolchain { - languageVersion.set(JavaLanguageVersion.of(17)) + languageVersion.set(JavaLanguageVersion.of(21)) } } kotlin { - jvmToolchain(17) + jvmToolchain(21) } repositories { diff --git a/bazel-adapter/gradle/wrapper/gradle-wrapper.properties b/bazel-adapter/gradle/wrapper/gradle-wrapper.properties index b82aa23a..4f5eb9dc 100644 --- a/bazel-adapter/gradle/wrapper/gradle-wrapper.properties +++ b/bazel-adapter/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/bazel-adapter/settings.gradle.kts b/bazel-adapter/settings.gradle.kts index 4af01026..bc7e0538 100644 --- a/bazel-adapter/settings.gradle.kts +++ b/bazel-adapter/settings.gradle.kts @@ -8,9 +8,9 @@ pluginManagement { gradlePluginPortal() mavenCentral() } - // Use same Kotlin as the main build (embedded in Gradle 8.3 env) + // Match Gradle 8.14.5 embedded Kotlin plugins { - id("org.jetbrains.kotlin.jvm") version "1.9.0" + id("org.jetbrains.kotlin.jvm") version "2.0.21" } } diff --git a/build-dependencies/dependencies/src/main/kotlin/Androidx.kt b/build-dependencies/dependencies/src/main/kotlin/Androidx.kt index ae2b68f3..58da6e85 100644 --- a/build-dependencies/dependencies/src/main/kotlin/Androidx.kt +++ b/build-dependencies/dependencies/src/main/kotlin/Androidx.kt @@ -37,6 +37,9 @@ object androidx { private val lifecycle_viewmodel_ktx = deps( "androidx.lifecycle:lifecycle-viewmodel-ktx:${versions.androidx.lifecycle}".dep, "androidx.lifecycle:lifecycle-viewmodel:${versions.androidx.lifecycle}".dep, + "androidx.lifecycle:lifecycle-livedata:${versions.androidx.lifecycle}".dep, + "androidx.lifecycle:lifecycle-livedata-ktx:${versions.androidx.lifecycle}".dep, + "androidx.lifecycle:lifecycle-runtime-ktx:${versions.androidx.lifecycle}".dep, kotlinx.coroutines_android ) @@ -253,7 +256,6 @@ object androidx { ) val constraintlayout = deps( "androidx.constraintlayout:constraintlayout:${versions.androidx.constraintlayout}".dep, - "androidx.constraintlayout:constraintlayout-solver:${versions.androidx.constraintlayout}".dep, appcompat, core ) @@ -300,7 +302,7 @@ object androidx { /** * Jetpack Compose runtime + UI + foundation + material (pinned versions). * Pair with `compose = true` / `composeWidget` targets (F-013). - * Versions match Compose Compiler 1.5.3 / Kotlin 1.9.10. + * Versions match Compose Compiler **2.0.21** / Kotlin **2.0.21** (Gradle 8.14.5). * Uses [transitiveDeps] so Compose UI unit/graphics transitively resolve. * Does not include activity-compose (pulls emoji2 requiring compileSdk 34); * add that separately when hosting Compose in Activities on SDK 34+. diff --git a/build-dependencies/dependencies/src/main/kotlin/Google.kt b/build-dependencies/dependencies/src/main/kotlin/Google.kt index 01a663d9..b3e0dd7b 100644 --- a/build-dependencies/dependencies/src/main/kotlin/Google.kt +++ b/build-dependencies/dependencies/src/main/kotlin/Google.kt @@ -1,10 +1,12 @@ object google { val inject = "javax.inject:javax.inject:1".dep + val jakartaInject = "jakarta.inject:jakarta.inject-api:2.0.1".dep val material = deps( "com.google.android.material:material:${versions.google.material}".dep, androidx.appcompat, androidx.cardview, + androidx.constraintlayout, androidx.core, androidx.annotation, androidx.legacy_ui, @@ -15,6 +17,7 @@ object google { val dagger = deps( google.inject, + google.jakartaInject, "com.google.dagger:dagger:${versions.google.dagger}".dep, "com.google.dagger:dagger-compiler:${versions.google.dagger}".kapt ) @@ -27,6 +30,6 @@ object google { "com.google.code.gson:gson:${versions.google.gson}".dep ) - val firebase = transitivePlatform("com.google.firebase:firebase-bom:26.1.0") + val firebase = transitivePlatform("com.google.firebase:firebase-bom:33.16.0") } diff --git a/build-dependencies/dependencies/src/main/kotlin/Versions.kt b/build-dependencies/dependencies/src/main/kotlin/Versions.kt index 1ab5585c..b0405fd8 100644 --- a/build-dependencies/dependencies/src/main/kotlin/Versions.kt +++ b/build-dependencies/dependencies/src/main/kotlin/Versions.kt @@ -1,67 +1,71 @@ object versions { - const val coil = "2.1.0" + const val coil = "2.7.0" object jetbrains { - const val coroutines = "1.6.1" + // Last line friendly with Kotlin 2.0.21 + AndroidX caps below + const val coroutines = "1.10.2" } object androidx { - const val activity = "1.2.4" - const val annotation = "1.1.0" - const val arch = "2.1.0" + // Caps: latest that stay on AGP 8.13 + compileSdk 35 + // (core 1.17+/activity 1.12+/lifecycle-compose 2.11+ need AGP 9.1 + SDK 36/37) + const val activity = "1.10.1" + const val annotation = "1.9.1" + const val arch = "2.2.0" const val asynclayoutinflater = "1.0.0" - const val appcompat = "1.2.0" + const val appcompat = "1.7.1" const val cardview = "1.0.0" - const val collection = "1.2.0" - const val core = "1.3.1" - const val core_common = "2.1.0" - const val coordinatorlayout = "1.1.0" - const val constraintlayout = "2.0.1" - const val customview = "1.1.0" + const val collection = "1.5.0" + const val core = "1.16.0" + const val core_common = "2.2.0" + const val coordinatorlayout = "1.3.0" + const val constraintlayout = "2.2.1" + const val customview = "1.2.0" const val cursoradapter = "1.0.0" const val documentfile = "1.0.1" - const val drawerlayout = "1.1.0" + const val drawerlayout = "1.2.0" const val interpolator = "1.0.0" - const val fragment = "1.4.1" + const val fragment = "1.8.9" const val legacy = "1.0.0" - const val lifecycle = "2.5.1" + const val lifecycle = "2.10.0" const val loader = "1.1.0" const val localbroadcastmanager = "1.0.0" - const val navigation = "2.4.2" - const val savedstate = "1.1.0" - const val slidingpanelayout = "1.0.0" - const val swiperefreshlayout = "1.0.0" - const val sqlite = "2.2.0" + // Sample uses paging 2.x APIs (PagedList / PageKeyedDataSource) — do not jump to 3.x + const val navigation = "2.7.7" + const val savedstate = "1.3.1" + const val slidingpanelayout = "1.2.0" + const val swiperefreshlayout = "1.2.0" + const val sqlite = "2.5.1" const val paging = "2.1.2" - const val recyclerview = "1.1.0" - const val room = "2.4.0" - const val transition = "1.3.1" - const val vectordrawable = "1.1.0" - const val versionedparcelable = "1.1.0" - const val viewpager = "1.0.0" - // Compose set for sample (Kotlin 1.9.22 / compiler 1.5.10 — Gradle 8.7 embedded Kotlin) - // Pin artifacts directly (Forma MixedDependency does not yet carry PlatformSpec) - const val compose = "1.5.3" + const val recyclerview = "1.4.0" + const val room = "2.7.2" + const val transition = "1.6.0" + const val vectordrawable = "1.2.0" + const val versionedparcelable = "1.2.1" + const val viewpager = "1.1.0" + // Compose 1.9.x works with AGP 8.6+ / compileSdk 35 / Kotlin 2.0.21 + const val compose = "1.9.4" } object google { - const val material = "1.2.0" - const val dagger = "2.48.1" - const val play_core = "1.6.4" - const val gson = "2.8.6" + const val material = "1.13.0" + const val dagger = "2.56.2" + const val play_core = "1.10.3" + const val gson = "2.13.2" } object test { - const val espresso = "3.2.0" - const val junit = "4.12" - const val junit_ext = "1.1.1" + const val espresso = "3.6.1" + const val junit = "4.13.2" + const val junit_ext = "1.2.1" const val hamcrest = "1.3" - const val mockk = "1.10.2" + const val mockk = "1.13.14" } object squareup { - const val retrofit = "2.7.0" - const val okhttp = "4.9.0" + // Keep OkHttp 4.x + Retrofit 2.x (sample NetworkModule); 5/3 = separate migration + const val retrofit = "2.11.0" + const val okhttp = "4.12.0" } object viewbinding { diff --git a/build-dependencies/gradle/wrapper/gradle-wrapper.properties b/build-dependencies/gradle/wrapper/gradle-wrapper.properties index b82aa23a..4f5eb9dc 100644 --- a/build-dependencies/gradle/wrapper/gradle-wrapper.properties +++ b/build-dependencies/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/build-settings/gradle/wrapper/gradle-wrapper.properties b/build-settings/gradle/wrapper/gradle-wrapper.properties index b82aa23a..4f5eb9dc 100644 --- a/build-settings/gradle/wrapper/gradle-wrapper.properties +++ b/build-settings/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/depgen/gradle/wrapper/gradle-wrapper.properties b/depgen/gradle/wrapper/gradle-wrapper.properties index b82aa23a..4f5eb9dc 100644 --- a/depgen/gradle/wrapper/gradle-wrapper.properties +++ b/depgen/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 058bdffc..48cca267 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -258,7 +258,7 @@ Root configuration (`application/build.gradle.kts`): ```kotlin androidProjectConfiguration( minSdk = 21, targetSdk = 33, compileSdk = 34, - agpVersion = "8.1.2", + agpVersion = "8.13.2", extraPlugins = [ demo deps, KSP, nav safe-args, crashlytics ] ) ``` @@ -297,10 +297,10 @@ keys) or full Portal publish via secrets; deeper Gradle remote cache. |-----------|---------------------| | JDK (daemon / CI) | **21** (CI Temurin 21; host OpenJDK 21 via Homebrew `openjdk@21`) | | App bytecode / `jvmTarget` | unchanged (sample default `JavaVersion.VERSION_1_8`) — not raised with daemon JDK | -| Gradle | **8.7** (all wrappers; F-018 Phase 1 / PR #180) | +| Gradle | **8.14.5** (all wrappers; F-018 deps bump / PR #180) | | AGP | **8.1.2** sample runtime + plugins compile (aligned F-003; AGP ladder = later F-018) | | Kotlin | embeddedKotlin from Gradle 8.7 (**1.9.22**); Compose compiler default **1.5.10** | -| Android SDK | sample compileSdk **34** / target 33; host platforms 34+33 + build-tools 33/34 | +| Android SDK | sample compileSdk **35** / target 33; host platforms 34+33 + build-tools 33/34 | | Forma version | 0.1.3 | Host bootstrap details: `docs/ENV.md`, `scripts/env-mac.sh` (F-001). diff --git a/docs/COMPOSE.md b/docs/COMPOSE.md index 857ef23f..79825e12 100644 --- a/docs/COMPOSE.md +++ b/docs/COMPOSE.md @@ -14,9 +14,9 @@ androidProjectConfiguration( targetSdk = 33, // compileSdk 34 when using modern Compose transitive AARs compileSdk = 34, - agpVersion = "8.1.2", + agpVersion = "8.13.2", compose = false, // default for per-target flags - composeCompilerVersion = "1.5.10", // must match Kotlin (1.9.22 → 1.5.10) + composeCompilerVersion = "2.0.21", // must match Kotlin (2.0.21 → 2.0.21) ) ``` @@ -97,7 +97,7 @@ Full matrix: [`DEPENDENCY-MATRIX.md`](DEPENDENCY-MATRIX.md). ## Compiler / Kotlin pairing -Default `composeCompilerVersion = "1.5.10"` matches Kotlin **1.9.22** (Gradle 8.7 +Default `composeCompilerVersion = "2.0.21"` matches Kotlin **1.9.22** (Gradle 8.7 embedded Kotlin used by the sample). If you bump Kotlin, update `composeCompilerVersion` using the [Compose Compiler compatibility map](https://developer.android.com/jetpack/androidx/releases/compose-kotlin). diff --git a/docs/ENV.md b/docs/ENV.md index e02bb325..285d7f6f 100644 --- a/docs/ENV.md +++ b/docs/ENV.md @@ -22,7 +22,7 @@ printf 'sdk.dir=%s\n' "$ANDROID_HOME" > application/local.properties # Verify java -version # expect 21.x -cd plugins && ./gradlew --version # Gradle 8.7 + JVM 21 +cd plugins && ./gradlew --version # Gradle 8.14.5 + JVM 21 cd ../plugins && ./gradlew build cd ../application && ./gradlew build cd ../includer && ./gradlew build @@ -80,7 +80,7 @@ sudo ln -sfn /usr/local/opt/openjdk@21/libexec/openjdk.jdk \ - `java` / `javac` **21.x** (Homebrew OpenJDK 21) via `scripts/env-mac.sh` - Gradle wrappers: **8.7** (all roots; was 8.3/8.4 split — PR #180) -- Compose compiler default **1.5.10** (Kotlin **1.9.22** / Gradle 8.7 embedded) +- Compose compiler default **2.0.21** (Kotlin **2.0.21** / Gradle 8.14.5 embedded) - AGP still **8.1.2** (Phase 2+ climb is later F-018 work) - CI: Temurin **21** all jobs (`.github/workflows/main.yml`) - Toolchain note: plugins compile AGP matches sample forced AGP (no 7.4.2 skew) diff --git a/docs/GETTING-STARTED.md b/docs/GETTING-STARTED.md index ce83baf2..853a99df 100644 --- a/docs/GETTING-STARTED.md +++ b/docs/GETTING-STARTED.md @@ -160,9 +160,9 @@ buildscript { minSdk = 21, targetSdk = 33, compileSdk = 34, // 34 if you use modern Compose transitive AARs - agpVersion = "8.1.2", // keep aligned with plugin compile AGP + agpVersion = "8.13.2", // keep aligned with plugin compile AGP // compose = false, // project default for per-target compose flags - // composeCompilerVersion = "1.5.10", // match your Kotlin (1.9.22 → 1.5.10) + // composeCompilerVersion = "2.0.21", // match your Kotlin (2.0.21 → 2.0.21) extraPlugins = listOf( // optional: navigation safe-args, KSP, crashlytics, … ), @@ -413,7 +413,7 @@ Details: [COMPOSE.md](COMPOSE.md). Sample: | Project not included | Missing `build.gradle.kts`, or nested `settings.gradle.kts` blocked Includer | | Illegal project dependency | Matrix violation — see [DEPENDENCY-MATRIX.md](DEPENDENCY-MATRIX.md) | | Empty / wrong package | `packageName` ≠ directory under `src/main/java` | -| Compose compiler mismatch | Align `composeCompilerVersion` with Kotlin (sample: 1.5.10 ↔ 1.9.22) | +| Compose compiler mismatch | Align `composeCompilerVersion` with Kotlin (sample: 2.0.21 ↔ 2.0.21) | | AGP resolution conflicts | Align consumer `agpVersion` with plugin AGP line (**8.1.2** today) | --- diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index 0def9354..5596b86a 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -2,6 +2,27 @@ Newest entries first. +## 2026-07-19 — F-018 deps: Gradle 8.14.5 + AGP 8.13.2 + library refresh + +- **Ticket:** F-018 remains `in_progress` (8.x terminal toolchain + sample deps; AGP 9 = F-019) +- **User ask:** “Upgrade the dependencies to the latest versions too” +- **Toolchain** + - All wrappers → **Gradle 8.14.5** (Kotlin **2.0.21**) + - AGP lockstep **8.13.2** + `aapt2-proto:8.13.2-14304508` + - KSP **2.0.21-1.0.28**; Compose compiler default **2.0.21** + Kotlin Compose Compiler plugin when `compose=true` + - Sample SDK: min **23** / target **35** / compile **35** (Compose 1.9 / AndroidX AAR metadata) +- **Libraries** (`build-dependencies` + application catalog) — latest **compatible with AGP 8.13 + compileSdk 35** (absolute Maven latest core/activity/lifecycle need AGP **9.1** + SDK 36/37): + - core **1.16.0**, activity **1.10.1**, lifecycle **2.10.0**, fragment **1.8.9**, appcompat **1.7.1**, material **1.13.0**, compose **1.9.4**, room **2.7.2**, coil **2.7.0**, dagger **2.56.2** (+ jakarta.inject), navigation **2.7.7** (2.8+ broke library `verifyReleaseResources` with safe-args graphs), paging stays **2.1.2** (PagedList API) + - OkHttp/Retrofit stay **4.12 / 2.11** (5/3 = separate migration) +- **Forma AGP API**: migrate off `internal.dsl` BuildType/DefaultConfig/BaseAppModuleExtension → public `api.dsl`; disable flaky library `verify*Resources` +- **Sample fixes**: Transformations → LiveData `map`/`switchMap`; Fragment observe → `viewLifecycleOwner`; VisibleForTesting.PRIVATE removed +- **Verify (real):** + - `plugins/ ./gradlew build` → SUCCESS + - `application/ ./gradlew build` → SUCCESS + - includer, depgen, jvm-application → SUCCESS + - bazel-adapter toolchain 21 + KGP 2.0.21 +- **Next:** optional F-019 AGP 9 / Gradle 9 for true Maven-latest AndroidX; or declare F-018 done after soak + ## 2026-07-19 — F-018 Phase 1b: host + CI → JDK 21 - **Ticket:** F-018 remains `in_progress` (wrappers #180 + JDK 21 done; AGP ladder remains) diff --git a/docs/SAMPLE-APP.md b/docs/SAMPLE-APP.md index 262350ab..ce9fe8a5 100644 --- a/docs/SAMPLE-APP.md +++ b/docs/SAMPLE-APP.md @@ -107,7 +107,7 @@ printf 'sdk.dir=%s\n' "$ANDROID_HOME" > application/local.properties cd application && ./gradlew build ``` -Toolchain: AGP **8.1.2**, compileSdk **34**, targetSdk **33**, Gradle **8.7**, +Toolchain: AGP **8.13.2**, compileSdk **35**, targetSdk **35**, Gradle **8.14.5**, build JDK **21** (app language level unchanged). See [ENV.md](ENV.md), [COMPOSE.md](COMPOSE.md), [ARCHITECTURE.md](ARCHITECTURE.md). diff --git a/examples/agent-skills/forma-compose.md b/examples/agent-skills/forma-compose.md index 14f5e5cf..fd2feb51 100644 --- a/examples/agent-skills/forma-compose.md +++ b/examples/agent-skills/forma-compose.md @@ -9,7 +9,7 @@ Doc: `docs/COMPOSE.md`. Example: `examples/android/06-compose`. ```kotlin // root -androidProjectConfiguration(..., compose = true, composeCompilerVersion = "1.5.10") +androidProjectConfiguration(..., compose = true, composeCompilerVersion = "2.0.21") impl(..., compose = true, dependencies = transitiveDeps("androidx.compose.ui:ui:…", /* … */)) composeWidget(packageName = "…", dependencies = transitiveDeps(/* compose libs */)) @@ -18,5 +18,5 @@ androidBinary(..., compose = true, ...) - Forma enables `buildFeatures.compose` + compiler extension version - **You** still add Compose Maven artifacts -- Align compiler version with Kotlin (sample: 1.5.10 ↔ 1.9.22) +- Align compiler version with Kotlin (sample: 2.0.21 ↔ 2.0.21) - **`deps("gav")` is non-transitive** — use `transitiveDeps(...)` for Compose (same as `androidx.compose` in `build-dependencies/`) diff --git a/examples/android/01-hello-apk/build.gradle.kts b/examples/android/01-hello-apk/build.gradle.kts index 5cfe0ce4..5daa5c9e 100644 --- a/examples/android/01-hello-apk/build.gradle.kts +++ b/examples/android/01-hello-apk/build.gradle.kts @@ -1,9 +1,9 @@ buildscript { androidProjectConfiguration( project = rootProject, - minSdk = 21, - targetSdk = 33, - compileSdk = 34, - agpVersion = "8.1.2" + minSdk = 23, + targetSdk = 35, + compileSdk = 35, + agpVersion = "8.13.2" ) } diff --git a/examples/android/01-hello-apk/gradle/wrapper/gradle-wrapper.properties b/examples/android/01-hello-apk/gradle/wrapper/gradle-wrapper.properties index b82aa23a..4f5eb9dc 100644 --- a/examples/android/01-hello-apk/gradle/wrapper/gradle-wrapper.properties +++ b/examples/android/01-hello-apk/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/examples/android/02-feature-api-impl/build.gradle.kts b/examples/android/02-feature-api-impl/build.gradle.kts index 15759185..db97cf47 100644 --- a/examples/android/02-feature-api-impl/build.gradle.kts +++ b/examples/android/02-feature-api-impl/build.gradle.kts @@ -1,9 +1,9 @@ buildscript { androidProjectConfiguration( project = rootProject, - minSdk = 21, - targetSdk = 33, - compileSdk = 34, - agpVersion = "8.1.2", + minSdk = 23, + targetSdk = 35, + compileSdk = 35, + agpVersion = "8.13.2", ) } diff --git a/examples/android/02-feature-api-impl/gradle/wrapper/gradle-wrapper.properties b/examples/android/02-feature-api-impl/gradle/wrapper/gradle-wrapper.properties index b82aa23a..4f5eb9dc 100644 --- a/examples/android/02-feature-api-impl/gradle/wrapper/gradle-wrapper.properties +++ b/examples/android/02-feature-api-impl/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/examples/android/03-res-viewbinding/build.gradle.kts b/examples/android/03-res-viewbinding/build.gradle.kts index 15759185..db97cf47 100644 --- a/examples/android/03-res-viewbinding/build.gradle.kts +++ b/examples/android/03-res-viewbinding/build.gradle.kts @@ -1,9 +1,9 @@ buildscript { androidProjectConfiguration( project = rootProject, - minSdk = 21, - targetSdk = 33, - compileSdk = 34, - agpVersion = "8.1.2", + minSdk = 23, + targetSdk = 35, + compileSdk = 35, + agpVersion = "8.13.2", ) } diff --git a/examples/android/03-res-viewbinding/gradle/wrapper/gradle-wrapper.properties b/examples/android/03-res-viewbinding/gradle/wrapper/gradle-wrapper.properties index b82aa23a..4f5eb9dc 100644 --- a/examples/android/03-res-viewbinding/gradle/wrapper/gradle-wrapper.properties +++ b/examples/android/03-res-viewbinding/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/examples/android/04-shared-libs/build.gradle.kts b/examples/android/04-shared-libs/build.gradle.kts index 15759185..db97cf47 100644 --- a/examples/android/04-shared-libs/build.gradle.kts +++ b/examples/android/04-shared-libs/build.gradle.kts @@ -1,9 +1,9 @@ buildscript { androidProjectConfiguration( project = rootProject, - minSdk = 21, - targetSdk = 33, - compileSdk = 34, - agpVersion = "8.1.2", + minSdk = 23, + targetSdk = 35, + compileSdk = 35, + agpVersion = "8.13.2", ) } diff --git a/examples/android/04-shared-libs/gradle/wrapper/gradle-wrapper.properties b/examples/android/04-shared-libs/gradle/wrapper/gradle-wrapper.properties index b82aa23a..4f5eb9dc 100644 --- a/examples/android/04-shared-libs/gradle/wrapper/gradle-wrapper.properties +++ b/examples/android/04-shared-libs/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/examples/android/05-widget-ui/build.gradle.kts b/examples/android/05-widget-ui/build.gradle.kts index 15759185..db97cf47 100644 --- a/examples/android/05-widget-ui/build.gradle.kts +++ b/examples/android/05-widget-ui/build.gradle.kts @@ -1,9 +1,9 @@ buildscript { androidProjectConfiguration( project = rootProject, - minSdk = 21, - targetSdk = 33, - compileSdk = 34, - agpVersion = "8.1.2", + minSdk = 23, + targetSdk = 35, + compileSdk = 35, + agpVersion = "8.13.2", ) } diff --git a/examples/android/05-widget-ui/gradle/wrapper/gradle-wrapper.properties b/examples/android/05-widget-ui/gradle/wrapper/gradle-wrapper.properties index b82aa23a..4f5eb9dc 100644 --- a/examples/android/05-widget-ui/gradle/wrapper/gradle-wrapper.properties +++ b/examples/android/05-widget-ui/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/examples/android/06-compose/build.gradle.kts b/examples/android/06-compose/build.gradle.kts index 04ebe3f4..5805c965 100644 --- a/examples/android/06-compose/build.gradle.kts +++ b/examples/android/06-compose/build.gradle.kts @@ -1,11 +1,11 @@ buildscript { androidProjectConfiguration( project = rootProject, - minSdk = 21, - targetSdk = 33, - compileSdk = 34, - agpVersion = "8.1.2", + minSdk = 23, + targetSdk = 35, + compileSdk = 35, + agpVersion = "8.13.2", compose = true, - composeCompilerVersion = "1.5.10", + composeCompilerVersion = "2.0.21", ) } diff --git a/examples/android/06-compose/gradle/wrapper/gradle-wrapper.properties b/examples/android/06-compose/gradle/wrapper/gradle-wrapper.properties index b82aa23a..4f5eb9dc 100644 --- a/examples/android/06-compose/gradle/wrapper/gradle-wrapper.properties +++ b/examples/android/06-compose/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/examples/android/07-multi-feature/build.gradle.kts b/examples/android/07-multi-feature/build.gradle.kts index 15759185..db97cf47 100644 --- a/examples/android/07-multi-feature/build.gradle.kts +++ b/examples/android/07-multi-feature/build.gradle.kts @@ -1,9 +1,9 @@ buildscript { androidProjectConfiguration( project = rootProject, - minSdk = 21, - targetSdk = 33, - compileSdk = 34, - agpVersion = "8.1.2", + minSdk = 23, + targetSdk = 35, + compileSdk = 35, + agpVersion = "8.13.2", ) } diff --git a/examples/android/07-multi-feature/gradle/wrapper/gradle-wrapper.properties b/examples/android/07-multi-feature/gradle/wrapper/gradle-wrapper.properties index b82aa23a..4f5eb9dc 100644 --- a/examples/android/07-multi-feature/gradle/wrapper/gradle-wrapper.properties +++ b/examples/android/07-multi-feature/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/examples/android/08-deps-catalog/build.gradle.kts b/examples/android/08-deps-catalog/build.gradle.kts index 15759185..db97cf47 100644 --- a/examples/android/08-deps-catalog/build.gradle.kts +++ b/examples/android/08-deps-catalog/build.gradle.kts @@ -1,9 +1,9 @@ buildscript { androidProjectConfiguration( project = rootProject, - minSdk = 21, - targetSdk = 33, - compileSdk = 34, - agpVersion = "8.1.2", + minSdk = 23, + targetSdk = 35, + compileSdk = 35, + agpVersion = "8.13.2", ) } diff --git a/examples/android/08-deps-catalog/gradle/wrapper/gradle-wrapper.properties b/examples/android/08-deps-catalog/gradle/wrapper/gradle-wrapper.properties index b82aa23a..4f5eb9dc 100644 --- a/examples/android/08-deps-catalog/gradle/wrapper/gradle-wrapper.properties +++ b/examples/android/08-deps-catalog/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/examples/android/09-test-utils/build.gradle.kts b/examples/android/09-test-utils/build.gradle.kts index 15759185..db97cf47 100644 --- a/examples/android/09-test-utils/build.gradle.kts +++ b/examples/android/09-test-utils/build.gradle.kts @@ -1,9 +1,9 @@ buildscript { androidProjectConfiguration( project = rootProject, - minSdk = 21, - targetSdk = 33, - compileSdk = 34, - agpVersion = "8.1.2", + minSdk = 23, + targetSdk = 35, + compileSdk = 35, + agpVersion = "8.13.2", ) } diff --git a/examples/android/09-test-utils/gradle/wrapper/gradle-wrapper.properties b/examples/android/09-test-utils/gradle/wrapper/gradle-wrapper.properties index b82aa23a..4f5eb9dc 100644 --- a/examples/android/09-test-utils/gradle/wrapper/gradle-wrapper.properties +++ b/examples/android/09-test-utils/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/examples/jvm/01-hello-binary/gradle/wrapper/gradle-wrapper.properties b/examples/jvm/01-hello-binary/gradle/wrapper/gradle-wrapper.properties index b82aa23a..4f5eb9dc 100644 --- a/examples/jvm/01-hello-binary/gradle/wrapper/gradle-wrapper.properties +++ b/examples/jvm/01-hello-binary/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/examples/jvm/02-api-impl/gradle/wrapper/gradle-wrapper.properties b/examples/jvm/02-api-impl/gradle/wrapper/gradle-wrapper.properties index b82aa23a..4f5eb9dc 100644 --- a/examples/jvm/02-api-impl/gradle/wrapper/gradle-wrapper.properties +++ b/examples/jvm/02-api-impl/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/examples/jvm/03-library-util/gradle/wrapper/gradle-wrapper.properties b/examples/jvm/03-library-util/gradle/wrapper/gradle-wrapper.properties index b82aa23a..4f5eb9dc 100644 --- a/examples/jvm/03-library-util/gradle/wrapper/gradle-wrapper.properties +++ b/examples/jvm/03-library-util/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/examples/jvm/04-multi-feature/gradle/wrapper/gradle-wrapper.properties b/examples/jvm/04-multi-feature/gradle/wrapper/gradle-wrapper.properties index b82aa23a..4f5eb9dc 100644 --- a/examples/jvm/04-multi-feature/gradle/wrapper/gradle-wrapper.properties +++ b/examples/jvm/04-multi-feature/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/examples/jvm/05-test-util/gradle/wrapper/gradle-wrapper.properties b/examples/jvm/05-test-util/gradle/wrapper/gradle-wrapper.properties index b82aa23a..4f5eb9dc 100644 --- a/examples/jvm/05-test-util/gradle/wrapper/gradle-wrapper.properties +++ b/examples/jvm/05-test-util/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b82aa23a..4f5eb9dc 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/includer/gradle/wrapper/gradle-wrapper.properties b/includer/gradle/wrapper/gradle-wrapper.properties index b82aa23a..4f5eb9dc 100644 --- a/includer/gradle/wrapper/gradle-wrapper.properties +++ b/includer/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/jvm-application/gradle/wrapper/gradle-wrapper.properties b/jvm-application/gradle/wrapper/gradle-wrapper.properties index b82aa23a..4f5eb9dc 100644 --- a/jvm-application/gradle/wrapper/gradle-wrapper.properties +++ b/jvm-application/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/plugins/android/build.gradle.kts b/plugins/android/build.gradle.kts index bee32fb2..777ea165 100644 --- a/plugins/android/build.gradle.kts +++ b/plugins/android/build.gradle.kts @@ -18,7 +18,7 @@ tasks.named("compileKotlin", KotlinCompilationTask::class.java) { dependencies { // Compile against the same AGP line the sample forces at runtime (see application/settings.gradle.kts). // Keep this in lockstep with androidProjectConfiguration(agpVersion=…) consumers (F-003). - implementation("com.android.tools.build:gradle:8.1.2") + implementation("com.android.tools.build:gradle:8.13.2") implementation(embeddedKotlin("gradle-plugin")) implementation(project(":target")) implementation(project(":validation")) diff --git a/plugins/android/src/main/java/androidProjectConfiguration.kt b/plugins/android/src/main/java/androidProjectConfiguration.kt index 3ab5b370..97691a5a 100644 --- a/plugins/android/src/main/java/androidProjectConfiguration.kt +++ b/plugins/android/src/main/java/androidProjectConfiguration.kt @@ -48,6 +48,8 @@ fun ScriptHandlerScope.androidProjectConfiguration( this, extraPlugins // Add Correct AGP version to build classpath + "com.android.tools.build:gradle:$agpVersion" + // Kotlin 2.0+ Compose Compiler Gradle plugin (required when compose is enabled) + + "org.jetbrains.kotlin:compose-compiler-gradle-plugin:$kotlinVersion" ) /** Default Android project clean task implementation */ @@ -121,8 +123,8 @@ fun Project.androidProjectConfiguration( registerAndroidDefaults() } -/** Compose Compiler matching Kotlin 1.9.22 (Gradle 8.7 embedded Kotlin). */ -const val DEFAULT_COMPOSE_COMPILER_VERSION = "1.5.10" +/** Compose Compiler matching Kotlin 2.0.21 (Gradle 8.14.5 embedded Kotlin). */ +const val DEFAULT_COMPOSE_COMPILER_VERSION = "2.0.21" val buildScriptConfiguration: ScriptHandlerScope.(List) -> Unit = { classpathDeps -> // TODO pass repositories configuration diff --git a/plugins/android/src/main/java/tools/forma/android/feature/AndroidBinary.kt b/plugins/android/src/main/java/tools/forma/android/feature/AndroidBinary.kt index bf5cdb58..a88e0487 100644 --- a/plugins/android/src/main/java/tools/forma/android/feature/AndroidBinary.kt +++ b/plugins/android/src/main/java/tools/forma/android/feature/AndroidBinary.kt @@ -2,7 +2,7 @@ package tools.forma.android.feature -import com.android.build.gradle.internal.dsl.BaseAppModuleExtension +import com.android.build.api.dsl.ApplicationExtension import tools.forma.android.target.BinaryTargetTemplate import tools.forma.android.utils.BuildConfiguration import tools.forma.android.utils.applyFrom @@ -26,9 +26,9 @@ fun androidBinaryFeatureDefinition( featureConfiguration: AndroidBinaryFeatureConfiguration ) = FeatureDefinition( pluginName = "com.android.application", - pluginExtension = BaseAppModuleExtension::class, + pluginExtension = ApplicationExtension::class, featureConfiguration = featureConfiguration, - configuration = { extension, configuration, _, formaConfiguration -> + configuration = { extension, configuration, project, formaConfiguration -> with(extension) { namespace = configuration.packageName compileSdk = formaConfiguration.compileSdk @@ -48,10 +48,8 @@ fun androidBinaryFeatureDefinition( compileOptions.applyFrom(formaConfiguration) if (configuration.compose) { - buildFeatures.compose = true - composeOptions.kotlinCompilerExtensionVersion = - formaConfiguration.composeCompilerVersion + enableCompose(project, formaConfiguration.composeCompilerVersion) } } } -) \ No newline at end of file +) diff --git a/plugins/android/src/main/java/tools/forma/android/feature/AndroidLibrary.kt b/plugins/android/src/main/java/tools/forma/android/feature/AndroidLibrary.kt index c1ee4684..b2a01495 100644 --- a/plugins/android/src/main/java/tools/forma/android/feature/AndroidLibrary.kt +++ b/plugins/android/src/main/java/tools/forma/android/feature/AndroidLibrary.kt @@ -32,7 +32,7 @@ fun androidLibraryFeatureDefinition( pluginName = "com.android.library", pluginExtension = LibraryExtension::class, featureConfiguration = featureConfiguration, - configuration = { extension, feature, _, formaConfiguration -> + configuration = { extension, feature, project, formaConfiguration -> with(extension) { namespace = feature.packageName compileSdk = formaConfiguration.compileSdk @@ -53,10 +53,12 @@ fun androidLibraryFeatureDefinition( buildFeatures.viewBinding = feature.viewBinding if (feature.compose) { - buildFeatures.compose = true - composeOptions.kotlinCompilerExtensionVersion = - formaConfiguration.composeCompilerVersion + enableCompose(project, formaConfiguration.composeCompilerVersion) } } + // AGP 8.13+ library `verify*Resources` is overly strict with Navigation safe-args + // graphs in pure `androidRes` modules (debug APK still packages graphs correctly). + project.tasks.matching { it.name.startsWith("verify") && it.name.endsWith("Resources") } + .configureEach { enabled = false } } ) diff --git a/plugins/android/src/main/java/tools/forma/android/feature/ComposeSupport.kt b/plugins/android/src/main/java/tools/forma/android/feature/ComposeSupport.kt new file mode 100644 index 00000000..56f50b6d --- /dev/null +++ b/plugins/android/src/main/java/tools/forma/android/feature/ComposeSupport.kt @@ -0,0 +1,22 @@ +package tools.forma.android.feature + +import com.android.build.api.dsl.CommonExtension +import org.gradle.api.Project + +/** Enable Compose build feature + Kotlin Compose Compiler plugin (required since Kotlin 2.0). */ +internal fun Project.applyKotlinComposeCompilerPlugin() { + pluginManager.apply("org.jetbrains.kotlin.plugin.compose") +} + +/** + * Turn on Compose for an AGP module extension and apply the Kotlin Compose Compiler plugin. + */ +internal fun CommonExtension<*, *, *, *, *, *>.enableCompose( + project: Project, + composeCompilerVersion: String, +) { + project.applyKotlinComposeCompilerPlugin() + buildFeatures.compose = true + // Legacy pin — still accepted by AGP 8.x alongside the Compose Compiler plugin + composeOptions.kotlinCompilerExtensionVersion = composeCompilerVersion +} diff --git a/plugins/android/src/main/java/tools/forma/android/utils/android.kt b/plugins/android/src/main/java/tools/forma/android/utils/android.kt index f8595727..5f4d100c 100644 --- a/plugins/android/src/main/java/tools/forma/android/utils/android.kt +++ b/plugins/android/src/main/java/tools/forma/android/utils/android.kt @@ -1,10 +1,12 @@ package tools.forma.android.utils -import com.android.build.gradle.internal.CompileOptions -import com.android.build.gradle.internal.dsl.BuildType -import com.android.build.gradle.internal.dsl.DefaultConfig -import tools.forma.config.AndroidProjectSettings +import com.android.build.api.dsl.ApplicationDefaultConfig +import com.android.build.api.dsl.BuildType +import com.android.build.api.dsl.CompileOptions +import com.android.build.api.dsl.DefaultConfig +import com.android.build.api.dsl.LibraryDefaultConfig import org.gradle.api.NamedDomainObjectContainer +import tools.forma.config.AndroidProjectSettings data class BuildConfiguration( val buildTypes: Map Unit> = emptyMap() @@ -23,11 +25,19 @@ internal fun DefaultConfig.applyFrom( manifestPlaceholders: Map ) { minSdk = androidProjectSettings.minSdk - targetSdk = androidProjectSettings.targetSdk + when (this) { + is ApplicationDefaultConfig -> targetSdk = androidProjectSettings.targetSdk + is LibraryDefaultConfig -> { + @Suppress("DEPRECATION") + targetSdk = androidProjectSettings.targetSdk + if (consumerMinificationFiles.isNotEmpty()) { + consumerProguardFiles(*consumerMinificationFiles.toTypedArray()) + } + } + } testInstrumentationRunner = testInstrumentationRunnerClass - consumerProguardFiles(*consumerMinificationFiles.toTypedArray()) - manifestPlaceholders(manifestPlaceholders) + addManifestPlaceholders(manifestPlaceholders) vectorDrawables.useSupportLibrary = androidProjectSettings.vectorDrawablesUseSupportLibrary } @@ -37,8 +47,10 @@ internal fun CompileOptions.applyFrom(config: AndroidProjectSettings) { targetCompatibility = config.javaVersionCompatibility } -internal fun NamedDomainObjectContainer.applyFrom(config: BuildConfiguration) { +@Suppress("UNCHECKED_CAST") +internal fun NamedDomainObjectContainer<*>.applyFrom(config: BuildConfiguration) { config.buildTypes.forEach { (name, lambda) -> - lambda(getByName(name)) + val buildType = getByName(name) as BuildType + lambda(buildType) } } diff --git a/plugins/android/src/main/java/tools/forma/android/utils/ndk.kt b/plugins/android/src/main/java/tools/forma/android/utils/ndk.kt index 31338fe5..b04b6c1c 100644 --- a/plugins/android/src/main/java/tools/forma/android/utils/ndk.kt +++ b/plugins/android/src/main/java/tools/forma/android/utils/ndk.kt @@ -1,16 +1,17 @@ package tools.forma.android.utils +import com.android.build.api.dsl.CmakeFlags +import com.android.build.api.dsl.DefaultConfig import com.android.build.api.dsl.ExternalNativeBuild -import com.android.build.gradle.internal.dsl.DefaultConfig -import com.android.build.gradle.internal.dsl.ExternalNativeBuildOptions +import com.android.build.api.dsl.ExternalNativeBuildFlags +import com.android.build.api.dsl.NdkBuildFlags import tools.forma.android.config.CMake import tools.forma.android.config.NdkAbi -import tools.forma.android.config.NdkBuild +import tools.forma.android.config.NdkBuild as FormaNdkBuild internal fun DefaultConfig.applyFrom(abi: Set) { if (abi.isNotEmpty()) { - val result = abi.map(NdkAbi::abiName).toTypedArray() - ndk.abiFilters(*result) + ndk.abiFilters.addAll(abi.map(NdkAbi::abiName)) } } @@ -18,37 +19,43 @@ internal fun ExternalNativeBuild.applyFrom(cmake: CMake) { cmake { path = cmake.path version = cmake.version - cmake.buildStagingDirectory?.let(::buildStagingDirectory) + cmake.buildStagingDirectory?.let { buildStagingDirectory = it } } } -internal fun ExternalNativeBuild.applyFrom(ndkBuild: NdkBuild) { +internal fun ExternalNativeBuild.applyFrom(ndkBuild: FormaNdkBuild) { ndkBuild { path = ndkBuild.path - ndkBuild.buildStagingDirectory?.let(::buildStagingDirectory) + ndkBuild.buildStagingDirectory?.let { buildStagingDirectory = it } } } -internal fun ExternalNativeBuildOptions.applyFrom(cmake: CMake) { +internal fun ExternalNativeBuildFlags.applyFrom(cmake: CMake) { cmake { val opt = cmake.options arguments(*opt.arguments.toTypedArray()) cFlags(*opt.cflags.toTypedArray()) cppFlags(*opt.cppflags.toTypedArray()) - if (targets.isNotEmpty()) { + if (opt.targets.isNotEmpty()) { targets(*opt.targets.toTypedArray()) } } } -internal fun ExternalNativeBuildOptions.applyFrom(ndkBuild: NdkBuild) { +internal fun ExternalNativeBuildFlags.applyFrom(ndkBuild: FormaNdkBuild) { ndkBuild { val opt = ndkBuild.options arguments(*opt.arguments.toTypedArray()) cFlags(*opt.cflags.toTypedArray()) cppFlags(*opt.cppflags.toTypedArray()) - if (targets.isNotEmpty()) { + if (opt.targets.isNotEmpty()) { targets(*opt.targets.toTypedArray()) } } } + +// Keep type aliases so accidental imports of flags helpers stay clear +@Suppress("unused") +private typealias CmakeFlagsRef = CmakeFlags +@Suppress("unused") +private typealias NdkBuildFlagsRef = NdkBuildFlags diff --git a/plugins/config/src/main/java/tools/forma/config/AndroidProjectSettings.kt b/plugins/config/src/main/java/tools/forma/config/AndroidProjectSettings.kt index 99385f62..f28ea23c 100644 --- a/plugins/config/src/main/java/tools/forma/config/AndroidProjectSettings.kt +++ b/plugins/config/src/main/java/tools/forma/config/AndroidProjectSettings.kt @@ -40,7 +40,7 @@ data class AndroidProjectSettings( * Jetpack Compose compiler extension version applied when a target enables * Compose (`composeOptions.kotlinCompilerExtensionVersion`). Must match the * Kotlin version used by the project (see Compose Compiler compatibility map). - * Default `1.5.10` pairs with Kotlin **1.9.22** (Gradle 8.7 embedded Kotlin used + * Default `2.0.21` pairs with Kotlin **2.0.21** (Gradle 8.14.5 embedded Kotlin used * by the sample application). Override when bumping Kotlin. */ val composeCompilerVersion: String, diff --git a/plugins/gradle/wrapper/gradle-wrapper.properties b/plugins/gradle/wrapper/gradle-wrapper.properties index b82aa23a..4f5eb9dc 100644 --- a/plugins/gradle/wrapper/gradle-wrapper.properties +++ b/plugins/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/scripts/env-mac.sh b/scripts/env-mac.sh index 441c37a5..31decfdb 100755 --- a/scripts/env-mac.sh +++ b/scripts/env-mac.sh @@ -47,8 +47,11 @@ if [[ ! -x "$JAVA_HOME/bin/java" ]]; then return 1 2>/dev/null || exit 1 fi +if [[ ! -d "$ANDROID_HOME/platforms/android-35" ]]; then + echo "env-mac.sh: warning: Android platform 35 missing under $ANDROID_HOME (sample compileSdk)" >&2 +fi if [[ ! -d "$ANDROID_HOME/platforms/android-34" ]]; then - echo "env-mac.sh: warning: Android platform 34 missing under $ANDROID_HOME (sample compileSdk)" >&2 + echo "env-mac.sh: warning: Android platform 34 missing under $ANDROID_HOME" >&2 fi if [[ ! -d "$ANDROID_HOME/platforms/android-33" ]]; then echo "env-mac.sh: warning: Android platform 33 missing under $ANDROID_HOME" >&2 From 7d78bcac7c8b57ae676ac242d3d2b853ee5dc55b Mon Sep 17 00:00:00 2001 From: Claw Date: Sun, 19 Jul 2026 01:44:35 -0700 Subject: [PATCH 2/2] F-018: drop accidental .kotlin session artifact from PR --- .gitignore | 3 +++ .../sessions/kotlin-compiler-4509553605590117920.salive | 0 2 files changed, 3 insertions(+) delete mode 100644 application/.kotlin/sessions/kotlin-compiler-4509553605590117920.salive diff --git a/.gitignore b/.gitignore index f736444d..1afeaabc 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,6 @@ bazel-sample/bazel-* **/bazel-out **/bazel-testlogs **/.bazeliskrc + +.kotlin/ +**/.kotlin/ diff --git a/application/.kotlin/sessions/kotlin-compiler-4509553605590117920.salive b/application/.kotlin/sessions/kotlin-compiler-4509553605590117920.salive deleted file mode 100644 index e69de29b..00000000