Skip to content

Commit

Permalink
Fix HTML link in composite builds
Browse files Browse the repository at this point in the history
Log using the root-most Gradle project, taking composite builds into account.
  • Loading branch information
adam-enko committed Oct 21, 2024
1 parent bdb3847 commit 7e225cd
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import org.jetbrains.dokka.gradle.engine.plugins.DokkaHtmlPluginParameters.Compa
import org.jetbrains.dokka.gradle.engine.plugins.DokkaVersioningPluginParameters
import org.jetbrains.dokka.gradle.engine.plugins.DokkaVersioningPluginParameters.Companion.DOKKA_VERSIONING_PLUGIN_PARAMETERS_NAME
import org.jetbrains.dokka.gradle.internal.DokkaInternalApi
import org.jetbrains.dokka.gradle.internal.rootProjectName
import org.jetbrains.dokka.gradle.internal.rootGradle
import org.jetbrains.dokka.gradle.internal.uppercaseFirstChar
import org.jetbrains.dokka.gradle.tasks.DokkaGeneratePublicationTask
import org.jetbrains.dokka.gradle.tasks.LogHtmlPublicationLinkTask
Expand Down Expand Up @@ -72,8 +72,9 @@ constructor(
.flatMap { it.outputDirectory.file("index.html") }

val indexHtmlPath = indexHtmlFile.map { indexHtml ->
val rootProjectName = project.rootProjectName()
val relativePath = indexHtml.asFile.relativeTo(project.rootDir)
val rootProjectName = project.rootGradle().rootProject.name
val rootProjectDir = project.rootGradle().rootProject.projectDir
val relativePath = indexHtml.asFile.relativeTo(rootProjectDir)
"${rootProjectName}/${relativePath.invariantSeparatorsPath}"
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import org.gradle.api.artifacts.component.ProjectComponentIdentifier
import org.gradle.api.attributes.Attribute
import org.gradle.api.attributes.AttributeContainer
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.invocation.Gradle
import org.gradle.api.model.ObjectFactory
import org.gradle.api.plugins.ExtensionAware
import org.gradle.api.plugins.ExtensionContainer
Expand Down Expand Up @@ -370,20 +371,9 @@ internal const val INTERNAL_CONF_DESCRIPTION_TAG = "[Internal Dokka Configuratio


/**
* Get the root project name.
* Get the root-most [Gradle] instance.
*
* This function will try to be compatible with
* [Isolated Projects](https://docs.gradle.org/current/userguide/isolated_projects.html).
* This is useful for determining the root directory of Composite Builds.
*/
internal fun Project.rootProjectName(): String {
return when {
CurrentGradleVersion >= "8.8" -> {
@Suppress("UnstableApiUsage")
isolated.rootProject.name
}

else -> {
rootProject.name
}
}
}
internal fun Project.rootGradle(): Gradle =
generateSequence(gradle) { it.parent }.last()
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,22 @@ import org.gradle.testkit.runner.TaskOutcome.SKIPPED
import org.gradle.testkit.runner.TaskOutcome.SUCCESS
import org.jetbrains.dokka.gradle.internal.DokkaConstants
import org.jetbrains.dokka.gradle.utils.*
import kotlin.io.path.appendLines
import kotlin.io.path.copyTo

class LogHtmlPublicationLinkTaskTest : FunSpec({

// Re-run all leaves, to ensure each test has a fresh server.
//isolationMode = InstancePerLeaf

context("given an active file-host server") {
val server = embeddedServer(CIO, port = 0) { }
afterSpec { server.stop(gracePeriodMillis = 0, timeoutMillis = 0) }
server.start(wait = false)
val serverPort = server.resolvedConnectors().first().port

val validServerUri = "http://localhost:$serverPort"
val validServerUriParam = `-P`("testServerUri=$validServerUri")
val validServerUriParam = "testServerUri=$validServerUri"

context("and a Kotlin project") {
val project = initDokkaProject()
Expand All @@ -32,10 +38,8 @@ class LogHtmlPublicationLinkTaskTest : FunSpec({
"clean",
"dokkaGeneratePublicationHtml",
"--stacktrace",
"--info",
validServerUriParam,
"-P${validServerUriParam}",
)
.forwardOutput()
.build {
test("expect project builds successfully") {
output shouldContain "BUILD SUCCESSFUL"
Expand All @@ -52,19 +56,15 @@ class LogHtmlPublicationLinkTaskTest : FunSpec({
}

context("and the server is down") {
// stop the server immediately
server.stop(gracePeriodMillis = 0, timeoutMillis = 0)

val invalidServerUriParam = "testServerUri=http://notavailable.test:"
context("when running the generate task") {
project.runner
.addArguments(
"clean",
"dokkaGeneratePublicationHtml",
"--stacktrace",
"--info",
validServerUriParam,
"-P${invalidServerUriParam}",
)
.forwardOutput()
.build {
test("expect project builds successfully") {
output shouldContain "BUILD SUCCESSFUL"
Expand All @@ -82,18 +82,46 @@ class LogHtmlPublicationLinkTaskTest : FunSpec({
}
}
}

context("and a composite build project") {
val project = initCompositeBuildDokkaProject()

val nestedProjectGradleProperties = project.file("nested-project/gradle.properties")
project.file("gradle.properties")
.copyTo(
target = nestedProjectGradleProperties,
overwrite = true,
)
nestedProjectGradleProperties.appendLines(
listOf(
validServerUriParam
)
)

context("when generate task is run with correct server URI") {
project.runner
.addArguments(
"clean",
"dokkaGenerate",
"--stacktrace",
)
.build {
test("expect project builds successfully") {
output shouldContain "BUILD SUCCESSFUL"
}
test("LogHtmlPublicationLinkTask should run") {
shouldHaveTasksWithAnyOutcome(
":nested-project:logLinkDokkaGeneratePublicationHtml" to listOf(SUCCESS)
)
}
test("expect link is logged") {
output shouldContain "Generated Dokka HTML publication: $validServerUri/Composite%20Build%20Demo/nested-project/build/dokka/html/index.html"
}
}
}
}
}
}) {
companion object {
@Suppress("SpellCheckingInspection")
/**
* prefix [param] with `-P`.
*
* (this exists to avoid annoying typo warnings, e.g. `-Pserver=localhost` -> `Typo: In word 'Pserver'`)
*/
private fun `-P`(param: String): String = "-P$param"
}
}
})


private fun initDokkaProject(
Expand All @@ -106,9 +134,6 @@ private fun initDokkaProject(
| id("org.jetbrains.dokka") version "${DokkaConstants.DOKKA_VERSION}"
|}
|
|dependencies {
|}
|
|tasks.withType<org.jetbrains.dokka.gradle.tasks.LogHtmlPublicationLinkTask>().configureEach {
| serverUri.set(providers.gradleProperty("testServerUri"))
|}
Expand All @@ -134,3 +159,71 @@ private fun initDokkaProject(
config()
}
}


private fun initCompositeBuildDokkaProject(
config: GradleProjectTest.() -> Unit = {},
): GradleProjectTest {
return gradleKtsProjectTest(
projectLocation = "log-html-publication-link-task-composite-build",
rootProjectName = "Composite Build Demo"
) {
buildGradleKts = """
|plugins {
| base
|}
|
|tasks.clean {
| dependsOn(gradle.includedBuild("nested-project").task(":clean"))
|}
|
|val dokkaGenerate by tasks.registering {
| dependsOn(gradle.includedBuild("nested-project").task(":dokkaGenerate"))
|}
|
""".trimMargin()

settingsGradleKts += """
|includeBuild("nested-project")
""".trimMargin()

dir("nested-project") {
buildGradleKts = """
|plugins {
| kotlin("jvm") version "1.9.25"
| id("org.jetbrains.dokka") version "${DokkaConstants.DOKKA_VERSION}"
|}
|
|tasks.withType<org.jetbrains.dokka.gradle.tasks.LogHtmlPublicationLinkTask>().configureEach {
| serverUri.set(providers.gradleProperty("testServerUri"))
|}
""".trimMargin()

settingsGradleKts = """
|rootProject.name = "Nested Project"
|
|${settingsRepositories()}
|
""".trimMargin()

createKotlinFile(
"src/main/kotlin/Hello.kt",
"""
|package com.project.hello
|
|/** The Hello class */
|class Hello {
| /** prints `Hello` to the console */
| fun sayHello() = println("Hello")
|}
|
""".trimMargin()
)
}

// remove the flag that disables the logging task, since this test wants the logger to run
gradleProperties.dokka.enableLogHtmlPublicationLink = null

config()
}
}

0 comments on commit 7e225cd

Please sign in to comment.