Skip to content

Commit 4fb5b34

Browse files
committed
chore: update build dependencies and migrate to Gradle Version Catalog
- Migrated to Gradle Version Catalog (libs.versions.toml) - Updated Kotlin from 2.1.0 to 2.2.20 (IDEA compatibility) - Updated Gradle wrapper from 8.6 to 8.13.2 - Updated Android Gradle Plugin from 8.6.0 to 8.13.2 - Updated AndroidX Compose BOM to 2025.12.01 - Updated AndroidX Activity Compose to 1.12.2
1 parent 5ed7dcf commit 4fb5b34

23 files changed

Lines changed: 954 additions & 876 deletions

File tree

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
66
to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). All scales should have the 'format' parameter.
77

8+
## [Unreleased]
9+
10+
### Changed
11+
12+
- Migrated to Gradle Version Catalog (`libs.versions.toml`) for centralized dependency management
13+
- Updated Kotlin from 2.1.0 to 2.2.20
14+
- Updated Gradle wrapper from 8.6 to 8.13.2
15+
- Updated Android Gradle Plugin from 8.6.0 to 8.13.2
16+
- Updated AndroidX Compose BOM to 2025.12.01
17+
- Updated AndroidX Activity Compose to 1.12.2
18+
19+
### Internal
20+
21+
- Centralized version management in `gradle/libs.versions.toml`
22+
- Removed version declarations from `gradle.properties`
23+
- Updated all subproject build scripts to use version catalog references
24+
- Updated Gradle wrapper scripts and binary to 8.13.2
25+
826
## [3.0.2] - 2025-12-22
927

1028
### Compatibility

build.gradle.kts

Lines changed: 134 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -3,151 +3,168 @@
33
* Use of this source code is governed by the MIT license that can be found in the LICENSE file.
44
*/
55

6+
@file:Suppress("UnstableApiUsage")
67

7-
// okhttp3 added for publishing to the Sonatype Central Repository:
88
import okhttp3.MultipartBody
99
import okhttp3.OkHttpClient
1010
import okhttp3.Request
1111
import okhttp3.RequestBody.Companion.asRequestBody
12-
import java.util.*
12+
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
13+
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
14+
import org.jetbrains.kotlin.gradle.plugin.KotlinBasePlugin
15+
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
16+
import java.util.Base64
17+
import java.util.Properties
1318

14-
buildscript {
15-
dependencies {
16-
classpath("com.squareup.okhttp3:okhttp:4.12.0")
17-
}
18-
}
19+
buildscript { dependencies { classpath(libs.okhttp) } }
1920

2021
plugins {
21-
// this is necessary to avoid the plugins to be loaded multiple times
22-
// in each subproject's classloader
23-
kotlin("multiplatform").apply(false)
24-
kotlin("plugin.compose").apply(false)
25-
kotlin("jvm").apply(false)
26-
id("org.jetbrains.compose").apply(false)
27-
28-
kotlin("android").apply(false)
29-
id("com.android.application").apply(false)
30-
id("com.android.library").apply(false)
31-
32-
id("io.codearte.nexus-staging").apply(false)
33-
id("io.github.gradle-nexus.publish-plugin")
34-
}
35-
36-
val localProps = Properties()
37-
if (project.file("local.properties").exists()) {
38-
localProps.load(project.file("local.properties").inputStream())
39-
} else {
40-
error("Couldn't read local.properties")
22+
alias(libs.plugins.kotlin.multiplatform) apply false
23+
alias(libs.plugins.kotlin.compose.compiler) apply false
24+
alias(libs.plugins.kotlin.jvm) apply false
25+
alias(libs.plugins.kotlin.android) apply false
26+
alias(libs.plugins.android.application) apply false
27+
alias(libs.plugins.android.library) apply false
28+
alias(libs.plugins.kotlin.multiplatform.android.library) apply false
29+
alias(libs.plugins.nexus.staging) apply false
30+
alias(libs.plugins.nexus.publish)
4131
}
4232

