Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add jupyter integration for lets-plot-kotlin and lets-plot-kotlin-geotools #258

Merged
merged 6 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ plugins {
id("io.codearte.nexus-staging") apply false

id("io.github.gradle-nexus.publish-plugin")

// Add the KSP plugin before the Jupyter API to avoid ksp versions incompatibility.
// May be removed when using further versions of the jupyter api
id("com.google.devtools.ksp") apply false
kotlin("jupyter.api") apply false
}

val localProps = Properties()
Expand Down
7 changes: 7 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,24 @@ kotlin.code.style=official
kotlin.daemon.jvmargs=-Xmx2048M
kotlin.jvm.target.validation.mode=error

# Jupyter API
kotlin.jupyter.add.scanner=false

# Versions
kotlin.version=1.9.25
datetime.version=0.3.2
kotlinLogging.version=2.0.5
slf4j.version=1.7.32
assertj.version=3.26.3
serialization.version=1.7.3

dokka.version=1.9.20
nexusStaging.version=0.30.0
nexusPublish.version=1.3.0

ksp.version=1.9.25-1.0.20
jupyterApi.version=0.12.0-313

# Also update JS version in <home>/demo/js-frontend-app/src/main/resources/index.html
letsPlot.version=4.5.1

Expand Down
19 changes: 19 additions & 0 deletions plot-api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,22 @@ tasks {
// print("${project.name}: ${uri(project.localMavenRepository)}")
//}

// Provide jvm resources to jupyter module
// https://youtrack.jetbrains.com/issue/KTIJ-16582/Consumer-Kotlin-JVM-library-cannot-access-a-Kotlin-Multiplatform-JVM-target-resources-in-multi-module-Gradle-project
tasks {
val jvmProcessResources by getting
val fixMissingResources by creating(Copy::class) {
dependsOn(jvmProcessResources)
from(layout.buildDirectory.dir("processedResources/jvm/main"))
into(layout.buildDirectory.dir("classes/kotlin/jvm/main"))
duplicatesStrategy = DuplicatesStrategy.INCLUDE
}
val jvmJar by getting(Jar::class) {
dependsOn(fixMissingResources)
duplicatesStrategy = DuplicatesStrategy.INCLUDE
}
}

tasks.named("jvmTest") {
dependsOn("fixMissingResources")
}
14 changes: 14 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,19 @@ pluginManagement {
val nexusStagingVersion = extra["nexusStaging.version"] as String
val nexusPublishVersion = extra["nexusPublish.version"] as String

val kspVersion = extra["ksp.version"] as String
val jupyterApiVersion = extra["jupyterApi.version"] as String

kotlin("multiplatform") version kotlinVersion
kotlin("jvm").version(kotlinVersion)

id("org.jetbrains.dokka") version dokkaVersion

id("io.codearte.nexus-staging") version nexusStagingVersion
id("io.github.gradle-nexus.publish-plugin") version nexusPublishVersion

id("com.google.devtools.ksp") version kspVersion
kotlin("jupyter.api") version jupyterApiVersion
}
}

Expand All @@ -39,6 +45,9 @@ include("js-frontend-app")
include("geotools")
include("geotools-batik")
include("dokka")
include("jupyter")
include("geotools-jupyter")
include("json")

project(":demo-common").projectDir = File("./demo/demo-common")
project(":jvm-javafx").projectDir = File("./demo/jvm-javafx")
Expand All @@ -50,3 +59,8 @@ project(":geotools").projectDir = File("./toolkit/geotools")
project(":geotools-batik").projectDir = File("./demo/geotools-batik")

project(":dokka").projectDir = File("./docs/dokka")

project(":jupyter").projectDir = File("./toolkit/jupyter")
project(":geotools-jupyter").projectDir = File("./toolkit/geotools-jupyter")

project(":json").projectDir = File("./toolkit/json")
103 changes: 103 additions & 0 deletions toolkit/geotools-jupyter/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
kotlin("jvm")
`maven-publish`
signing
id("com.google.devtools.ksp")
kotlin("jupyter.api")
}

repositories {
mavenCentral()
}

val geoToolsVersion = extra["geotools.version"] as String

dependencies {
implementation(projects.plotApi)
// basic LPK jupyter integration
implementation(projects.jupyter)

// geotools implementations
implementation(projects.geotools)
implementation("org.geotools:gt-main:$geoToolsVersion")
implementation("org.geotools:gt-geojson:$geoToolsVersion")

testImplementation(kotlin("test"))
}

kotlin {
jvmToolchain(11)
}
tasks.withType<KotlinCompile>().all {
kotlinOptions {
jvmTarget = JavaVersion.VERSION_11.toString()
}
}

tasks.withType<JavaCompile>().all {
sourceCompatibility = JavaVersion.VERSION_11.toString()
targetCompatibility = JavaVersion.VERSION_11.toString()
}

