diff --git a/CHANGELOG.md b/CHANGELOG.md index e5f16e34..9afc4379 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). All scales should have the 'format' parameter. +## [Unreleased] + +### Changed + +- Migrated to Gradle Version Catalog (`libs.versions.toml`) for centralized dependency management +- Updated Kotlin from 2.1.0 to 2.2.20 +- 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 + +### Internal + +- Centralized version management in `gradle/libs.versions.toml` +- Removed version declarations from `gradle.properties` +- Updated all subproject build scripts to use version catalog references +- Updated Gradle wrapper scripts and binary to 8.13.2 + ## [3.0.2] - 2025-12-22 ### Compatibility diff --git a/build.gradle.kts b/build.gradle.kts index 037c6e65..e1dcecab 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,151 +3,168 @@ * Use of this source code is governed by the MIT license that can be found in the LICENSE file. */ +@file:Suppress("UnstableApiUsage") -// okhttp3 added for publishing to the Sonatype Central Repository: import okhttp3.MultipartBody import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.RequestBody.Companion.asRequestBody -import java.util.* +import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension +import org.jetbrains.kotlin.gradle.dsl.KotlinVersion +import org.jetbrains.kotlin.gradle.plugin.KotlinBasePlugin +import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask +import java.util.Base64 +import java.util.Properties -buildscript { - dependencies { - classpath("com.squareup.okhttp3:okhttp:4.12.0") - } -} +buildscript { dependencies { classpath(libs.okhttp) } } plugins { - // this is necessary to avoid the plugins to be loaded multiple times - // in each subproject's classloader - kotlin("multiplatform").apply(false) - kotlin("plugin.compose").apply(false) - kotlin("jvm").apply(false) - id("org.jetbrains.compose").apply(false) - - kotlin("android").apply(false) - id("com.android.application").apply(false) - id("com.android.library").apply(false) - - id("io.codearte.nexus-staging").apply(false) - id("io.github.gradle-nexus.publish-plugin") -} - -val localProps = Properties() -if (project.file("local.properties").exists()) { - localProps.load(project.file("local.properties").inputStream()) -} else { - error("Couldn't read local.properties") + alias(libs.plugins.kotlin.multiplatform) apply false + alias(libs.plugins.kotlin.compose.compiler) apply false + alias(libs.plugins.kotlin.jvm) apply false + alias(libs.plugins.kotlin.android) apply false + alias(libs.plugins.android.application) apply false + alias(libs.plugins.android.library) apply false + alias(libs.plugins.kotlin.multiplatform.android.library) apply false + alias(libs.plugins.nexus.staging) apply false + alias(libs.plugins.nexus.publish) } -allprojects { - group = "org.jetbrains.lets-plot" - version = "3.0.3-SNAPSHOT" -// version = "0.0.0-SNAPSHOT" // for local publishing only +// ============================= +// Properties & Config +// ============================= - tasks.withType().all { - kotlinOptions { - jvmTarget = "11" - } +val localProps = + Properties().apply { + val localPropertiesFile = rootProject.file("local.properties") + if (localPropertiesFile.exists()) { + load(localPropertiesFile.inputStream()) + } } - tasks.withType().all { - sourceCompatibility = "11" - targetCompatibility = "11" - } -} +val javaVersion: String = libs.versions.java.get() +val javaLanguageVersion: JavaLanguageVersion = JavaLanguageVersion.of(javaVersion) -// define the Maven Repository URL. Currently set to a local path for uploading -// artifacts to the Sonatype Central Repository. -val mavenReleasePublishUrl by extra { layout.buildDirectory.dir("maven/artifacts").get().toString() } -// define Maven Snapshot repository URL. -val mavenSnapshotPublishUrl by extra { "https://central.sonatype.com/repository/maven-snapshots/" } +// ============================= +// Maven Publishing Config +// ============================= -// define Sonatype Central Repository settings: +val mavenReleasePublishUrl by extra { + layout.buildDirectory.dir("maven/artifacts").get().toString() +} +val mavenSnapshotPublishUrl by extra { "https://central.sonatype.com/repository/maven-snapshots/" } val sonatypeUsername by extra { localProps["sonatype.username"] ?: "" } val sonatypePassword by extra { localProps["sonatype.password"] ?: "" } -val packageMavenArtifacts by tasks.registering(Zip::class) { +// ============================= +// All Projects Config +// ============================= - from(mavenReleasePublishUrl) - archiveFileName.set("${project.name}-artifacts.zip") - destinationDirectory.set(layout.buildDirectory) +allprojects { + group = "org.jetbrains.lets-plot" + version = "3.0.3-SNAPSHOT" } -val uploadMavenArtifacts by tasks.registering { - dependsOn(packageMavenArtifacts) - - doLast { - val uriBase = "https://central.sonatype.com/api/v1/publisher/upload" - val publishingType = "USER_MANAGED" - val deploymentName = "${project.name}-$version" - val uri = "$uriBase?name=$deploymentName&publishingType=$publishingType" - - val userName = sonatypeUsername as String - val password = sonatypePassword as String - val base64Auth = Base64.getEncoder().encode("$userName:$password".toByteArray()).toString(Charsets.UTF_8) - val bundleFile = packageMavenArtifacts.get().archiveFile.get().asFile - println("Sending request to $uri...") - - val client = OkHttpClient() - val request = Request.Builder() - .url(uri) - .header("Authorization", "Bearer $base64Auth") - .post( - MultipartBody.Builder() - .setType(MultipartBody.FORM) - .addFormDataPart("bundle", bundleFile.name, bundleFile.asRequestBody()) - .build() - ) - .build() - - client.newCall(request).execute().use { response -> - val statusCode = response.code - println("Upload status code: $statusCode") - println("Upload result: ${response.body!!.string()}") - if (statusCode != 201) { - error("Upload error to Central repository. Status code $statusCode.") - } - } +// ============================= +// Subprojects Config +// ============================= + +subprojects { + // Kotlin Configuration + plugins.withType { + extensions.configure { + jvmToolchain { languageVersion.set(javaLanguageVersion) } } + + tasks.withType>().configureEach { + compilerOptions { + apiVersion.set(KotlinVersion.KOTLIN_2_2) + languageVersion.set(KotlinVersion.KOTLIN_2_2) + allWarningsAsErrors.set(false) + optIn.addAll("kotlin.RequiresOptIn", "kotlin.ExperimentalStdlibApi") + freeCompilerArgs.addAll("-Xjsr305=strict") + } + } + } + + // Java Configuration + plugins.withType { + tasks.withType().configureEach { + sourceCompatibility = JavaVersion.toVersion(javaVersion).majorVersion + targetCompatibility = JavaVersion.toVersion(javaVersion).majorVersion + + options.apply { + encoding = Charsets.UTF_8.name() + isFork = true + isIncremental = true + } + } + } + + // Javadoc JAR for publishing + val jarJavaDocs by + tasks.registering(Jar::class) { + archiveClassifier.set("javadoc") + group = "publishing" + from(rootProject.file("README.md")) + } + + // Workaround for signing issue: https://github.com/gradle/gradle/issues/26091 + tasks.withType().configureEach { mustRunAfter(tasks.withType()) } } +// ============================= +// Publishing Tasks +// ============================= + +val packageMavenArtifacts by + tasks.registering(Zip::class) { + group = "publishing" + description = "Packages Maven artifacts for upload to Central Repository" + from(mavenReleasePublishUrl) + archiveFileName.set("${rootProject.name}-artifacts.zip") + destinationDirectory.set(layout.buildDirectory) + } -subprojects { - repositories { - mavenCentral() - google() - maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") - - // Repositories where other projects publish their artifacts locally to. - localProps["maven.repo.local"]?.let { - (it as String).split(",").forEach { repo -> - mavenLocal { - url = uri(repo) - } - } +val uploadMavenArtifacts by + tasks.registering { + group = "publishing" + description = "Uploads Maven artifacts to Sonatype Central Repository" + dependsOn(packageMavenArtifacts) + + doLast { + val uploadUrl = buildString { + append("https://central.sonatype.com/api/v1/publisher/upload") + append("?name=${rootProject.name}-$version") + append("&publishingType=USER_MANAGED") } - // SNAPSHOTS - maven(url = mavenSnapshotPublishUrl) + val credentials = "$sonatypeUsername:$sonatypePassword" + val base64Auth = Base64.getEncoder().encodeToString(credentials.toByteArray()) + val bundleFile = packageMavenArtifacts.get().archiveFile.get().asFile - mavenLocal() - } + logger.lifecycle("Uploading to: $uploadUrl") - val jarJavaDocs by tasks.creating(Jar::class) { - archiveClassifier.set("javadoc") - group = "lets plot" - from("$rootDir/README.md") - } + val request = + Request.Builder() + .url(uploadUrl) + .header("Authorization", "Bearer $base64Auth") + .post( + MultipartBody.Builder() + .setType(MultipartBody.FORM) + .addFormDataPart("bundle", bundleFile.name, bundleFile.asRequestBody()) + .build() + ) + .build() - // ------------------------------------------ - // Workaround for the error when signing published artifacts. - // It seems to appear after switching to Gradle 8.3 - // For details see: https://github.com/gradle/gradle/issues/26091 : - // Publishing a KMP project with signing fails with "Task ... uses this output of task ... without declaring an explicit or implicit dependency" - // https://github.com/gradle/gradle/issues/26091 - tasks.withType().configureEach { - val signingTasks = tasks.withType() - mustRunAfter(signingTasks) + OkHttpClient().newCall(request).execute().use { response -> + val statusCode = response.code + val responseBody = response.body?.string() ?: "" + + logger.lifecycle("Upload status: $statusCode") + logger.lifecycle("Response: $responseBody") + + check(statusCode == 201) { "Upload failed with status $statusCode: $responseBody" } + } + } } -} diff --git a/demo/plot/compose-android-median/build.gradle.kts b/demo/plot/compose-android-median/build.gradle.kts index c60dac99..69387732 100644 --- a/demo/plot/compose-android-median/build.gradle.kts +++ b/demo/plot/compose-android-median/build.gradle.kts @@ -4,14 +4,13 @@ */ plugins { - kotlin("android") - id("com.android.application") - kotlin("plugin.compose") + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.compose.compiler) } - android { - compileSdk = (findProperty("android.compileSdk") as String).toInt() + compileSdk = libs.versions.android.compileSdk.get().toInt() namespace = "demo.plot.CanvasDemo" buildFeatures { @@ -21,8 +20,8 @@ android { defaultConfig { applicationId = "demo.plot.CanvasDemo" - minSdk = (findProperty("android.minSdk") as String).toInt() - targetSdk = (findProperty("android.targetSdk") as String).toInt() + minSdk = libs.versions.android.minSdk.get().toInt() + targetSdk = libs.versions.android.compileSdk.get().toInt() versionCode = 1 versionName = "1.0" @@ -35,31 +34,26 @@ android { } compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 } kotlin { - jvmToolchain(11) + jvmToolchain(21) } } -val androidComposeBom = extra["androidx.compose.bom"] as String -val androidxActivityCompose = extra["androidx.activity.compose"] as String -val letsPlotVersion = extra["letsPlot.version"] as String -val letsPlotKotlinVersion = extra["letsPlotKotlin.version"] as String - dependencies { - implementation(platform("androidx.compose:compose-bom:$androidComposeBom")) - implementation("androidx.compose.ui:ui") - implementation("androidx.compose.material:material") - implementation("androidx.activity:activity-compose:$androidxActivityCompose") - - implementation("org.jetbrains.lets-plot:lets-plot-kotlin-kernel:$letsPlotKotlinVersion") - implementation("org.jetbrains.lets-plot:lets-plot-common:$letsPlotVersion") - implementation("org.jetbrains.lets-plot:canvas:$letsPlotVersion") - implementation("org.jetbrains.lets-plot:plot-raster:$letsPlotVersion") - - implementation(project(":lets-plot-compose")) - implementation(project(":demo-plot-shared")) + implementation(project.dependencies.platform(libs.androidx.compose.bom)) + implementation(libs.androidx.compose.ui) + implementation(libs.androidx.compose.material) + implementation(libs.androidx.activity.compose) + + implementation(libs.letsplot.kotlin.kernel) + implementation(libs.letsplot.common) + implementation(libs.letsplot.canvas) + implementation(libs.letsplot.plot.raster) + + implementation(projects.letsPlotCompose) + implementation(projects.demo.plot.shared) } diff --git a/demo/plot/compose-android-min/build.gradle.kts b/demo/plot/compose-android-min/build.gradle.kts index fc2bb51d..1d203c3e 100644 --- a/demo/plot/compose-android-min/build.gradle.kts +++ b/demo/plot/compose-android-min/build.gradle.kts @@ -4,14 +4,13 @@ */ plugins { - kotlin("android") - id("com.android.application") - kotlin("plugin.compose") + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.compose.compiler) } - android { - compileSdk = (findProperty("android.compileSdk") as String).toInt() + compileSdk = libs.versions.android.compileSdk.get().toInt() namespace = "demo.plot.CanvasDemo" buildFeatures { @@ -21,8 +20,8 @@ android { defaultConfig { applicationId = "demo.plot.CanvasDemo" - minSdk = (findProperty("android.minSdk") as String).toInt() - targetSdk = (findProperty("android.targetSdk") as String).toInt() + minSdk = libs.versions.android.minSdk.get().toInt() + targetSdk = libs.versions.android.compileSdk.get().toInt() versionCode = 1 versionName = "1.0" @@ -35,33 +34,27 @@ android { } compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 } kotlin { - jvmToolchain(11) + jvmToolchain(21) } } -val androidComposeBom = extra["androidx.compose.bom"] as String -val androidxActivityCompose = extra["androidx.activity.compose"] as String -val letsPlotVersion = extra["letsPlot.version"] as String -val letsPlotKotlinVersion = extra["letsPlotKotlin.version"] as String - dependencies { - implementation(platform("androidx.compose:compose-bom:$androidComposeBom")) - implementation("androidx.activity:activity-compose:$androidxActivityCompose") - implementation("androidx.compose.material3:material3") - implementation("androidx.compose.ui:ui") - - implementation("org.jetbrains.lets-plot:lets-plot-kotlin-kernel:$letsPlotKotlinVersion") - implementation("org.jetbrains.lets-plot:lets-plot-common:$letsPlotVersion") - implementation("org.jetbrains.lets-plot:plot-stem:$letsPlotVersion") - implementation("org.jetbrains.lets-plot:canvas:$letsPlotVersion") - implementation("org.jetbrains.lets-plot:plot-raster:$letsPlotVersion") - - implementation(project(":lets-plot-compose")) - implementation(project(":demo-plot-shared")) - + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.androidx.activity.compose) + implementation(libs.androidx.compose.material3) + implementation(libs.androidx.compose.ui) + + implementation(libs.letsplot.kotlin.kernel) + implementation(libs.letsplot.common) + implementation(libs.letsplot.plot.stem) + implementation(libs.letsplot.canvas) + implementation(libs.letsplot.plot.raster) + + implementation(projects.letsPlotCompose) + implementation(projects.demo.plot.shared) } diff --git a/demo/plot/compose-android-redraw/build.gradle.kts b/demo/plot/compose-android-redraw/build.gradle.kts index 5401af58..42fb33d3 100644 --- a/demo/plot/compose-android-redraw/build.gradle.kts +++ b/demo/plot/compose-android-redraw/build.gradle.kts @@ -4,14 +4,13 @@ */ plugins { - kotlin("android") - id("com.android.application") - kotlin("plugin.compose") + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.compose.compiler) } - android { - compileSdk = (findProperty("android.compileSdk") as String).toInt() + compileSdk = libs.versions.android.compileSdk.get().toInt() namespace = "demo.letsPlot" buildFeatures { @@ -21,8 +20,8 @@ android { defaultConfig { applicationId = "demo.letsPlot.composeMinDemo" - minSdk = (findProperty("android.minSdk") as String).toInt() - targetSdk = (findProperty("android.targetSdk") as String).toInt() + minSdk = libs.versions.android.minSdk.get().toInt() + targetSdk = libs.versions.android.compileSdk.get().toInt() versionCode = 1 versionName = "1.0" @@ -38,32 +37,26 @@ android { } compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 } kotlin { - jvmToolchain(11) + jvmToolchain(21) } } -val androidComposeBom = extra["androidx.compose.bom"] as String -val androidxActivityCompose = extra["androidx.activity.compose"] as String -val letsPlotVersion = extra["letsPlot.version"] as String -val letsPlotKotlinVersion = extra["letsPlotKotlin.version"] as String - dependencies { - implementation(platform("androidx.compose:compose-bom:$androidComposeBom")) - implementation("androidx.compose.ui:ui") - implementation("androidx.compose.material:material") - implementation("androidx.activity:activity-compose:$androidxActivityCompose") - - implementation("org.jetbrains.lets-plot:lets-plot-kotlin-kernel:$letsPlotKotlinVersion") - implementation("org.jetbrains.lets-plot:lets-plot-common:$letsPlotVersion") - - implementation("org.jetbrains.lets-plot:canvas:$letsPlotVersion") - implementation("org.jetbrains.lets-plot:plot-raster:$letsPlotVersion") - - implementation(project(":lets-plot-compose")) - implementation(project(":demo-plot-shared")) + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.androidx.compose.ui) + implementation(libs.androidx.compose.material) + implementation(libs.androidx.activity.compose) + + implementation(libs.letsplot.kotlin.kernel) + implementation(libs.letsplot.common) + implementation(libs.letsplot.canvas) + implementation(libs.letsplot.plot.raster) + + implementation(projects.letsPlotCompose) + implementation(projects.demo.plot.shared) } diff --git a/demo/plot/compose-desktop/build.gradle.kts b/demo/plot/compose-desktop/build.gradle.kts index 33ccf8fb..73a90c06 100644 --- a/demo/plot/compose-desktop/build.gradle.kts +++ b/demo/plot/compose-desktop/build.gradle.kts @@ -1,24 +1,20 @@ plugins { -// kotlin("multiplatform") // kotlin("jvm") doesn't work well in IDEA/AndroidStudio (https://github.com/JetBrains/compose-jb/issues/22) - kotlin("jvm") - kotlin("plugin.compose") - id("org.jetbrains.compose") + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.kotlin.compose.compiler) + alias(libs.plugins.kotlin.compose.multiplatform) } -val letsPlotVersion = extra["letsPlot.version"] as String -val letsPlotKotlinVersion = extra["letsPlotKotlin.version"] as String - dependencies { implementation(compose.desktop.currentOs) implementation(compose.components.resources) - implementation("org.jetbrains.lets-plot:lets-plot-kotlin-kernel:$letsPlotKotlinVersion") - implementation("org.jetbrains.lets-plot:lets-plot-common:$letsPlotVersion") - implementation("org.jetbrains.lets-plot:canvas:$letsPlotVersion") - implementation("org.jetbrains.lets-plot:plot-raster:$letsPlotVersion") + implementation(libs.letsplot.kotlin.kernel) + implementation(libs.letsplot.common) + implementation(libs.letsplot.canvas) + implementation(libs.letsplot.plot.raster) - implementation(project(":lets-plot-compose")) - implementation(project(":demo-plot-shared")) + implementation(projects.letsPlotCompose) + implementation(projects.demo.plot.shared) - implementation("org.slf4j:slf4j-simple:2.0.9") // Enable logging to console + implementation(libs.slf4j.simple) // Enable logging to console } diff --git a/demo/plot/shared/build.gradle.kts b/demo/plot/shared/build.gradle.kts index 043e5c0e..21b963d9 100644 --- a/demo/plot/shared/build.gradle.kts +++ b/demo/plot/shared/build.gradle.kts @@ -4,17 +4,13 @@ */ plugins { - kotlin("jvm") + alias(libs.plugins.kotlin.jvm) } -val letsPlotVersion = extra["letsPlot.version"] as String -val letsPlotKotlinVersion = extra["letsPlotKotlin.version"] as String - dependencies { - compileOnly("org.jetbrains.lets-plot:lets-plot-kotlin-kernel:$letsPlotKotlinVersion") - - compileOnly("org.jetbrains.lets-plot:commons:$letsPlotVersion") - compileOnly("org.jetbrains.lets-plot:datamodel:$letsPlotVersion") - - testImplementation(kotlin("test")) + compileOnly(libs.letsplot.kotlin.kernel) + compileOnly(libs.letsplot.commons) + compileOnly(libs.letsplot.datamodel) + + testImplementation(libs.kotlin.test) } diff --git a/demo/plot/swing/build.gradle.kts b/demo/plot/swing/build.gradle.kts index bbd1d4c8..79aefb50 100644 --- a/demo/plot/swing/build.gradle.kts +++ b/demo/plot/swing/build.gradle.kts @@ -1,24 +1,21 @@ plugins { - kotlin("jvm") - kotlin("plugin.compose") - id("org.jetbrains.compose") + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.kotlin.compose.compiler) + alias(libs.plugins.kotlin.compose.multiplatform) } -val letsPlotVersion = extra["letsPlot.version"] as String -val letsPlotKotlinVersion = extra["letsPlotKotlin.version"] as String - dependencies { implementation(compose.desktop.currentOs) compileOnly(compose.ui) - implementation("org.jetbrains.lets-plot:lets-plot-kotlin-kernel:$letsPlotKotlinVersion") - implementation("org.jetbrains.lets-plot:lets-plot-common:$letsPlotVersion") - implementation("org.jetbrains.lets-plot:platf-awt:$letsPlotVersion") - implementation("org.jetbrains.lets-plot:canvas:$letsPlotVersion") - implementation("org.jetbrains.lets-plot:plot-raster:$letsPlotVersion") + implementation(libs.letsplot.kotlin.kernel) + implementation(libs.letsplot.common) + implementation(libs.letsplot.platf.awt) + implementation(libs.letsplot.canvas) + implementation(libs.letsplot.plot.raster) - implementation(project(":lets-plot-compose")) - implementation(project(":demo-plot-shared")) + implementation(projects.letsPlotCompose) + implementation(projects.demo.plot.shared) - implementation("org.slf4j:slf4j-simple:2.0.17") // Enable logging to console + implementation(libs.slf4j.simple) // Enable logging to console } diff --git a/demo/svg/compose-desktop/build.gradle.kts b/demo/svg/compose-desktop/build.gradle.kts index e8466782..fc52d75e 100644 --- a/demo/svg/compose-desktop/build.gradle.kts +++ b/demo/svg/compose-desktop/build.gradle.kts @@ -1,19 +1,14 @@ -//import org.jetbrains.compose.desktop.application.dsl.TargetFormat - plugins { -// kotlin("multiplatform") // kotlin("jvm") doesn't work well in IDEA/AndroidStudio (https://github.com/JetBrains/compose-jb/issues/22) - kotlin("jvm") - kotlin("plugin.compose") - id("org.jetbrains.compose") + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.kotlin.compose.compiler) + alias(libs.plugins.kotlin.compose.multiplatform) } -val letsPlotVersion = extra["letsPlot.version"] as String - dependencies { implementation(compose.desktop.currentOs) - implementation("org.jetbrains.lets-plot:lets-plot-common:$letsPlotVersion") + implementation(libs.letsplot.common) - implementation(project(":lets-plot-compose")) - implementation(project(":demo-svg-shared")) + implementation(projects.letsPlotCompose) + implementation(projects.demo.svg.shared) } diff --git a/demo/svg/shared/build.gradle.kts b/demo/svg/shared/build.gradle.kts index cc9e3332..52485b26 100644 --- a/demo/svg/shared/build.gradle.kts +++ b/demo/svg/shared/build.gradle.kts @@ -4,17 +4,14 @@ */ plugins { - kotlin("jvm") + alias(libs.plugins.kotlin.jvm) } -val kotlinLoggingVersion = extra["kotlinLogging.version"] as String -val letsPlotVersion = extra["letsPlot.version"] as String - dependencies { - implementation("io.github.microutils:kotlin-logging-jvm:$kotlinLoggingVersion") + implementation(libs.kotlin.logging.jvm) - compileOnly("org.jetbrains.lets-plot:commons:$letsPlotVersion") - compileOnly("org.jetbrains.lets-plot:datamodel:$letsPlotVersion") + compileOnly(libs.letsplot.commons) + compileOnly(libs.letsplot.datamodel) - testImplementation(kotlin("test")) + testImplementation(libs.kotlin.test) } diff --git a/demo/svg/swing/build.gradle.kts b/demo/svg/swing/build.gradle.kts index 66675a85..8f5a0fc8 100644 --- a/demo/svg/swing/build.gradle.kts +++ b/demo/svg/swing/build.gradle.kts @@ -1,17 +1,15 @@ plugins { - kotlin("jvm") - kotlin("plugin.compose") - id("org.jetbrains.compose") + alias(libs.plugins.kotlin.jvm) + alias(libs.plugins.kotlin.compose.compiler) + alias(libs.plugins.kotlin.compose.multiplatform) } -val letsPlotVersion = extra["letsPlot.version"] as String - dependencies { implementation(compose.desktop.currentOs) compileOnly(compose.ui) - implementation("org.jetbrains.lets-plot:lets-plot-common:$letsPlotVersion") + implementation(libs.letsplot.common) - implementation(project(":lets-plot-compose")) - implementation(project(":demo-svg-shared")) + implementation(projects.letsPlotCompose) + implementation(projects.demo.svg.shared) } diff --git a/demo/view/android-plot-view/build.gradle.kts b/demo/view/android-plot-view/build.gradle.kts index 1e619a8c..f1cbb435 100644 --- a/demo/view/android-plot-view/build.gradle.kts +++ b/demo/view/android-plot-view/build.gradle.kts @@ -4,23 +4,22 @@ */ plugins { - kotlin("android") - id("com.android.application") + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) } android { - compileSdk = (findProperty("android.compileSdk") as String).toInt() + compileSdk = libs.versions.android.compileSdk.get().toInt() namespace = "demo.plot.view" defaultConfig { applicationId = "demo.plot.view" - minSdk = (findProperty("android.minSdk") as String).toInt() - targetSdk = (findProperty("android.targetSdk") as String).toInt() + minSdk = libs.versions.android.minSdk.get().toInt() + targetSdk = libs.versions.android.compileSdk.get().toInt() versionCode = 1 versionName = "1.0" - } buildTypes { @@ -30,23 +29,20 @@ android { } compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 } kotlin { - jvmToolchain(11) + jvmToolchain(21) } } -val letsPlotVersion = extra["letsPlot.version"] as String -val letsPlotKotlinVersion = extra["letsPlotKotlin.version"] as String - dependencies { - implementation(project(":platf-android")) - implementation(project(":demo-plot-shared")) - implementation("org.jetbrains.lets-plot:lets-plot-kotlin-kernel:${letsPlotKotlinVersion}") - implementation("org.jetbrains.lets-plot:lets-plot-common:$letsPlotVersion") - implementation("org.jetbrains.lets-plot:canvas:$letsPlotVersion") - implementation("org.jetbrains.lets-plot:plot-raster:$letsPlotVersion") + implementation(projects.platfAndroid) + implementation(projects.demo.plot.shared) + implementation(libs.letsplot.kotlin.kernel) + implementation(libs.letsplot.common) + implementation(libs.letsplot.canvas) + implementation(libs.letsplot.plot.raster) } diff --git a/demo/view/android-svg-view/build.gradle.kts b/demo/view/android-svg-view/build.gradle.kts index f0d9f159..414292b1 100644 --- a/demo/view/android-svg-view/build.gradle.kts +++ b/demo/view/android-svg-view/build.gradle.kts @@ -4,19 +4,19 @@ */ plugins { - kotlin("android") - id("com.android.application") + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) } android { - compileSdk = (findProperty("android.compileSdk") as String).toInt() + compileSdk = libs.versions.android.compileSdk.get().toInt() namespace = "demo.svg.view" defaultConfig { applicationId = "demo.svg.view" - minSdk = (findProperty("android.minSdk") as String).toInt() - targetSdk = (findProperty("android.targetSdk") as String).toInt() + minSdk = libs.versions.android.minSdk.get().toInt() + targetSdk = libs.versions.android.compileSdk.get().toInt() versionCode = 1 versionName = "1.0" @@ -29,21 +29,19 @@ android { } compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 } kotlin { - jvmToolchain(11) + jvmToolchain(21) } } -val letsPlotVersion = extra["letsPlot.version"] as String - dependencies { - implementation(project(":platf-android")) - implementation(project(":demo-svg-shared")) - implementation("org.jetbrains.lets-plot:lets-plot-common:$letsPlotVersion") - implementation("org.jetbrains.lets-plot:canvas:$letsPlotVersion") - implementation("org.jetbrains.lets-plot:plot-raster:$letsPlotVersion") + implementation(projects.platfAndroid) + implementation(projects.demo.svg.shared) + implementation(libs.letsplot.common) + implementation(libs.letsplot.canvas) + implementation(libs.letsplot.plot.raster) } diff --git a/gradle.properties b/gradle.properties index 2ef825e2..2776b83d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,6 @@ org.gradle.jvmargs=-Xmx4096M -Dkotlin.daemon.jvm.options=-Xmx2096M #Kotlin -kotlin.version=2.1.0 kotlin.code.style=official #MPP @@ -14,35 +13,4 @@ kotlin.mpp.androidSourceSetLayoutVersion=2 org.jetbrains.compose.experimental.uikit.enabled=true #Android -kotlin.android.version=2.1.0 -agp.version=8.6.0 android.useAndroidX=true -android.compileSdk=35 -android.targetSdk=34 -android.minSdk=24 -androidx.compose.bom=2025.08.00 -androidx.activity.compose=1.10.1 - -#Versions - -# Beware of the versions in IDEA platform -# The list of 3rd party libraries used in the IDEA platform: https://www.jetbrains.com/legal/third-party-software/?product=IIU - -# KMP is not compatible with AGP 8.3 yet. -compose.version=1.9.3 -# Skiko version should be compatible with Compose version -# Check skiko in the Compose version here (change the version in the URL as needed): -# https://repo1.maven.org/maven2/org/jetbrains/compose/ui/ui-desktop/1.8.2/ui-desktop-1.8.2.pom -skiko.version=0.9.22.2 - -letsPlot.version=4.8.2 - -letsPlotKotlin.version=4.12.1 - -nexusStaging.version=0.30.0 -nexusPublish.version=1.3.0 - -kotlinLogging.version=2.0.5 -assertj.version=3.12.2 -junit.version=1.1.5 -espresso.core.version=3.5.1 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 00000000..40437a0f --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,128 @@ +[versions] +# ==================================================================================== +# DEPENDENCY COMPATIBILITY NOTES +# ==================================================================================== +# +# IDEA Platform Compatibility: +# Before updating major dependencies, verify compatibility with IntelliJ IDEA. +# Reference: https://www.jetbrains.com/legal/third-party-software/?product=IIU +# +# Skiko <-> Compose Version Compatibility: +# Skiko version must be compatible with the Compose Multiplatform version. +# Check Compose's Skiko dependency at: +# https://repo1.maven.org/maven2/org/jetbrains/compose/ui/ui-desktop/{version}/ui-desktop-{version}.pom +# +# AGP Version Considerations: +# Kotlin Multiplatform had historical compatibility issues with AGP 8.3+. +# Current version (8.13.2) should be verified with Android builds. +# +# ==================================================================================== + +# Java +java = "21" + +# Kotlin & Compose +junitJupiter = "6.0.1" +kotlin = "2.2.20" +compose = "1.9.3" +mockk = "1.14.7" +skiko = "0.9.22.2" + +# Android +agp = "8.13.2" +android-compileSdk = "36" +android-minSdk = "24" +androidx-compose-bom = "2025.12.01" +androidx-activity-compose = "1.12.2" + +# Lets-Plot +lets-plot = "4.8.2" +lets-plot-kotlin = "4.12.1" + +# Publishing +nexusStaging = "0.30.0" +nexusPublish = "2.0.0" + +# Logging & Testing +kotlinLogging = "3.0.5" +assertj = "3.27.6" +junit = "4.13.2" +androidx-test-junit = "1.3.0" +espressoCore = "3.7.0" +slf4j = "2.0.17" +okhttp = "5.3.2" + +androidx-activity = "1.11.0" +androidx-appcompat = "1.7.1" +androidx-core = "1.17.0" +androidx-espresso = "3.7.0" +androidx-lifecycle = "2.9.6" +androidx-testExt = "1.3.0" +composeHotReload = "1.0.0" +composeMultiplatform = "1.9.3" +kotlinx-coroutines = "1.10.2" +kotlinx-datetime = "0.6.2" + +[libraries] +junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junitJupiter" } +kotlinx-coroutinesSwing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "kotlinx-coroutines" } +kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-datetime" } +kotlinx-datetime-jvm = { module = "org.jetbrains.kotlinx:kotlinx-datetime-jvm", version.ref = "kotlinx-datetime" } +kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } +kotlin-testJunit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlin" } +junit = { module = "junit:junit", version.ref = "junit" } + +# Lets-Plot +lets-plot-image-export = { module = "org.jetbrains.lets-plot:lets-plot-image-export", version.ref = "lets-plot" } +letsplot-kotlin-kernel = { module = "org.jetbrains.lets-plot:lets-plot-kotlin-kernel", version.ref = "lets-plot-kotlin" } +letsplot-common = { module = "org.jetbrains.lets-plot:lets-plot-common", version.ref = "lets-plot" } +letsplot-commons = { module = "org.jetbrains.lets-plot:commons", version.ref = "lets-plot" } +letsplot-datamodel = { module = "org.jetbrains.lets-plot:datamodel", version.ref = "lets-plot" } +letsplot-canvas = { module = "org.jetbrains.lets-plot:canvas", version.ref = "lets-plot" } +letsplot-plot-base = { module = "org.jetbrains.lets-plot:plot-base", version.ref = "lets-plot" } +letsplot-plot-builder = { module = "org.jetbrains.lets-plot:plot-builder", version.ref = "lets-plot" } +letsplot-plot-stem = { module = "org.jetbrains.lets-plot:plot-stem", version.ref = "lets-plot" } +letsplot-plot-raster = { module = "org.jetbrains.lets-plot:plot-raster", version.ref = "lets-plot" } +letsplot-platf-awt = { module = "org.jetbrains.lets-plot:platf-awt", version.ref = "lets-plot" } + +# Skiko +mockk = { module = "io.mockk:mockk", version.ref = "mockk" } +skiko = { module = "org.jetbrains.skiko:skiko", version.ref = "skiko" } + +# AndroidX +androidx-compose-bom = { module = "androidx.compose:compose-bom", version.ref = "androidx-compose-bom" } +androidx-compose-ui = { module = "androidx.compose.ui:ui" } +androidx-compose-ui-graphics = { module = "androidx.compose.ui:ui-graphics" } +androidx-compose-material = { module = "androidx.compose.material:material" } +androidx-compose-material3 = { module = "androidx.compose.material3:material3" } +androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity-compose" } +androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidx-core" } +androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" } +androidx-lifecycle-viewmodelCompose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "androidx-lifecycle" } +androidx-lifecycle-runtimeCompose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-runtime-compose", version.ref = "androidx-lifecycle" } + +# Testing +androidx-test-junit = { module = "androidx.test.ext:junit", version.ref = "androidx-test-junit" } +androidx-test-espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "espressoCore" } +assertj-core = { module = "org.assertj:assertj-core", version.ref = "assertj" } + +# Logging +kotlin-logging-jvm = { module = "io.github.microutils:kotlin-logging-jvm", version.ref = "kotlinLogging" } +kotlin-logging = { module = "io.github.microutils:kotlin-logging", version.ref = "kotlinLogging" } +slf4j-simple = { module = "org.slf4j:slf4j-simple", version.ref = "slf4j" } + +# Build +okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" } + +[plugins] +kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } +kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlin-compose-hotReload = { id = "org.jetbrains.compose.hot-reload", version.ref = "composeHotReload" } +kotlin-compose-multiplatform = { id = "org.jetbrains.compose", version.ref = "composeMultiplatform" } +kotlin-compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } +kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } +kotlin-multiplatform-android-library = { id = "com.android.kotlin.multiplatform.library", version.ref = "agp" } +android-application = { id = "com.android.application", version.ref = "agp" } +android-library = { id = "com.android.library", version.ref = "agp" } +nexus-staging = { id = "io.codearte.nexus-staging", version.ref = "nexusStaging" } +nexus-publish = { id = "io.github.gradle-nexus.publish-plugin", version.ref = "nexusPublish" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e708b1c0..f8e1ee31 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 5c82cb03..23449a2b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 4f906e0c..adff685a 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,81 +15,114 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -98,88 +131,118 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=`expr $i + 1` + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 107acd32..c4bdd3ab 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,8 +13,10 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +27,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,13 +43,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -56,32 +59,33 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/lets-plot-compose/build.gradle.kts b/lets-plot-compose/build.gradle.kts index 021bcbc9..949c1758 100644 --- a/lets-plot-compose/build.gradle.kts +++ b/lets-plot-compose/build.gradle.kts @@ -4,98 +4,63 @@ */ plugins { - kotlin("multiplatform") - kotlin("plugin.compose") - id("com.android.library") - id("org.jetbrains.compose") + alias(libs.plugins.kotlin.multiplatform.android.library) + alias(libs.plugins.kotlin.multiplatform) + alias(libs.plugins.kotlin.compose.compiler) + alias(libs.plugins.kotlin.compose.multiplatform) `maven-publish` signing } -val androidComposeBom = extra["androidx.compose.bom"] as String -val skikoVersion = extra["skiko.version"] as String -val letsPlotVersion = extra["letsPlot.version"] as String -val letsPlotKotlinVersion = extra["letsPlotKotlin.version"] as String -val kotlinLoggingVersion = extra["kotlinLogging.version"] as String - kotlin { - jvm("desktop") { - compilations.all { - kotlinOptions.jvmTarget = "11" - } - } + jvm("desktop") - androidTarget { - publishLibraryVariants("release") + androidLibrary { + namespace = "org.jetbrains.letsPlot.compose" + compileSdk = libs.versions.android.compileSdk.get().toInt() + minSdk = libs.versions.android.minSdk.get().toInt() } sourceSets { - named("commonMain") { + commonMain { dependencies { compileOnly(compose.runtime) compileOnly(compose.ui) compileOnly(compose.foundation) - compileOnly("org.jetbrains.lets-plot:lets-plot-kotlin-kernel:$letsPlotKotlinVersion") - compileOnly("org.jetbrains.lets-plot:lets-plot-common:$letsPlotVersion") - compileOnly("org.jetbrains.lets-plot:plot-raster:$letsPlotVersion") - compileOnly("org.jetbrains.lets-plot:canvas:$letsPlotVersion") + compileOnly(libs.letsplot.kotlin.kernel) + compileOnly(libs.letsplot.common) + compileOnly(libs.letsplot.plot.raster) + compileOnly(libs.letsplot.canvas) + implementation(libs.kotlinx.datetime) } } - named("desktopMain") { + val desktopMain by getting { dependencies { compileOnly(compose.runtime) compileOnly(compose.ui) compileOnly(compose.desktop.currentOs) compileOnly(compose.components.resources) - compileOnly("org.jetbrains.skiko:skiko:${skikoVersion}") - api(project(":platf-skia")) - compileOnly("io.github.microutils:kotlin-logging-jvm:$kotlinLoggingVersion") + compileOnly(libs.skiko) + api(projects.platfSkia) + compileOnly(libs.kotlin.logging.jvm) } } - named("androidMain") { + val androidMain by getting { dependencies { - implementation(project.dependencies.platform("androidx.compose:compose-bom:$androidComposeBom")) - implementation("androidx.compose.ui:ui") - implementation("androidx.compose.ui:ui-graphics") - api(project(":platf-android")) - compileOnly("org.jetbrains.lets-plot:plot-raster:$letsPlotVersion") - compileOnly("org.jetbrains.lets-plot:canvas:$letsPlotVersion") + implementation(project.dependencies.platform(libs.androidx.compose.bom)) + implementation(libs.androidx.compose.ui) + implementation(libs.androidx.compose.ui.graphics) + api(projects.platfAndroid) + compileOnly(libs.letsplot.plot.raster) + compileOnly(libs.letsplot.canvas) } } } } -android { - namespace = "org.jetbrains.letsPlot.compose" - - compileSdk = (findProperty("android.compileSdk") as String).toInt() - - sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") - - defaultConfig { - minSdk = (findProperty("android.minSdk") as String).toInt() - } - - buildTypes { - getByName("release") { - isMinifyEnabled = false // true - error: when compiling demo cant resolve classes -// proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") - } - } - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } - - kotlin { - jvmToolchain(11) - } -} - /////////////////////////////////////////////// // Publishing @@ -133,7 +98,7 @@ afterEvaluate { repositories { mavenLocal { - url = uri("$rootDir/.maven-publish-dev-repo") + url = rootDir.resolve(".maven-publish-dev-repo").toURI() } maven { // For SNAPSHOT publication use separate URL and credentials: @@ -156,4 +121,4 @@ signing { if (!(project.version as String).contains("SNAPSHOT")) { sign(publishing.publications) } -} \ No newline at end of file +} diff --git a/platf-android/build.gradle.kts b/platf-android/build.gradle.kts index fa3f18a4..4c993ba1 100644 --- a/platf-android/build.gradle.kts +++ b/platf-android/build.gradle.kts @@ -5,241 +5,226 @@ import java.io.ByteArrayOutputStream import java.io.FileInputStream -import java.util.* +import java.util.Properties plugins { - kotlin("multiplatform") - id("com.android.library") - `maven-publish` - signing + alias(libs.plugins.kotlin.multiplatform.android.library) + alias(libs.plugins.kotlin.multiplatform) + `maven-publish` + signing } -val letsPlotVersion = extra["letsPlot.version"] as String -val assertjVersion = extra["assertj.version"] as String -val junitVersion = extra["junit.version"] as String -val espressoCoreVersion = extra["espresso.core.version"] as String - kotlin { - jvm { - compilations.all { - kotlinOptions.jvmTarget = "11" - } - } + jvm() - androidTarget { - publishLibraryVariants("release") + androidLibrary { + namespace = "org.jetbrains.letsPlot.android.canvas" + compileSdk = libs.versions.android.compileSdk.get().toInt() + minSdk = libs.versions.android.minSdk.get().toInt() + + withDeviceTest { + instrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } - sourceSets { - named("androidMain") { - dependencies { - compileOnly("org.jetbrains.lets-plot:commons:$letsPlotVersion") - compileOnly("org.jetbrains.lets-plot:datamodel:$letsPlotVersion") - compileOnly("org.jetbrains.lets-plot:canvas:$letsPlotVersion") - compileOnly("org.jetbrains.lets-plot:plot-base:$letsPlotVersion") - compileOnly("org.jetbrains.lets-plot:plot-builder:$letsPlotVersion") - compileOnly("org.jetbrains.lets-plot:plot-stem:$letsPlotVersion") - compileOnly("org.jetbrains.lets-plot:plot-raster:$letsPlotVersion") - } - } +// publishing { +// singleVariant("release") +// } + } + + sourceSets { + androidMain { + dependencies { + compileOnly(libs.letsplot.commons) + compileOnly(libs.letsplot.datamodel) + compileOnly(libs.letsplot.canvas) + compileOnly(libs.letsplot.plot.base) + compileOnly(libs.letsplot.plot.builder) + compileOnly(libs.letsplot.plot.stem) + compileOnly(libs.letsplot.plot.raster) + } + } - named("androidInstrumentedTest") { - dependencies { - implementation(kotlin("test")) - implementation("androidx.test.ext:junit:$junitVersion") - implementation("androidx.test.espresso:espresso-core:$espressoCoreVersion") - - implementation("org.assertj:assertj-core:$assertjVersion") - implementation("org.jetbrains.lets-plot:commons:$letsPlotVersion") - implementation("org.jetbrains.lets-plot:datamodel:$letsPlotVersion") - implementation("org.jetbrains.lets-plot:canvas:$letsPlotVersion") - implementation("org.jetbrains.lets-plot:plot-base:$letsPlotVersion") - implementation("org.jetbrains.lets-plot:plot-builder:$letsPlotVersion") - implementation("org.jetbrains.lets-plot:plot-stem:$letsPlotVersion") - implementation("org.jetbrains.lets-plot:plot-raster:$letsPlotVersion") - } - } + androidInstrumentedTest { + dependencies { + implementation(libs.kotlin.test) + implementation(libs.androidx.test.junit) + implementation(libs.androidx.test.espresso.core) + + implementation(libs.assertj.core) + implementation(libs.letsplot.commons) + implementation(libs.letsplot.datamodel) + implementation(libs.letsplot.canvas) + implementation(libs.letsplot.plot.base) + implementation(libs.letsplot.plot.builder) + implementation(libs.letsplot.plot.stem) + implementation(libs.letsplot.plot.raster) + } } + } } -android { - namespace = "org.jetbrains.letsPlot.android.canvas" - compileSdk = (findProperty("android.compileSdk") as String).toInt() +abstract class PullDebugImagesTask : DefaultTask() { + @get:Inject abstract val execOperations: ExecOperations - sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") + @get:Input abstract val projectDir: Property - defaultConfig { - minSdk = (findProperty("android.minSdk") as String).toInt() - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - } + @get:Input abstract val rootProjectDir: Property - buildTypes { - getByName("release") { - isMinifyEnabled = false // true - error: when compiling demo cant resolve classes -// proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") - } - } + @TaskAction + fun execute() { + val destDir = File(projectDir.get(), "build/test-results/") + destDir.mkdirs() - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + // 1. Load local.properties + val localProperties = Properties() + val localPropertiesFile = File(rootProjectDir.get(), "local.properties") + if (localPropertiesFile.exists()) { + FileInputStream(localPropertiesFile).use { fis -> localProperties.load(fis) } } - kotlin { - jvmToolchain(11) + // 2. Get sdk.dir from local.properties + val sdkDir = + localProperties.getProperty("sdk.dir") + ?: System.getenv("ANDROID_HOME") + ?: System.getProperty("android.home") + if (sdkDir == null) { + throw GradleException( + "sdk.dir not found in local.properties and ANDROID_HOME or android.home not set" + ) } -} - -tasks.register("pullDebugImages") { - doLast { - val destDir = File(projectDir, "build/test-results/") - destDir.mkdirs() - - // 1. Load local.properties - val localProperties = Properties() - val localPropertiesFile = File(rootProject.projectDir, "local.properties") - if (localPropertiesFile.exists()) { - FileInputStream(localPropertiesFile).use { fis -> - localProperties.load(fis) - } - } - // 2. Get sdk.dir from local.properties - val sdkDir = localProperties.getProperty("sdk.dir") ?: System.getenv("ANDROID_HOME") - ?: System.getProperty("android.home") - if (sdkDir == null) { - throw GradleException("sdk.dir not found in local.properties and ANDROID_HOME or android.home not set") - } - - // 3. Construct adb executable path - val adbPath = "$sdkDir/platform-tools/adb" - val adbFile = File(adbPath) - if (!adbFile.exists()) { - throw GradleException("adb not found at $adbPath") - } - val adbExecutable = adbFile.absolutePath - - // Get the list of connected devices using adb devices - val adbDevicesOutput = ByteArrayOutputStream() - exec { - commandLine(adbExecutable, "devices", "-l") - standardOutput = adbDevicesOutput - isIgnoreExitValue = true - } + // 3. Construct adb executable path + val adbPath = "$sdkDir/platform-tools/adb" + val adbFile = File(adbPath) + if (!adbFile.exists()) { + throw GradleException("adb not found at $adbPath") + } + val adbExecutable = adbFile.absolutePath + + // Get the list of connected devices using adb devices + val adbDevicesOutput = ByteArrayOutputStream() + execOperations.exec { + commandLine(adbExecutable, "devices", "-l") + standardOutput = adbDevicesOutput + isIgnoreExitValue = true + } - val devicesOutput = adbDevicesOutput.toString() + val devicesOutput = adbDevicesOutput.toString() - val devices = devicesOutput.reader().readLines() + val devices = + devicesOutput + .reader() + .readLines() .drop(1) // Skip the header line .filter { it.isNotBlank() && !it.startsWith("* daemon") } // Remove empty lines .map { it.split("\\s+".toRegex())[0] } - if (devices.isEmpty()) { - println("No connected Android devices found.") - return@doLast - } - - devices.forEach { deviceSerial -> - println("Pulling images from device: $deviceSerial") - - //The directory on device to pull from - val devicePicturesDir = - "/storage/emulated/0/Android/data/org.jetbrains.letsPlot.android.canvas.test/files/Pictures/" - //The local directory to initially pull the images to - val tempLocalDir = File(destDir, "temp_pictures") - if (tempLocalDir.exists()) { - tempLocalDir.deleteRecursively() - } - tempLocalDir.mkdirs() - - // Pull the images from the device to the temporary directory - exec { - commandLine( - adbExecutable, - "-s", - deviceSerial, - "pull", - devicePicturesDir, - tempLocalDir.absolutePath - ) - } - - val tempPicturesDir = File(tempLocalDir, "Pictures") - val diffImagesDir = File(destDir, "/diff_images/") - if (diffImagesDir.exists()) { - diffImagesDir.deleteRecursively() - } - diffImagesDir.mkdirs() + if (devices.isEmpty()) { + println("No connected Android devices found.") + return + } - //Move files from temporary dir to destination dir - tempPicturesDir.listFiles()?.forEach { file -> - file.copyTo(File(diffImagesDir, file.name)) - } - //Delete temporary dir - tempLocalDir.deleteRecursively() - } + devices.forEach { deviceSerial -> + println("Pulling images from device: $deviceSerial") + + // The directory on device to pull from + val devicePicturesDir = + "/storage/emulated/0/Android/data/org.jetbrains.letsPlot.android.canvas.test/files/Pictures/" + // The local directory to initially pull the images to + val tempLocalDir = File(destDir, "temp_pictures") + if (tempLocalDir.exists()) { + tempLocalDir.deleteRecursively() + } + tempLocalDir.mkdirs() + + // Pull the images from the device to the temporary directory + execOperations.exec { + commandLine( + adbExecutable, + "-s", + deviceSerial, + "pull", + devicePicturesDir, + tempLocalDir.absolutePath, + ) + } + + val tempPicturesDir = File(tempLocalDir, "Pictures") + val diffImagesDir = File(destDir, "/diff_images/") + if (diffImagesDir.exists()) { + diffImagesDir.deleteRecursively() + } + diffImagesDir.mkdirs() + + // Move files from temporary dir to destination dir + tempPicturesDir.listFiles()?.forEach { file -> file.copyTo(File(diffImagesDir, file.name)) } + // Delete temporary dir + tempLocalDir.deleteRecursively() } + } } +tasks.register("pullDebugImages") { + projectDir.set(project.projectDir) + rootProjectDir.set(project.rootProject.projectDir) +} /////////////////////////////////////////////// // Publishing /////////////////////////////////////////////// afterEvaluate { - publishing { - publications.forEach { pub -> - with(pub as MavenPublication) { - artifact(tasks.jarJavaDocs) - - pom { - name.set("Lets-Plot Compose - Android") - description.set("Android drawing for Lets-Plot Compose plotting library.") - url.set("https://github.com/JetBrains/lets-plot-compose") - licenses { - license { - name.set("MIT") - url.set("https://raw.githubusercontent.com/JetBrains/lets-plot-compose/master/LICENSE") - } - } - developers { - developer { - id.set("jetbrains") - name.set("JetBrains") - email.set("lets-plot@jetbrains.com") - } - } - scm { - url.set("https://github.com/JetBrains/lets-plot-compose") - } - } + publishing { + publications.forEach { pub -> + with(pub as MavenPublication) { + artifact(tasks.jarJavaDocs) + + pom { + name.set("Lets-Plot Compose - Android") + description.set("Android drawing for Lets-Plot Compose plotting library.") + url.set("https://github.com/JetBrains/lets-plot-compose") + licenses { + license { + name.set("MIT") + url.set( + "https://raw.githubusercontent.com/JetBrains/lets-plot-compose/master/LICENSE" + ) + } + } + developers { + developer { + id.set("jetbrains") + name.set("JetBrains") + email.set("lets-plot@jetbrains.com") } + } + scm { url.set("https://github.com/JetBrains/lets-plot-compose") } } + } + } - repositories { - mavenLocal { - url = uri("$rootDir/.maven-publish-dev-repo") - } - maven { - // For SNAPSHOT publication use separate URL and credentials: - if (version.toString().endsWith("-SNAPSHOT")) { - url = uri(rootProject.project.extra["mavenSnapshotPublishUrl"].toString()) - - credentials { - username = rootProject.project.extra["sonatypeUsername"].toString() - password = rootProject.project.extra["sonatypePassword"].toString() - } - } else { - url = uri(rootProject.project.extra["mavenReleasePublishUrl"].toString()) - } - } + repositories { + mavenLocal { url = uri("$rootDir/.maven-publish-dev-repo") } + maven { + // For SNAPSHOT publication use separate URL and credentials: + if (version.toString().endsWith("-SNAPSHOT")) { + url = uri(rootProject.project.extra["mavenSnapshotPublishUrl"].toString()) + + credentials { + username = rootProject.project.extra["sonatypeUsername"].toString() + password = rootProject.project.extra["sonatypePassword"].toString() + } + } else { + url = uri(rootProject.project.extra["mavenReleasePublishUrl"].toString()) } + } } + } } signing { - if (!(project.version as String).contains("SNAPSHOT")) { - sign(publishing.publications) - } -} \ No newline at end of file + if (!(project.version as String).contains("SNAPSHOT")) { + sign(publishing.publications) + } +} diff --git a/platf-skia/build.gradle.kts b/platf-skia/build.gradle.kts index 58ce6554..fd2e859d 100644 --- a/platf-skia/build.gradle.kts +++ b/platf-skia/build.gradle.kts @@ -4,115 +4,99 @@ */ plugins { - kotlin("multiplatform") - `maven-publish` - signing + alias(libs.plugins.kotlin.multiplatform) + `maven-publish` + signing } -val skikoVersion = extra["skiko.version"] as String -val letsPlotVersion = extra["letsPlot.version"] as String -val kotlinLoggingVersion = extra["kotlinLogging.version"] as String -val assertjVersion = extra["assertj.version"] as String - kotlin { - jvm { - compilations.all { - kotlinOptions.jvmTarget = "11" - } - } + jvm() - sourceSets { - commonMain { - dependencies { - compileOnly("org.jetbrains.skiko:skiko:$skikoVersion") + sourceSets { + commonMain { + dependencies { + compileOnly(libs.skiko) - compileOnly("org.jetbrains.lets-plot:commons:$letsPlotVersion") - compileOnly("org.jetbrains.lets-plot:datamodel:$letsPlotVersion") - compileOnly("org.jetbrains.lets-plot:plot-base:$letsPlotVersion") - compileOnly("org.jetbrains.lets-plot:plot-stem:$letsPlotVersion") - compileOnly("org.jetbrains.lets-plot:plot-builder:$letsPlotVersion") - compileOnly("org.jetbrains.lets-plot:plot-raster:$letsPlotVersion") - compileOnly("org.jetbrains.lets-plot:canvas:$letsPlotVersion") - } - } + compileOnly(libs.letsplot.commons) + compileOnly(libs.letsplot.datamodel) + compileOnly(libs.letsplot.plot.base) + compileOnly(libs.letsplot.plot.stem) + compileOnly(libs.letsplot.plot.builder) + compileOnly(libs.letsplot.plot.raster) + compileOnly(libs.letsplot.canvas) + } + } - named("jvmMain") { - dependencies { - compileOnly("io.github.microutils:kotlin-logging-jvm:$kotlinLoggingVersion") - } - } + jvmMain { dependencies { compileOnly(libs.kotlin.logging.jvm) } } - named("jvmTest") { - dependencies { - implementation(kotlin("test")) - implementation("org.assertj:assertj-core:$assertjVersion") - implementation("org.jetbrains.skiko:skiko:$skikoVersion") - implementation("org.jetbrains.lets-plot:commons:$letsPlotVersion") - implementation("org.jetbrains.lets-plot:datamodel:$letsPlotVersion") - implementation("io.github.microutils:kotlin-logging:$kotlinLoggingVersion") - } - } + jvmTest { + dependencies { + implementation(libs.kotlin.test) + implementation(libs.assertj.core) + implementation(libs.skiko) + implementation(libs.letsplot.commons) + implementation(libs.letsplot.datamodel) + implementation(libs.kotlin.logging) + } } + } } - /////////////////////////////////////////////// // Publishing /////////////////////////////////////////////// afterEvaluate { - publishing { - publications.forEach { pub -> - with(pub as MavenPublication) { - artifact(tasks.jarJavaDocs) + publishing { + publications.forEach { pub -> + with(pub as MavenPublication) { + artifact(tasks.jarJavaDocs) - pom { - name.set("Lets-Plot Compose - Skia") - description.set("Skia drawing for Lets-Plot Compose plotting library.") - url.set("https://github.com/JetBrains/lets-plot-compose") - licenses { - license { - name.set("MIT") - url.set("https://raw.githubusercontent.com/JetBrains/lets-plot-compose/master/LICENSE") - } - } - developers { - developer { - id.set("jetbrains") - name.set("JetBrains") - email.set("lets-plot@jetbrains.com") - } - } - scm { - url.set("https://github.com/JetBrains/lets-plot-compose") - } - } + pom { + name.set("Lets-Plot Compose - Skia") + description.set("Skia drawing for Lets-Plot Compose plotting library.") + url.set("https://github.com/JetBrains/lets-plot-compose") + licenses { + license { + name.set("MIT") + url.set( + "https://raw.githubusercontent.com/JetBrains/lets-plot-compose/master/LICENSE" + ) } + } + developers { + developer { + id.set("jetbrains") + name.set("JetBrains") + email.set("lets-plot@jetbrains.com") + } + } + scm { url.set("https://github.com/JetBrains/lets-plot-compose") } } + } + } - repositories { - mavenLocal { - url = uri("$rootDir/.maven-publish-dev-repo") - } - maven { - // For SNAPSHOT publication use separate URL and credentials: - if (version.toString().endsWith("-SNAPSHOT")) { - url = uri(rootProject.project.extra["mavenSnapshotPublishUrl"].toString()) + repositories { + mavenLocal { url = rootDir.resolve(".maven-publish-dev-repo").toURI() } + maven { + // For SNAPSHOT publication use separate URL and credentials: + if (version.toString().endsWith("-SNAPSHOT")) { + url = uri(rootProject.project.extra["mavenSnapshotPublishUrl"].toString()) - credentials { - username = rootProject.project.extra["sonatypeUsername"].toString() - password = rootProject.project.extra["sonatypePassword"].toString() - } - } else { - url = uri(rootProject.project.extra["mavenReleasePublishUrl"].toString()) - } - } + credentials { + username = rootProject.project.extra["sonatypeUsername"].toString() + password = rootProject.project.extra["sonatypePassword"].toString() + } + } else { + url = uri(rootProject.project.extra["mavenReleasePublishUrl"].toString()) } + } } + } } signing { - if (!(project.version as String).contains("SNAPSHOT")) { - sign(publishing.publications) - } -} \ No newline at end of file + if (!(project.version as String).contains("SNAPSHOT")) { + sign(publishing.publications) + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 8acac974..b10f40cc 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,80 +1,71 @@ -pluginManagement { - repositories { - gradlePluginPortal() - mavenCentral() - google() - maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") - } +/* + * Copyright (c) 2023. JetBrains s.r.o. + * Use of this source code is governed by the MIT license that can be found in the LICENSE file. + */ - plugins { - val kotlinVersion = extra["kotlin.version"] as String - val composeVersion = extra["compose.version"] as String - val agpVersion = extra["agp.version"] as String - val nexusStagingVersion = extra["nexusStaging.version"] as String - val nexusPublishVersion = extra["nexusPublish.version"] as String +@file:Suppress("UnstableApiUsage") - kotlin("jvm").version(kotlinVersion) - kotlin("multiplatform").version(kotlinVersion) - kotlin("plugin.compose").version(kotlinVersion) - id("org.jetbrains.compose").version(composeVersion) +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") - kotlin("android").version(kotlinVersion) - id("com.android.application").version(agpVersion) - id("com.android.library").version(agpVersion) +rootProject.name = "lets-plot-compose-root" - id("io.codearte.nexus-staging") version nexusStagingVersion - id("io.github.gradle-nexus.publish-plugin") version nexusPublishVersion - } +pluginManagement { + repositories { + gradlePluginPortal() + mavenCentral() + google() + maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") + } } -include("lets-plot-compose") -include("platf-android") -include("platf-skia") - -// ============================= -// Plot Demos -// ============================= - -include("demo-plot-shared") -project(":demo-plot-shared").projectDir = File("./demo/plot/shared") - -include("demo-plot-compose-desktop") -project(":demo-plot-compose-desktop").projectDir = File("./demo/plot/compose-desktop") - -include("demo-plot-swing") -project(":demo-plot-swing").projectDir = File("./demo/plot/swing") - -include("demo-plot-compose-android-min") -project(":demo-plot-compose-android-min").projectDir = File("./demo/plot/compose-android-min") - -include("demo-plot-compose-android-median") -project(":demo-plot-compose-android-median").projectDir = File("./demo/plot/compose-android-median") - -include("demo-plot-compose-android-redraw") -project(":demo-plot-compose-android-redraw").projectDir = File("./demo/plot/compose-android-redraw") - - -// ============================= -// Pure SVG Rendering -// Internal - for testing. -// ============================= - -include("demo-svg-shared") -project(":demo-svg-shared").projectDir = File("./demo/svg/shared") - -include("demo-svg-compose-desktop") -project(":demo-svg-compose-desktop").projectDir = File("./demo/svg/compose-desktop") - -include("demo-svg-swing") -project(":demo-svg-swing").projectDir = File("./demo/svg/swing") - -// ============================= -// SVG View Rendering -// Internal - for testing. -// ============================= - -include("demo-svg-view-android") -project(":demo-svg-view-android").projectDir = File("./demo/view/android-svg-view") +dependencyResolutionManagement { + repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS + + repositories { + google() + mavenCentral() + maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") + maven("https://central.sonatype.com/repository/maven-snapshots/") + mavenLocal() + + // Load local.properties for custom maven repos + val localPropertiesFile = rootDir.resolve("local.properties") + if (localPropertiesFile.exists()) { + val localProps = java.util.Properties().apply { load(localPropertiesFile.inputStream()) } + localProps["maven.repo.local"]?.let { repos -> + (repos as String).split(",").forEach { repo -> + maven { url = uri(repo.trim()) } + } + } + } + } +} -include("demo-plot-view-android") -project(":demo-plot-view-android").projectDir = File("./demo/view/android-plot-view") +include( + ":lets-plot-compose", + ":platf-android", + ":platf-skia", + + // ========================================= + // Plot Demos + // ========================================= + ":demo:plot:shared", + ":demo:plot:compose-desktop", + ":demo:plot:swing", + ":demo:plot:compose-android-min", + ":demo:plot:compose-android-median", + ":demo:plot:compose-android-redraw", + + // ========================================= + // Pure SVG Rendering - Internal for testing + // ========================================= + ":demo:svg:shared", + ":demo:svg:compose-desktop", + ":demo:svg:swing", + + // ========================================= + // SVG View Rendering - Internal for testing + // ========================================= + ":demo:view:android-svg-view", + ":demo:view:android-plot-view" +)