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

Update CLI Integration Tests to use JVM Test Suites #3580

Merged
merged 10 commits into from May 7, 2024
@@ -0,0 +1,45 @@
/*
* Copyright 2014-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/
import dokkabuild.utils.declarable
import dokkabuild.utils.resolvable
import org.gradle.api.attributes.Bundling.BUNDLING_ATTRIBUTE
import org.gradle.api.attributes.Bundling.SHADOWED
import org.gradle.api.attributes.Usage.JAVA_RUNTIME
import org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE


val dokkaCli: Configuration by configurations.creating {
whyoleg marked this conversation as resolved.
Show resolved Hide resolved
description = "Dependency on Dokka CLI JAR. Must only contain a single dependency."
declarable()
}

val dokkaCliResolver: Configuration by configurations.creating {
description = "Resolve the Dokka CLI JAR. Intransitive - must only contain a single JAR."
resolvable()
extendsFrom(dokkaCli)
attributes {
attribute(USAGE_ATTRIBUTE, objects.named(JAVA_RUNTIME))
attribute(BUNDLING_ATTRIBUTE, objects.named(SHADOWED))
}
// we should have single artifact here
isTransitive = false
}


val dokkaPluginsClasspath: Configuration by configurations.creating {
description = "Dokka CLI runtime dependencies required to run Dokka CLI, and its plugins."
declarable()
}

val dokkaPluginsClasspathResolver: Configuration by configurations.creating {
description = "Resolve Dokka CLI runtime dependencies required to run Dokka CLI, and its plugins. " +
"Transitive dependencies are excluded, and so must be defined explicitly."
resolvable()
extendsFrom(dokkaPluginsClasspath)
attributes {
attribute(USAGE_ATTRIBUTE, objects.named(JAVA_RUNTIME))
}
// we don't fetch transitive dependencies here to be able to control external dependencies explicitly
isTransitive = false
}
118 changes: 64 additions & 54 deletions dokka-integration-tests/cli/build.gradle.kts
@@ -1,79 +1,89 @@
/*
* Copyright 2014-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/
@file:Suppress("UnstableApiUsage")

import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.gradle.api.attributes.Bundling.BUNDLING_ATTRIBUTE
import org.gradle.api.attributes.Bundling.SHADOWED

plugins {
id("dokkabuild.test-integration")
id("com.github.johnrengelman.shadow")
id("dokkabuild.kotlin-jvm")
id("dokkabuild.test-cli-dependencies")
`jvm-test-suite`
}

dependencies {
implementation(kotlin("test-junit5"))
implementation(libs.junit.jupiterApi)
implementation(projects.utilities)
}
api(kotlin("test-junit5"))
api(libs.junit.jupiterApi)
api(projects.utilities)

val cliPluginsClasspath: Configuration by configurations.creating {
description = "plugins/dependencies required to run CLI with base plugin"
attributes {
attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_RUNTIME))
}
dokkaCli("org.jetbrains.dokka:runner-cli")
whyoleg marked this conversation as resolved.
Show resolved Hide resolved

// we don't fetch transitive dependencies here to be able to control external dependencies explicitly
isTransitive = false
}
//region required dependencies of plugin-base
dokkaPluginsClasspath("org.jetbrains.dokka:plugin-base")
dokkaPluginsClasspath(libs.kotlinx.html)
adam-enko marked this conversation as resolved.
Show resolved Hide resolved
dokkaPluginsClasspath(libs.freemarker)

val cliClasspath: Configuration by configurations.creating {
description = "dependency on CLI JAR"
attributes {
attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_RUNTIME))
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
val analysisDependency = dokkaBuild.integrationTestUseK2.map { useK2 ->
if (useK2) {
"org.jetbrains.dokka:analysis-kotlin-symbols"
} else {
"org.jetbrains.dokka:analysis-kotlin-descriptors"
}
}
dokkaPluginsClasspath(analysisDependency) {
attributes {
attribute(BUNDLING_ATTRIBUTE, project.objects.named(SHADOWED))
}
}
// we should have single artifact here
isTransitive = false
//endregion
}

dependencies {
cliClasspath("org.jetbrains.dokka:runner-cli")

cliPluginsClasspath("org.jetbrains.dokka:plugin-base")
// required dependencies of `plugin-base`
cliPluginsClasspath(libs.freemarker)
cliPluginsClasspath(libs.kotlinx.html)

val tryK2 = project.providers
.gradleProperty("org.jetbrains.dokka.experimental.tryK2")
.map(String::toBoolean)
.orNull ?: false
/**
* Provide files required for running Dokka CLI in a build cache friendly way.
*/
abstract class DokkaCliClasspathProvider : CommandLineArgumentProvider {
@get:Classpath
abstract val dokkaCli: ConfigurableFileCollection

val analysisDependency = when {
tryK2 -> "org.jetbrains.dokka:analysis-kotlin-symbols"
else -> "org.jetbrains.dokka:analysis-kotlin-descriptors"
}
@get:Classpath
abstract val dokkaPluginsClasspath: ConfigurableFileCollection

cliPluginsClasspath(analysisDependency) {
attributes {
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
override fun asArguments(): Iterable<String> = buildList {
require(dokkaCli.count() == 1) {
"Expected a single Dokka CLI JAR, but got ${dokkaCli.count()}"
adam-enko marked this conversation as resolved.
Show resolved Hide resolved
}
add("-D" + "dokkaCliJarPath=" + dokkaCli.singleFile.absolutePath)
add("-D" + "dokkaPluginsClasspath=" + dokkaPluginsClasspath.joinToString(";") { it.absolutePath })
}
}

val cliPluginsShadowJar by tasks.registering(ShadowJar::class) {
archiveFileName.set("cli-plugins-${project.version}.jar")
configurations = listOf(cliPluginsClasspath)

// service files are merged to make sure all Dokka plugins
// from the dependencies are loaded, and not just a single one.
mergeServiceFiles()
}
testing {
suites {
withType<JvmTestSuite>().configureEach {
useJUnitJupiter()
}

tasks.integrationTest {
dependsOn(cliClasspath)
dependsOn(cliPluginsShadowJar)
register<JvmTestSuite>("integrationTest") {
dependencies {
implementation(project())
}

targets.configureEach {
testTask.configure {
jvmArgumentProviders.add(
objects.newInstance<DokkaCliClasspathProvider>().apply {
dokkaCli.from(configurations.dokkaCliResolver)
dokkaPluginsClasspath.from(configurations.dokkaPluginsClasspathResolver)
}
)
}
}
}
}
}

inputs.dir(file("projects"))
environment("CLI_JAR_PATH", cliClasspath.singleFile)
environment("BASE_PLUGIN_JAR_PATH", cliPluginsShadowJar.get().archiveFile.get())
tasks.check {
dependsOn(testing.suites)
}