Skip to content

Commit 038a635

Browse files
authored
Update Kotlin to 2.0.21, AGP to 8.8.1, Gradle to 8.14 (#720)
* Update Gradle to 8.14 * Update Kotlin to 2.0.21, AGP to 8.8.1 * Address breaking issues in Kotlin multiplatform example app * Use api discovery result in Kotlin example app * Update Gradle wrapper 8.14 to 'all' variant * Update wordpress.Dockerfile NDK version * Update Docker cached Gradle version to 8.14
1 parent 9edb495 commit 038a635

File tree

15 files changed

+96
-72
lines changed

15 files changed

+96
-72
lines changed

native/kotlin/api/kotlin/build.gradle.kts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ testing {
2323
}
2424

2525
register<JvmTestSuite>("integrationTest") {
26-
testType = TestSuiteType.INTEGRATION_TEST
27-
2826
sources {
2927
resources {
3028
setSrcDirs(

native/kotlin/build.gradle.kts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ plugins {
22
alias(libs.plugins.androidApplication) apply false
33
alias(libs.plugins.androidLibrary) apply false
44
alias(libs.plugins.jetbrainsCompose) apply false
5-
// TODO (Kotlin-2.0) - re-enable
6-
// alias(libs.plugins.compose.compiler) apply false
5+
alias(libs.plugins.compose.compiler) apply false
76
alias(libs.plugins.kotlinMultiplatform) apply false
87
alias(libs.plugins.kotlinJvm) apply false
98
alias(libs.plugins.kotlinSerialization) apply false

native/kotlin/example/composeApp/build.gradle.kts

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
11
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
2+
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
23

34
plugins {
45
alias(libs.plugins.kotlinMultiplatform)
56
alias(libs.plugins.androidApplication)
67
alias(libs.plugins.jetbrainsCompose)
7-
// TODO (Kotlin-2.0) - re-enable
8-
// alias(libs.plugins.compose.compiler)
8+
alias(libs.plugins.compose.compiler)
99
}
1010

11-
kotlin {
12-
androidTarget {
13-
// TODO (Kotlin-2.0) - re-enable
14-
// @OptIn(ExperimentalKotlinGradlePluginApi::class)
15-
// compilerOptions {
16-
// jvmTarget.set(JvmTarget.JVM_11)
17-
// }
18-
}
11+
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
12+
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
13+
14+
tasks.withType<KotlinJvmCompile>().configureEach {
15+
compilerOptions {
16+
jvmTarget.set(JvmTarget.JVM_11)
17+
freeCompilerArgs.add("-opt-in=kotlin.RequiresOptIn")
18+
}
19+
}
1920

21+
kotlin {
22+
androidTarget()
2023
jvm("desktop")
2124

2225
sourceSets {
@@ -88,22 +91,15 @@ android {
8891
}
8992
}
9093
compileOptions {
91-
// TODO (Kotlin-2.0) - Revert back to VERSION_11
92-
sourceCompatibility = JavaVersion.VERSION_17
93-
targetCompatibility = JavaVersion.VERSION_17
94+
sourceCompatibility = JavaVersion.VERSION_11
95+
targetCompatibility = JavaVersion.VERSION_11
9496
}
9597
buildFeatures {
9698
compose = true
9799
}
98100
dependencies {
99101
debugImplementation(compose.uiTooling)
100102
}
101-
// TODO (Kotlin-2.0) - Remove `composeOptions`
102-
composeOptions {
103-
// Once Kotlin is upgraded to >=2.0, this should be replaced with compose compiler plugin
104-
// https://developer.android.com/develop/ui/compose/compiler
105-
kotlinCompilerExtensionVersion = "1.5.14"
106-
}
107103
}
108104

109105
compose.desktop {

native/kotlin/example/composeApp/src/androidMain/kotlin/rs/wordpress/example/ui/welcome/WelcomeActivity.kt

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
package rs.wordpress.example.ui.welcome
22

33
import android.content.Intent
4-
import android.net.Uri
54
import android.os.Bundle
65
import androidx.activity.ComponentActivity
76
import androidx.activity.compose.setContent
87
import androidx.compose.runtime.Composable
98
import androidx.compose.ui.tooling.preview.Preview
109
import kotlinx.coroutines.runBlocking
1110
import org.koin.android.ext.android.inject
11+
import rs.wordpress.api.kotlin.ApiDiscoveryResult
1212
import rs.wordpress.api.kotlin.WpLoginClient
1313
import rs.wordpress.example.shared.App
1414
import rs.wordpress.example.shared.repository.AuthenticationRepository
15+
import androidx.core.net.toUri
16+
import uniffi.wp_api.AutoDiscoveryAttemptSuccess
1517

1618
class WelcomeActivity : ComponentActivity() {
1719
private val authRepository: AuthenticationRepository by inject()
20+
private var apiDiscoverySuccess: AutoDiscoveryAttemptSuccess? = null
1821

1922
override fun onCreate(savedInstanceState: Bundle?) {
2023
super.onCreate(savedInstanceState)
@@ -25,11 +28,14 @@ class WelcomeActivity : ComponentActivity() {
2528
}
2629

2730
private fun authenticateSite(url: String) {
28-
val authenticationUrl = runBlocking {
29-
WpLoginClient().apiDiscovery(url)
30-
.getOrThrow().applicationPasswordsAuthenticationUrl.url()
31+
val success = runBlocking {
32+
when (val apiDiscoveryResult = WpLoginClient().apiDiscovery(url)) {
33+
is ApiDiscoveryResult.Success -> apiDiscoveryResult.success
34+
else -> throw IllegalStateException("Api discovery should succeed for the example app")
35+
}
3136
}
32-
val uriBuilder = Uri.parse(authenticationUrl).buildUpon()
37+
val uriBuilder = success.applicationPasswordsAuthenticationUrl.url().toUri().buildUpon()
38+
apiDiscoverySuccess = success
3339

3440
uriBuilder
3541
.appendQueryParameter("app_name", "WordPressRsAndroidExample")
@@ -51,7 +57,14 @@ class WelcomeActivity : ComponentActivity() {
5157
val password = it.getQueryParameter("password")
5258

5359
if (siteUrl != null && username != null && password != null) {
54-
authRepository.addAuthenticatedSite(siteUrl, username, password)
60+
val discoverySuccess = apiDiscoverySuccess
61+
?: throw IllegalStateException("Api discovery has to be successful before authentication")
62+
authRepository.addAuthenticatedSite(
63+
discoverySuccess.parsedSiteUrl,
64+
discoverySuccess.apiRootUrl,
65+
username,
66+
password
67+
)
5568
onBackPressedDispatcher.onBackPressed()
5669
}
5770
}

native/kotlin/example/composeApp/src/commonMain/kotlin/rs/wordpress/example/shared/domain/AuthenticatedSite.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ package rs.wordpress.example.shared.domain
22

33
import uniffi.wp_api.ParsedUrl
44

5-
data class AuthenticatedSite(val name: String, val url: ParsedUrl)
5+
data class AuthenticatedSite(val name: String, val apiRootUrl: ParsedUrl)

native/kotlin/example/composeApp/src/commonMain/kotlin/rs/wordpress/example/shared/repository/AuthenticationRepository.kt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,17 @@ class AuthenticationRepository(
1313
private val authenticatedSites = mutableMapOf<AuthenticatedSite, WpAuthentication>()
1414

1515
init {
16-
addAuthenticatedSite(localTestSiteUrl, localTestSiteUsername, localTestSitePassword)
16+
addAuthenticatedSite(
17+
ParsedUrl.parse(localTestSiteUrl),
18+
ParsedUrl.parse("$localTestSiteUrl/wp-json"),
19+
localTestSiteUsername,
20+
localTestSitePassword
21+
)
1722
}
1823

19-
fun addAuthenticatedSite(siteUrl: String, username: String, password: String): Boolean {
20-
if (siteUrl.isNotEmpty() && username.isNotEmpty() && password.isNotEmpty()) {
21-
authenticatedSites[AuthenticatedSite(name = siteUrl, url = ParsedUrl.parse(siteUrl))] =
24+
fun addAuthenticatedSite(siteUrl: ParsedUrl, apiRootUrl: ParsedUrl, username: String, password: String): Boolean {
25+
if (username.isNotEmpty() && password.isNotEmpty()) {
26+
authenticatedSites[AuthenticatedSite(name = siteUrl.url(), apiRootUrl)] =
2227
wpAuthenticationFromUsernameAndPassword(username, password)
2328
return true
2429
}

native/kotlin/example/composeApp/src/commonMain/kotlin/rs/wordpress/example/shared/ui/login/LoginScreen.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ fun LoginScreen(authenticateSite: (String) -> Unit) {
2424
verticalArrangement = Arrangement.Center,
2525
modifier = Modifier.fillMaxSize(),
2626
) {
27-
var siteUrl by remember { mutableStateOf("boldly-inner.jurassic.ninja") }
27+
var siteUrl by remember { mutableStateOf("magnificent-funnel.jurassic.ninja") }
2828
TextField(value = siteUrl, onValueChange = { siteUrl = it })
2929
Button(onClick = { authenticateSite(siteUrl) }) {
3030
Text("Login")

native/kotlin/example/composeApp/src/commonMain/kotlin/rs/wordpress/example/shared/ui/plugins/PluginListViewModel.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,18 @@ import rs.wordpress.example.shared.domain.AuthenticatedSite
77
import rs.wordpress.example.shared.repository.AuthenticationRepository
88
import uniffi.wp_api.PluginListParams
99
import uniffi.wp_api.PluginWithEditContext
10+
import uniffi.wp_api.WpAuthenticationProvider
1011

1112
class PluginListViewModel(private val authRepository: AuthenticationRepository) {
1213
private var apiClient: WpApiClient? = null
1314

1415
fun setAuthenticatedSite(authenticatedSite: AuthenticatedSite) {
1516
apiClient = null
1617
authRepository.authenticationForSite(authenticatedSite)?.let {
17-
apiClient = WpApiClient(apiRootUrl = authenticatedSite.url, authentication = it)
18+
apiClient = WpApiClient(
19+
apiRootUrl = authenticatedSite.apiRootUrl,
20+
authProvider = WpAuthenticationProvider.staticWithAuth(it)
21+
)
1822
}
1923
}
2024

@@ -26,7 +30,7 @@ class PluginListViewModel(private val authRepository: AuthenticationRepository)
2630
}
2731
}
2832
return when (pluginsResult) {
29-
is WpRequestResult.WpRequestSuccess -> pluginsResult.data
33+
is WpRequestResult.WpRequestSuccess -> pluginsResult.data.data
3034
else -> listOf()
3135
}
3236
}

native/kotlin/example/composeApp/src/commonMain/kotlin/rs/wordpress/example/shared/ui/users/UserListViewModel.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,18 @@ import rs.wordpress.example.shared.domain.AuthenticatedSite
77
import rs.wordpress.example.shared.repository.AuthenticationRepository
88
import uniffi.wp_api.UserListParams
99
import uniffi.wp_api.UserWithEditContext
10+
import uniffi.wp_api.WpAuthenticationProvider
1011

1112
class UserListViewModel(private val authRepository: AuthenticationRepository) {
1213
private var apiClient: WpApiClient? = null
1314

1415
fun setAuthenticatedSite(authenticatedSite: AuthenticatedSite) {
1516
apiClient = null
1617
authRepository.authenticationForSite(authenticatedSite)?.let {
17-
apiClient = WpApiClient(apiRootUrl = authenticatedSite.url, authentication = it)
18+
apiClient = WpApiClient(
19+
apiRootUrl = authenticatedSite.apiRootUrl,
20+
authProvider = WpAuthenticationProvider.staticWithAuth(it)
21+
)
1822
}
1923
}
2024

@@ -26,8 +30,8 @@ class UserListViewModel(private val authRepository: AuthenticationRepository) {
2630
}
2731
}
2832
return when (usersResult) {
29-
is WpRequestResult.WpRequestSuccess -> usersResult.data
30-
else -> listOf()
33+
is WpRequestResult.WpRequestSuccess -> usersResult.data.data
34+
else -> throw IllegalStateException("User list request should succeed: $usersResult")
3135
}
3236
}
3337
return listOf()

native/kotlin/gradle/libs.versions.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[versions]
2-
agp = "8.3.2" # TODO (Kotlin-2.0) - update to latest
3-
android-compileSdk = "34"
2+
agp = "8.8.1"
3+
android-compileSdk = "36"
44
android-minSdk = "24"
55
android-targetSdk = "34"
66
androidx-activityCompose = "1.10.1"
@@ -13,8 +13,8 @@ detekt-plugin = "1.23.8"
1313
jna = "5.17.0"
1414
junit = "4.13.2"
1515
koin = "4.0.4"
16-
kotlin = "1.9.24"
17-
kotlinx-coroutines = "1.9.0"
16+
kotlin = "2.0.21"
17+
kotlinx-coroutines = "1.10.2"
1818
kotlinx-serialization-json = "1.6.3"
1919
landscapist = "2.4.7"
2020
lifecycle = "2.8.7"

0 commit comments

Comments
 (0)