POST
Using Gradle Metadata for a Kotlin multiplatform project
Data2viz is a Kotlin multimodule/multiplatform library. That means a lot of dependencies and artifacts. Let’s see how Gradle Metadata simplifies the dependencies management.
Before Gradle Metadata :
Android project
dependencies {
...
api "io.data2viz.d2v:scale-jvm:$data2viz_version"
api "io.data2viz.d2v:viz-android:$data2viz_version"
}
Kotlin/JS project
dependencies {
...
api "io.data2viz.d2v:scale-js:$data2viz_version"
api "io.data2viz.d2v:viz-js:$data2viz_version"
}
After Gradle Metadata, for all platforms:
dependencies {
...
api "io.data2viz.d2v:scale:$data2viz_version"
api "io.data2viz.d2v:viz:$data2viz_version"
}
The issue we had
Currently, you can use data2viz on the following platforms: Android, the browser, and JavaFX.
Data2viz contains 24 modules: axis
, chord
, contour
, core
, delaunay
, dsv
, ease
, force
, format
, hexbin
, hierarchy
, interpolate
, quadtree
, sankey
, scale
, shape
, tile
, time
, time-format
, timer
, transition
, viz
, voronoi
.
Depending on your targeted platform, you must choose the correct version
of the module, using the right artifact name. The name is composed of the
module’s name plus a suffix that can take the following values: -js
, -jvm
,
-android
, -jfx
.
There is no mystery with -js
. If you are developing a Kotlin/JS
visualization that needs scales, add the dependency on the data2viz
scale-js
module.
Things are a little bit more complicated with Android and JavaFX platforms. Most data2viz modules use the same artifact for both Android and JavaFX platforms.
For instance, the scale module produces an artifact
scale-jvm
that you can use for both Android and JavaFX projects.
This is because the scale module has no specific interaction with
the platform API. The module’s code uses the Kotlin standard library exclusively.
On the opposite, the viz
module is very tight to the underlying platform.
On Android, it uses android.graphics.Canvas
and on JavaFX
javafx.scene.canvas.Canvas
. So, there is no viz-jvm
artifact
but instead one for each jvm platform: viz-android
and viz-jfx
.
So depending on your project you need to add a dependency on :
Android
dependencies {
...
api "io.data2viz.d2v:viz-android:$data2viz_version"
}
JavaFX
dependencies {
...
api "io.data2viz.d2v:viz-jfx:$data2viz_version"
}
However, there is now a more simple way to manage dependencies using Gradle Metadata.
Gradle Metadata to the rescue
Gradle Metadata is a way to define variants of the published artifacts. A module file contains the information of the different variants and the context in which a project can consume them.
Here is an extract of the module file for io.data2viz.d2v:viz
{
"formatVersion": "1.0",
"component": {
"group": "io.data2viz.d2v",
"module": "viz",
"version": "0.8.0-RC10",
"attributes": {
"org.gradle.status": "release"
}
},
"createdBy": {
"gradle": {
"version": "5.4.1",
"buildId": "5z7vctbdqnggdpavv4q37uj4fa"
}
},
...
{
"name": "android-releaseRuntimeElements",
"attributes": {
"com.android.build.api.attributes.BuildTypeAttr": "release",
"com.android.build.api.attributes.VariantAttr": "release",
"com.android.build.gradle.internal.dependency.AndroidTypeAttr": "Aar",
"org.gradle.usage": "java-runtime",
"org.jetbrains.kotlin.platform.type": "androidJvm"
},
"available-at": {
"url": "../../viz-android/0.8.0-RC10/viz-android-0.8.0-RC10.module",
"group": "io.data2viz.d2v",
"module": "viz-android",
"version": "0.8.0-RC10"
}
},
{
"name": "jfx-api",
"attributes": {
"org.gradle.usage": "java-api-jars",
"org.jetbrains.kotlin.platform.type": "jvm"
},
"available-at": {
"url": "../../viz-jfx/0.8.0-RC10/viz-jfx-0.8.0-RC10.module",
"group": "io.data2viz.d2v",
"module": "viz-jfx",
"version": "0.8.0-RC10"
}
},
...
We can see here two different JVM variants of the module: a jvm
and an androidJvm
(there is also a js variant ).
Depending on the consumer project, Gradle (and Idea) is now able to choose the correct variant automatically.
You just need to add a dependency on the multiplatform module:
dependencies {
...
api "io.data2viz.d2v:viz:$data2viz_version"
}
This features works out of the box since Gradle 6.+.
To use it from Gradle 5.3+ projects,
you have to include enableFeaturePreview('GRADLE_METADATA')
in your settings.gradle
file.