Skip to content

Commit

Permalink
Publishing JVM jar and pom in root variant (#3859)
Browse files Browse the repository at this point in the history
Solves the issue of Maven and Gradle <6.0 users being unable to resolve
platform variants.

See discussion in
https://youtrack.jetbrains.com/issue/KT-65529/As-a-multiplatform-library-dev-I-want-the-root-variant-to-include-JVM-dependencies
and PR #3858
  • Loading branch information
Kantis committed Feb 3, 2024
1 parent 9cd184f commit 4861afa
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 11 deletions.
66 changes: 66 additions & 0 deletions buildSrc/src/main/kotlin/kotest-publishing-conventions.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,64 @@
import groovy.util.Node
import groovy.util.NodeList
import org.gradle.configurationcache.extensions.capitalized

/**
* Publish the platform JAR and POM so that consumers who depend on this module and can't read Gradle module
* metadata can still get the platform artifact and transitive dependencies from the POM
* (see details in https://youtrack.jetbrains.com/issue/KT-39184#focus=streamItem-27-4115233.0-0)
*/
fun Project.publishPlatformArtifactsInRootModule() {
val platformPublication: MavenPublication? =
extensions
.findByType(PublishingExtension::class.java)
?.publications
?.getByName<MavenPublication>("jvm")
if (platformPublication != null) {

lateinit var platformXml: XmlProvider
platformPublication.pom?.withXml { platformXml = this }

extensions
.findByType(PublishingExtension::class.java)
?.publications
?.getByName("kotlinMultiplatform")
?.let { it as MavenPublication }
?.run {

// replace pom
pom.withXml {
val xmlProvider = this
val root = xmlProvider.asNode()
// Remove the original content and add the content from the platform POM:
root.children().toList().forEach { root.remove(it as Node) }
platformXml.asNode().children().forEach { root.append(it as Node) }

// Adjust the self artifact ID, as it should match the root module's coordinates:
((root.get("artifactId") as NodeList).get(0) as Node).setValue(artifactId)

// Set packaging to POM to indicate that there's no artifact:
root.appendNode("packaging", "pom")

// Remove the original platform dependencies and add a single dependency on the platform
// module:
val dependencies = (root.get("dependencies") as NodeList).get(0) as Node
dependencies.children().toList().forEach { dependencies.remove(it as Node) }
val singleDependency = dependencies.appendNode("dependency")
singleDependency.appendNode("groupId", platformPublication.groupId)
singleDependency.appendNode("artifactId", platformPublication.artifactId)
singleDependency.appendNode("version", platformPublication.version)
singleDependency.appendNode("scope", "compile")
}
}

tasks
.matching { it.name == "generatePomFileForKotlinMultiplatformPublication" }
.configureEach {
dependsOn("generatePomFileFor${platformPublication.name.capitalized()}Publication")
}
}
}

plugins {
signing
`java-library`
Expand All @@ -18,6 +79,7 @@ val javadocJar by tasks.creating(Jar::class) {
from(javadoc)
}


publishing {
publications.withType<MavenPublication>().forEach {
it.apply {
Expand All @@ -42,6 +104,8 @@ signing {
}
}

publishPlatformArtifactsInRootModule()

publishing {
repositories {
maven {
Expand Down Expand Up @@ -88,3 +152,5 @@ publishing {
}
}
}


20 changes: 12 additions & 8 deletions doc/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ These are provided separately so you can pick and choose which parts to use if y

The following instructions give you the batteries included setup in gradle or maven. Omit any modules you don't wish to use.

_Note: Kotest is a [multi-platform project](https://kotlinlang.org/docs/reference/multiplatform.html).
If you are unfamilar with this, then Kotlin compiles to different targets - JVM, JS, Native, iOS and so on. If you are doing server side or android development then you want the modules that end with -JVM, such as `kotest-property-jvm`_


#### Gradle

To use in gradle, configure your build to use the [JUnit Platform](https://junit.org/junit5/docs/current/user-guide/#running-tests-build-gradle). For Gradle 4.6 and higher this is
Expand Down Expand Up @@ -119,21 +115,29 @@ For maven you must configure the surefire plugin for junit tests.

And then add the Kotest JUnit5 runner to your build to use the framework product.


```xml
<dependency>
<groupId>io.kotest</groupId>
<artifactId>kotest-runner-junit5-jvm</artifactId>
<artifactId>kotest-runner-junit5</artifactId>
<version>{version}</version>
<scope>test</scope>
</dependency>
```

For using kotest core jvm assertions add the following configuration.
:::info
Kotest is a [multi-platform project](https://kotlinlang.org/docs/reference/multiplatform.html).
If you are unfamiliar with this, then Kotlin compiles to different targets - JVM, JS, Native, iOS and so on.
Since version 5.9.0, Kotest includes a workaround so that the `kotest-runner-junit5` module can be used directly, but
for older versions you need to explicitly depend on the modules that end with -JVM, such as `kotest-property-jvm`_
:::

For using kotest assertions add the following configuration.

```xml
<dependency>
<groupId>io.kotest</groupId>
<artifactId>kotest-assertions-core-jvm</artifactId>
<artifactId>kotest-assertions-core</artifactId>
<version>{version}</version>
<scope>test</scope>
</dependency>
Expand All @@ -144,7 +148,7 @@ And for using kotest property testing add the following configuration.
```xml
<dependency>
<groupId>io.kotest</groupId>
<artifactId>kotest-property-jvm</artifactId>
<artifactId>kotest-property</artifactId>
<version>{version}</version>
<scope>test</scope>
</dependency>
Expand Down
4 changes: 2 additions & 2 deletions documentation/docs/extensions/pitest.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ First of all, you need to configure the [Maven Pitest plugin](https://pitest.org
<configuration>
<targetClasses>...</targetClasses>
<coverageThreshold>...</coverageThreshold>
... other configurations as needed
... other configurations as needed
</configuration>
</plugin>
```
Expand All @@ -54,7 +54,7 @@ Then add the dependency on Pitest Kotest extension:

```xml
<dependencies>
... the other Kotest dependencies like kotest-runner-junit5-jvm
... the other Kotest dependencies like kotest-runner-junit5
<dependency>
<groupId>io.kotest.extensions</groupId>
<artifactId>kotest-extensions-pitest</artifactId>
Expand Down
9 changes: 8 additions & 1 deletion documentation/docs/framework/setup.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,19 @@ And then add the Kotest JUnit5 runner to your dependencies section.
```xml
<dependency>
<groupId>io.kotest</groupId>
<artifactId>kotest-runner-junit5-jvm</artifactId>
<artifactId>kotest-runner-junit5</artifactId>
<version>{version}</version>
<scope>test</scope>
</dependency>
```

:::info
Kotest is a [multi-platform project](https://kotlinlang.org/docs/reference/multiplatform.html).
If you are unfamiliar with this, then Kotlin compiles to different targets - JVM, JS, Native, iOS and so on.
Since version 5.9.0, Kotest includes a workaround so that the `kotest-runner-junit5` module can be used directly, but
for older versions you need to explicitly depend on the modules that end with -JVM, such as `kotest-property-jvm`_
:::

</TabItem>
<TabItem value="Android">

Expand Down

0 comments on commit 4861afa

Please sign in to comment.