-
Notifications
You must be signed in to change notification settings - Fork 417
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update CLI Integration Tests to use JVM Test Suites (#3580)
* Part of KT-64200 - Migrate the CLI integration tests away from the custom integration test convention (which are not build-cache compatible) to use JVM Test Suites. - Remove shadowing, replace with passing in the JARs via system properties. (a custom CommandLineArgumentProvider is confusing and overly complicated, but it's required to satisfy Gradle input normalization, so that the build-cache can be re-used.) - Simplify `processUtils.kt` - the coroutines logic isn't necessary since the entrypoint just used `runBlocking {}`. - move `jsonBuilder.kt` test-util into `src/main`, since it's not a test - Rename `CliIntegrationTest` to `CliTest` (it wasn't an integration test, and the name was confusing compared to the actual `CliIntegrationTest`) * fix dokkaCli dependency resolution * exclude transitives from dokkaPluginsClasspath * create a dokka-config.json for each test in the temp directory, don't re-write a shared file in resources * add ticket to TODO * rm check fix * revert build.gradle.kts * re-add `required dependencies of plugin-base` comment * incrementally print stdout from Process * rm unnecessary coroutines dependency
- Loading branch information
Showing
13 changed files
with
233 additions
and
204 deletions.
There are no files selected for viewing
45 changes: 45 additions & 0 deletions
45
build-logic/src/main/kotlin/dokkabuild.test-cli-dependencies.gradle.kts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 { | ||
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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") | ||
|
||
// 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) | ||
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()}" | ||
} | ||
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) | ||
} |
Oops, something went wrong.