Skip to content

Commit ee916cc

Browse files
authored
Merge pull request #159 from altavir/feature/plugin-mpp
MPP support for Gradle plugin
2 parents 72c8069 + 240e875 commit ee916cc

File tree

6 files changed

+96
-30
lines changed

6 files changed

+96
-30
lines changed

docs/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
# Kotlin kernel for IPython/Jupyter
88

9-
[Kotlin](https://kotlinlang.org/) (1.4.30) kernel for [Jupyter](https://jupyter.org).
9+
[Kotlin](https://kotlinlang.org/) (1.4.31) kernel for [Jupyter](https://jupyter.org).
1010

1111
Beta version. Tested with Jupyter Notebook 6.0.3, Jupyter Lab 1.2.6 and Jupyter Console 6.1.0
1212
on Windows, Ubuntu Linux and macOS. Using with Jupyter Console frontend is problematic now because of

gradle.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# kotlinVersion=1.4.255-SNAPSHOT
2-
kotlinVersion=1.4.30
2+
kotlinVersion=1.4.31
33
kotlinLanguageLevel=1.4
44
jvmTarget=1.8
55

jupyter-lib/kotlin-jupyter-api-gradle-plugin/build.gradle.kts

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ project.version = rootProject.version
1010
project.group = "org.jetbrains.kotlin"
1111

1212
val junitVersion: String by rootProject
13+
val kotlinVersion: String by rootProject
1314

1415
repositories {
1516
jcenter()
@@ -21,7 +22,7 @@ dependencies {
2122
// Temporary solution until Kotlin 1.4 will be supported in
2223
// .kts buildscripts and it will be possible to use
2324
// kotlinx.serialization in plugin code
24-
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.20")
25+
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
2526
implementation("com.google.code.gson:gson:2.8.6")
2627

2728
testImplementation(kotlin("test"))

jupyter-lib/kotlin-jupyter-api-gradle-plugin/src/main/kotlin/org/jetbrains/kotlinx/jupyter/api/plugin/ApiGradlePlugin.kt

+37-14
Original file line numberDiff line numberDiff line change
@@ -2,52 +2,75 @@ package org.jetbrains.kotlinx.jupyter.api.plugin
22

33
import org.gradle.api.Plugin
44
import org.gradle.api.Project
5+
import org.gradle.kotlin.dsl.findByType
56
import org.gradle.kotlin.dsl.invoke
67
import org.gradle.kotlin.dsl.register
78
import org.gradle.kotlin.dsl.repositories
9+
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
810
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin
911
import org.jetbrains.kotlin.gradle.plugin.KaptExtension
12+
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
1013
import org.jetbrains.kotlinx.jupyter.api.plugin.tasks.JupyterApiResourcesTask
1114

1215
class ApiGradlePlugin : Plugin<Project> {
13-
override fun apply(target: Project) {
14-
target.pluginManager.run {
16+
override fun apply(target: Project): Unit = with(target) {
17+
pluginManager.run {
1518
apply(Kapt3GradleSubplugin::class.java)
1619
}
1720

18-
val jupyterBuildPath = target.buildDir.resolve(FQNS_PATH)
19-
target.extensions.configure<KaptExtension>("kapt") {
21+
val jupyterBuildPath = buildDir.resolve(FQNS_PATH)
22+
extensions.configure<KaptExtension>("kapt") {
2023
arguments {
2124
arg("kotlin.jupyter.fqn.path", jupyterBuildPath)
2225
}
2326
}
2427

25-
target.repositories {
28+
repositories {
2629
mavenCentral()
2730
}
2831

2932
val pluginExtension = KotlinJupyterPluginExtension(target)
30-
target.extensions.add("kotlinJupyter", pluginExtension)
33+
extensions.add("kotlinJupyter", pluginExtension)
3134
pluginExtension.addDependenciesIfNeeded()
3235

33-
target.tasks {
36+
tasks {
3437
val cleanJupyterTask = register("cleanJupyterPluginFiles") {
3538
doLast {
3639
jupyterBuildPath.deleteRecursively()
3740
}
3841
}
3942

4043
val resourcesTaskName = "processJupyterApiResources"
41-
register<JupyterApiResourcesTask>(resourcesTaskName) {
42-
val kaptKotlinTask = findByName("kaptKotlin")
43-
if (kaptKotlinTask != null) {
44-
dependsOn(kaptKotlinTask)
45-
kaptKotlinTask.dependsOn(cleanJupyterTask)
44+
fun registerResourceTask() {
45+
register<JupyterApiResourcesTask>(resourcesTaskName) {
46+
val kaptKotlinTask = findByName("kaptKotlin")
47+
if (kaptKotlinTask != null) {
48+
dependsOn(kaptKotlinTask)
49+
kaptKotlinTask.dependsOn(cleanJupyterTask)
50+
}
4651
}
4752
}
4853

49-
named("processResources") {
50-
dependsOn(resourcesTaskName)
54+
// apply configuration to JVM-only project
55+
plugins.withId("org.jetbrains.kotlin.jvm") {
56+
// Task should be registered after plugin is applied
57+
registerResourceTask()
58+
named("processResources") {
59+
dependsOn(resourcesTaskName)
60+
}
61+
}
62+
63+
// apply only to multiplatform plugin
64+
plugins.withId("org.jetbrains.kotlin.multiplatform") {
65+
// Task should be registered after plugin is applied
66+
registerResourceTask()
67+
extensions.findByType<KotlinMultiplatformExtension>()?.apply {
68+
val jvmTargetName = targets.filterIsInstance<KotlinJvmTarget>().firstOrNull()?.name
69+
?: error("Single JVM target not found in a multiplatform project")
70+
named(jvmTargetName + "ProcessResources") {
71+
dependsOn(resourcesTaskName)
72+
}
73+
}
5174
}
5275
}
5376
}

jupyter-lib/kotlin-jupyter-api-gradle-plugin/src/main/kotlin/org/jetbrains/kotlinx/jupyter/api/plugin/KotlinJupyterPluginExtension.kt

+32-10
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,49 @@ package org.jetbrains.kotlinx.jupyter.api.plugin
22

33
import org.gradle.api.Project
44
import org.gradle.kotlin.dsl.dependencies
5+
import org.gradle.kotlin.dsl.findByType
6+
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
7+
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
8+
9+
private fun Project.configureDependency(scope: String, dependencyNotation: Any) {
10+
// apply configuration to JVM-only project
11+
plugins.withId("org.jetbrains.kotlin.jvm") {
12+
val configuration = project.configurations.findByName(scope)
13+
?: error("$scope configuration is not resolved for a Kotlin-JVM project")
14+
dependencies {
15+
configuration.invoke(dependencyNotation)
16+
}
17+
}
18+
// apply only to multiplatform plugin
19+
plugins.withId("org.jetbrains.kotlin.multiplatform") {
20+
extensions.findByType<KotlinMultiplatformExtension>()?.apply {
21+
val jvmTargetName = targets.filterIsInstance<KotlinJvmTarget>().firstOrNull()?.name
22+
?: error("Single JVM target not found in a multiplatform project")
23+
val configuration = project.configurations.findByName(jvmTargetName + scope.capitalize())
24+
?: error("$scope configuration is not resolved for a multiplatform project")
25+
dependencies {
26+
configuration.invoke(dependencyNotation)
27+
}
28+
}
29+
}
30+
}
531

632
class KotlinJupyterPluginExtension(
733
private val project: Project
834
) {
9-
fun addApiDependency(version: String? = null) {
35+
fun addApiDependency(version: String? = null) = with(project) {
1036
val apiVersion = version ?: apiVersion()
11-
val compileOnlyConf = project.configurations.findByName("compileOnly") ?: return
12-
project.dependencies {
13-
compileOnlyConf("$GROUP_ID:kotlin-jupyter-api:$apiVersion")
14-
}
37+
configureDependency("compileOnly", "$GROUP_ID:kotlin-jupyter-api:$apiVersion")
1538
}
1639

17-
fun addScannerDependency(version: String? = null) {
18-
val implementationConf = project.configurations.findByName("implementation") ?: return
19-
val kaptConf = project.configurations.findByName("kapt") ?: return
40+
fun addScannerDependency(version: String? = null) = with(project) {
41+
val kaptConf = configurations.findByName("kapt") ?: return
2042
val apiVersion = version ?: apiVersion()
2143
val mavenCoordinates = "$GROUP_ID:kotlin-jupyter-api-annotations:$apiVersion"
22-
project.dependencies {
23-
implementationConf(mavenCoordinates)
44+
dependencies {
2445
kaptConf(mavenCoordinates)
2546
}
47+
configureDependency("implementation", mavenCoordinates)
2648
}
2749

2850
internal fun addDependenciesIfNeeded() {

jupyter-lib/kotlin-jupyter-api-gradle-plugin/src/main/kotlin/org/jetbrains/kotlinx/jupyter/api/plugin/tasks/JupyterApiResourcesTask.kt

+23-3
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@ import com.google.gson.Gson
44
import org.gradle.api.DefaultTask
55
import org.gradle.api.tasks.Input
66
import org.gradle.api.tasks.OutputDirectory
7+
import org.gradle.api.tasks.SourceSet
78
import org.gradle.api.tasks.SourceSetContainer
89
import org.gradle.api.tasks.TaskAction
10+
import org.gradle.kotlin.dsl.findByType
11+
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
12+
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
913
import org.jetbrains.kotlinx.jupyter.api.plugin.ApiGradlePlugin
1014
import java.io.File
1115

@@ -31,9 +35,25 @@ open class JupyterApiResourcesTask : DefaultTask() {
3135

3236
init {
3337
val sourceSets = project.extensions.getByName("sourceSets") as SourceSetContainer
34-
val mainSourceSet = sourceSets.named("main").get()
35-
outputDir = mainSourceSet.output.resourcesDir?.resolve("META-INF/kotlin-jupyter-libraries")
36-
?: throw IllegalStateException("No resources dir for main source set")
38+
when {
39+
project.plugins.findPlugin("org.jetbrains.kotlin.jvm") != null -> {
40+
val mainSourceSet: SourceSet = sourceSets.named("main").get()
41+
outputDir = mainSourceSet.output.resourcesDir?.resolve("META-INF/kotlin-jupyter-libraries")
42+
?: throw IllegalStateException("No resources dir for main source set")
43+
}
44+
project.plugins.findPlugin("org.jetbrains.kotlin.multiplatform") != null -> {
45+
val mppExtension = project.extensions.findByType<KotlinMultiplatformExtension>()
46+
?: error("Kotlin MPP extension not found")
47+
val jvmTargetName = mppExtension.targets.filterIsInstance<KotlinJvmTarget>().firstOrNull()?.name
48+
?: error("Single JVM target not found in a multiplatform project")
49+
// TODO properly resolve resource directory
50+
outputDir = project.buildDir.resolve("processedResources/$jvmTargetName/main")
51+
.resolve("META-INF/kotlin-jupyter-libraries")
52+
}
53+
else -> {
54+
error("Kotlin plugin not found in the project")
55+
}
56+
}
3757
}
3858

3959
@TaskAction

0 commit comments

Comments
 (0)