43-
allprojects {
44-
group = "org.jetbrains.lets-plot"
45-
version = "3.0.3-SNAPSHOT"
46-
// version = "0.0.0-SNAPSHOT" // for local publishing only
33+
// =============================
34+
// Properties & Config
35+
// =============================
4736

48-
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().all {
49-
kotlinOptions {
50-
jvmTarget = "11"
51-
}
37+
val localProps =
38+
Properties().apply {
39+
val localPropertiesFile = rootProject.file("local.properties")
40+
if (localPropertiesFile.exists()) {
41+
load(localPropertiesFile.inputStream())
42+
}
5243
}
5344

54-
tasks.withType<JavaCompile>().all {
55-
sourceCompatibility = "11"
56-
targetCompatibility = "11"
57-
}
58-
}
45+
val javaVersion: String = libs.versions.java.get()
46+
val javaLanguageVersion: JavaLanguageVersion = JavaLanguageVersion.of(javaVersion)
5947

60-
// define the Maven Repository URL. Currently set to a local path for uploading
61-
// artifacts to the Sonatype Central Repository.
62-
val mavenReleasePublishUrl by extra { layout.buildDirectory.dir("maven/artifacts").get().toString() }
63-
// define Maven Snapshot repository URL.
64-
val mavenSnapshotPublishUrl by extra { "https://central.sonatype.com/repository/maven-snapshots/" }
48+
// =============================
49+
// Maven Publishing Config
50+
// =============================
6551

66-
// define Sonatype Central Repository settings:
52+
val mavenReleasePublishUrl by extra {
53+
layout.buildDirectory.dir("maven/artifacts").get().toString()
54+
}
55+
val mavenSnapshotPublishUrl by extra { "https://central.sonatype.com/repository/maven-snapshots/" }
6756
val sonatypeUsername by extra { localProps["sonatype.username"] ?: "" }
6857
val sonatypePassword by extra { localProps["sonatype.password"] ?: "" }
6958

70-
val packageMavenArtifacts by tasks.registering(Zip::class) {
59+
// =============================
60+
// All Projects Config
61+
// =============================
7162

72-
from(mavenReleasePublishUrl)
73-
archiveFileName.set("${project.name}-artifacts.zip")
74-
destinationDirectory.set(layout.buildDirectory)
63+
allprojects {
64+
group = "org.jetbrains.lets-plot"
65+
version = "3.0.3-SNAPSHOT"
7566
}
76-
val uploadMavenArtifacts by tasks.registering {
77-
dependsOn(packageMavenArtifacts)
78-
79-
doLast {
80-
val uriBase = "https://central.sonatype.com/api/v1/publisher/upload"
81-
val publishingType = "USER_MANAGED"
82-
val deploymentName = "${project.name}-$version"
83-
val uri = "$uriBase?name=$deploymentName&publishingType=$publishingType"
84-
85-
val userName = sonatypeUsername as String
86-
val password = sonatypePassword as String
87-
val base64Auth = Base64.getEncoder().encode("$userName:$password".toByteArray()).toString(Charsets.UTF_8)
88-
val bundleFile = packageMavenArtifacts.get().archiveFile.get().asFile
8967

90-
println("Sending request to $uri...")
91-
92-
val client = OkHttpClient()
93-
val request = Request.Builder()
94-
.url(uri)
95-
.header("Authorization", "Bearer $base64Auth")
96-
.post(
97-
MultipartBody.Builder()
98-
.setType(MultipartBody.FORM)
99-
.addFormDataPart("bundle", bundleFile.name, bundleFile.asRequestBody())
100-
.build()
101-
)
102-
.build()
103-
104-
client.newCall(request).execute().use { response ->
105-
val statusCode = response.code
106-
println("Upload status code: $statusCode")
107-
println("Upload result: ${response.body!!.string()}")
108-
if (statusCode != 201) {
109-
error("Upload error to Central repository. Status code $statusCode.")
110-
}
111-
}
68+
// =============================
69+
// Subprojects Config
70+
// =============================
71+
72+
subprojects {
73+
// Kotlin Configuration
74+
plugins.withType<KotlinBasePlugin> {
75+
extensions.configure<KotlinProjectExtension> {
76+
jvmToolchain { languageVersion.set(javaLanguageVersion) }
11277
}
78+
79+
tasks.withType<KotlinCompilationTask<*>>().configureEach {
80+
compilerOptions {
81+
apiVersion.set(KotlinVersion.KOTLIN_2_2)
82+
languageVersion.set(KotlinVersion.KOTLIN_2_2)
83+
allWarningsAsErrors.set(false)
84+
optIn.addAll("kotlin.RequiresOptIn", "kotlin.ExperimentalStdlibApi")
85+
freeCompilerArgs.addAll("-Xjsr305=strict")
86+
}
87+
}
88+
}
89+
90+
// Java Configuration
91+
plugins.withType<JavaPlugin> {
92+
tasks.withType<JavaCompile>().configureEach {
93+
sourceCompatibility = JavaVersion.toVersion(javaVersion).majorVersion
94+
targetCompatibility = JavaVersion.toVersion(javaVersion).majorVersion
95+
96+
options.apply {
97+
encoding = Charsets.UTF_8.name()
98+
isFork = true
99+
isIncremental = true
100+
}
101+
}
102+
}
103+
104+
// Javadoc JAR for publishing
105+
val jarJavaDocs by
106+
tasks.registering(Jar::class) {
107+
archiveClassifier.set("javadoc")
108+
group = "publishing"
109+
from(rootProject.file("README.md"))
110+
}
111+
112+
// Workaround for signing issue: https://github.com/gradle/gradle/issues/26091
113+
tasks.withType<AbstractPublishToMaven>().configureEach { mustRunAfter(tasks.withType<Sign>()) }
113114
}
114115

116+
// =============================
117+
// Publishing Tasks
118+
// =============================
119+
120+
val packageMavenArtifacts by
121+
tasks.registering(Zip::class) {
122+
group = "publishing"
123+
description = "Packages Maven artifacts for upload to Central Repository"
124+
from(mavenReleasePublishUrl)
125+
archiveFileName.set("${rootProject.name}-artifacts.zip")
126+
destinationDirectory.set(layout.buildDirectory)
127+
}
115128

116-
subprojects {
117-
repositories {
118-
mavenCentral()
119-
google()
120-
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
121-
122-
// Repositories where other projects publish their artifacts locally to.
123-
localProps["maven.repo.local"]?.let {
124-
(it as String).split(",").forEach { repo ->
125-
mavenLocal {
126-
url = uri(repo)
127-
}
128-
}
129+
val uploadMavenArtifacts by
130+
tasks.registering {
131+
group = "publishing"
132+
description = "Uploads Maven artifacts to Sonatype Central Repository"
133+
dependsOn(packageMavenArtifacts)
134+
135+
doLast {
136+
val uploadUrl = buildString {
137+
append("https://central.sonatype.com/api/v1/publisher/upload")
138+
append("?name=${rootProject.name}-$version")
139+
append("&publishingType=USER_MANAGED")
129140
}
130141

131-
// SNAPSHOTS
132-
maven(url = mavenSnapshotPublishUrl)
142+
val credentials = "$sonatypeUsername:$sonatypePassword"
143+
val base64Auth = Base64.getEncoder().encodeToString(credentials.toByteArray())
144+
val bundleFile = packageMavenArtifacts.get().archiveFile.get().asFile
133145

134-
mavenLocal()
135-
}
146+
logger.lifecycle("Uploading to: $uploadUrl")
136147

137-
val jarJavaDocs by tasks.creating(Jar::class) {
138-
archiveClassifier.set("javadoc")
139-
group = "lets plot"
140-
from("$rootDir/README.md")
141-
}
148+
val request =
149+
Request.Builder()
150+
.url(uploadUrl)
151+
.header("Authorization", "Bearer $base64Auth")
152+
.post(
153+
MultipartBody.Builder()
154+
.setType(MultipartBody.FORM)
155+
.addFormDataPart("bundle", bundleFile.name, bundleFile.asRequestBody())
156+
.build()
157+
)
158+
.build()
142159

143-
// ------------------------------------------
144-
// Workaround for the error when signing published artifacts.
145-
// It seems to appear after switching to Gradle 8.3
146-
// For details see: https://github.com/gradle/gradle/issues/26091 :
147-
// Publishing a KMP project with signing fails with "Task ... uses this output of task ... without declaring an explicit or implicit dependency"
148-
// https://github.com/gradle/gradle/issues/26091
149-
tasks.withType<AbstractPublishToMaven>().configureEach {
150-
val signingTasks = tasks.withType<Sign>()
151-
mustRunAfter(signingTasks)
160+
OkHttpClient().newCall(request).execute().use { response ->
161+
val statusCode = response.code
162+
val responseBody = response.body?.string() ?: ""
163+
164+
logger.lifecycle("Upload status: $statusCode")
165+
logger.lifecycle("Response: $responseBody")
166+
167+
check(statusCode == 201) { "Upload failed with status $statusCode: $responseBody" }
168+
}
169+
}
152170
}
153-
}

demo/plot/compose-android-median/build.gradle.kts

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@
44
*/
55

66
plugins {
7-
kotlin("android")
8-
id("com.android.application")
9-
kotlin("plugin.compose")
7+
alias(libs.plugins.android.application)
8+
alias(libs.plugins.kotlin.android)
9+
alias(libs.plugins.kotlin.compose.compiler)
1010
}
1111

12-
1312
android {
14-
compileSdk = (findProperty("android.compileSdk") as String).toInt()
13+
compileSdk = libs.versions.android.compileSdk.get().toInt()
1514
namespace = "demo.plot.CanvasDemo"
1615

1716
buildFeatures {
@@ -21,8 +20,8 @@ android {
2120
defaultConfig {
2221
applicationId = "demo.plot.CanvasDemo"
2322

24-
minSdk = (findProperty("android.minSdk") as String).toInt()
25-
targetSdk = (findProperty("android.targetSdk") as String).toInt()
23+
minSdk = libs.versions.android.minSdk.get().toInt()
24+
targetSdk = libs.versions.android.compileSdk.get().toInt()
2625

2726
versionCode = 1
2827
versionName = "1.0"
@@ -35,31 +34,26 @@ android {
3534
}
3635

3736
compileOptions {
38-
sourceCompatibility = JavaVersion.VERSION_11
39-
targetCompatibility = JavaVersion.VERSION_11
37+
sourceCompatibility = JavaVersion.VERSION_21
38+
targetCompatibility = JavaVersion.VERSION_21
4039
}
4140

4241
kotlin {
43-
jvmToolchain(11)
42+
jvmToolchain(21)
4443
}
4544
}
4645

47-
val androidComposeBom = extra["androidx.compose.bom"] as String
48-
val androidxActivityCompose = extra["androidx.activity.compose"] as String
49-
val letsPlotVersion = extra["letsPlot.version"] as String
50-
val letsPlotKotlinVersion = extra["letsPlotKotlin.version"] as String
51-
5246
dependencies {
53-
implementation(platform("androidx.compose:compose-bom:$androidComposeBom"))
54-
implementation("androidx.compose.ui:ui")
55-
implementation("androidx.compose.material:material")
56-
implementation("androidx.activity:activity-compose:$androidxActivityCompose")
57-
58-
implementation("org.jetbrains.lets-plot:lets-plot-kotlin-kernel:$letsPlotKotlinVersion")
59-
implementation("org.jetbrains.lets-plot:lets-plot-common:$letsPlotVersion")
60-
implementation("org.jetbrains.lets-plot:canvas:$letsPlotVersion")
61-
implementation("org.jetbrains.lets-plot:plot-raster:$letsPlotVersion")
62-
63-
implementation(project(":lets-plot-compose"))
64-
implementation(project(":demo-plot-shared"))
47+
implementation(project.dependencies.platform(libs.androidx.compose.bom))
48+
implementation(libs.androidx.compose.ui)
49+
implementation(libs.androidx.compose.material)
50+
implementation(libs.androidx.activity.compose)
51+
52+
implementation(libs.letsplot.kotlin.kernel)
53+
implementation(libs.letsplot.common)
54+
implementation(libs.letsplot.canvas)
55+
implementation(libs.letsplot.plot.raster)
56+
57+
implementation(projects.letsPlotCompose)
58+
implementation(projects.demo.plot.shared)
6559
}

0 commit comments

Comments
 (0)