tasks.processJupyterApiResources {
libraryProducers = listOf("org.jetbrains.letsPlot.toolkit.geotools.jupyter.Integration")
}

val artifactBaseName = "lets-plot-kotlin-geotools-jupyter"
val artifactGroupId = project.group as String
val artifactVersion = project.version as String

afterEvaluate {

publishing {
publications {
// Build artifact with all dependencies.
create<MavenPublication>("letsPlotKotlinGeotoolsJupyter") {

groupId = artifactGroupId
artifactId = artifactBaseName
version = artifactVersion

from(components["java"])

pom {
name.set("Lets-Plot Kotlin Geotools Jupyter Integration")
description.set(
"Lets-Plot Kotlin Geotools Integration For Kotlin Jupyter Kernel."
)
url.set("https://github.com/JetBrains/lets-plot-kotlin")
licenses {
license {
name.set("MIT")
url.set("https://raw.githubusercontent.com/JetBrains/lets-plot-kotlin/master/LICENSE")
}
}
developers {
developer {
id.set("jetbrains")
name.set("JetBrains")
email.set("[email protected]")
}
}
scm {
url.set("https://github.com/JetBrains/lets-plot-kotlin")
}
}
}
}

repositories {
mavenLocal {
val localMavenRepository: String by project
url = uri(localMavenRepository)
}
}
}
}
signing {
if (!(project.version as String).contains("SNAPSHOT")) {
sign(publishing.publications)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.jetbrains.letsPlot.toolkit.geotools.jupyter

import org.jetbrains.kotlinx.jupyter.api.Notebook
import org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration
import org.jetbrains.kotlinx.jupyter.api.libraries.repositories
import org.jetbrains.letsPlot.export.VersionChecker

@Suppress("unused")
class Integration(private val notebook: Notebook, private val options: MutableMap<String, String?>) :
JupyterIntegration() {
private val api = options["api"] ?: VersionChecker.letsPlotKotlinAPIVersion
override fun Builder.onLoaded() {
repositories {
maven("https://repo.osgeo.org/repository/release")
}
import("org.jetbrains.letsPlot.toolkit.geotools.toSpatialDataset")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.jetbrains.letsPlot.toolkit.geotools.jupyter

import org.jetbrains.kotlinx.jupyter.testkit.JupyterReplTestCase
import kotlin.test.Test

class NaturalEarthTest : JupyterReplTestCase() {
private val geotoolsDependencies = """
USE {
dependencies {
implementation("org.geotools:gt-shapefile:30.0")
}
}
""".trimIndent()

private val naturalEarthMap = """
import org.geotools.data.shapefile.ShapefileDataStoreFactory
import org.geotools.data.simple.SimpleFeatureCollection
import java.net.URL

val factory = ShapefileDataStoreFactory()
val worldFeatures : SimpleFeatureCollection = with("naturalearth_lowres") {
val url = "https://raw.githubusercontent.com/JetBrains/lets-plot-kotlin/master/docs/examples/shp/${'$'}this/${'$'}this.shp"
factory.createDataStore(URL(url)).featureSource.features
}

val world = worldFeatures.toSpatialDataset(10)
letsPlot() +
geomMap(map = world) +
ggsize(700, 400) +
themeVoid()
""".trimIndent()

@Test
fun `natural earth example compilation in jupyter`() {
execRendered(geotoolsDependencies)
execRendered(naturalEarthMap)
}
}
68 changes: 68 additions & 0 deletions toolkit/json/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
plugins {
kotlin("jvm")
`maven-publish`
signing
}

val serializationVersion = extra["serialization.version"] as String

dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$serializationVersion")

testImplementation(kotlin("test"))
}


val artifactBaseName = "lets-plot-kotlin-json"
val artifactGroupId = project.group as String
val artifactVersion = project.version as String

afterEvaluate {
publishing {
publications {
create<MavenPublication>("letsPlotKotlinJson") {
groupId = artifactGroupId
artifactId = artifactBaseName
version = artifactVersion

from(components["java"])

pom {
name.set("Lets-Plot Kotlin Util")
description.set(
"Lets-Plot Kotlin Util For Json Serialization."
)
url.set("https://github.com/JetBrains/lets-plot-kotlin")
licenses {
license {
name.set("MIT")
url.set("https://raw.githubusercontent.com/JetBrains/lets-plot-kotlin/master/LICENSE")
}
}
developers {
developer {
id.set("jetbrains")
name.set("JetBrains")
email.set("[email protected]")
}
}
scm {
url.set("https://github.com/JetBrains/lets-plot-kotlin")
}
}
}
}

repositories {
mavenLocal {
val localMavenRepository: String by project
url = uri(localMavenRepository)
}
}
}
}
signing {
if (!(project.version as String).contains("SNAPSHOT")) {
sign(publishing.publications)
}
}
Loading
Loading