Skip to content

Commit

Permalink
Fix HTML link log when project name doesn't match directory name (#3788)
Browse files Browse the repository at this point in the history
* Fix HTML link log when project name doesn't match directory name
* simplify registering the HTML HtmlUrlLogging task

KT-71254
  • Loading branch information
adam-enko authored Sep 9, 2024
1 parent 51ddab5 commit 0ff378b
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import org.gradle.api.Task
import org.gradle.api.file.ArchiveOperations
import org.gradle.api.logging.Logging
import org.gradle.api.provider.ProviderFactory
import org.gradle.api.tasks.TaskProvider
import org.gradle.kotlin.dsl.register
import org.gradle.kotlin.dsl.registerBinding
import org.gradle.kotlin.dsl.withType
Expand Down Expand Up @@ -66,36 +65,30 @@ constructor(
}
}

/** Register a [LogHtmlPublicationLinkTask] task. */
private fun DokkaFormatPluginContext.configureHtmlUrlLogging() {
val logHtmlUrlTask = registerLogHtmlUrlTask()

dokkaTasks.generatePublication.configure {
finalizedBy(logHtmlUrlTask)
}
}

private fun DokkaFormatPluginContext.registerLogHtmlUrlTask():
TaskProvider<LogHtmlPublicationLinkTask> {

val generatePublicationTask = dokkaTasks.generatePublication

val indexHtmlFile = generatePublicationTask
val indexHtmlFile = dokkaTasks.generatePublication
.flatMap { it.outputDirectory.file("index.html") }

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

return project.tasks.register<LogHtmlPublicationLinkTask>(
"logLink" + generatePublicationTask.name.uppercaseFirstChar()
val logHtmlUrlTask = project.tasks.register<LogHtmlPublicationLinkTask>(
"logLink" + dokkaTasks.generatePublication.name.uppercaseFirstChar()
) {
// default port of IntelliJ built-in server is defined in the docs
// The default port of IntelliJ's built-in server is defined in the docs
// https://www.jetbrains.com/help/idea/settings-debugger.html#24aabda8
serverUri.convention("http://localhost:63342")
// IntelliJ always uses port 63342, but users might configure an additional port.
this.serverUri.convention("http://localhost:63342")
this.indexHtmlPath.convention(indexHtmlPath)
}

dokkaTasks.generatePublication.configure {
finalizedBy(logHtmlUrlTask)
}
}

/**
Expand Down Expand Up @@ -162,7 +155,7 @@ constructor(
logger.warn(/* language=text */ """
|[${task.path}] org.jetbrains.dokka:all-modules-page-plugin is missing.
|
|Publication '$moduleName' in has $modulesCount modules, but
|Dokka Publication '$moduleName' has $modulesCount Dokka modules, but
|the Dokka Generator plugins classpath does not contain
| org.jetbrains.dokka:all-modules-page-plugin
|which is required for aggregating Dokka HTML modules.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import org.gradle.api.provider.ValueSource
import org.gradle.api.provider.ValueSourceParameters
import org.gradle.api.tasks.Console
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.UntrackedTask
import org.gradle.kotlin.dsl.of
import org.gradle.work.DisableCachingByDefault
import org.jetbrains.dokka.gradle.internal.DokkaInternalApi
import org.jetbrains.dokka.gradle.internal.appendPath
import org.jetbrains.dokka.gradle.tasks.LogHtmlPublicationLinkTask.Companion.ENABLE_TASK_PROPERTY_NAME
Expand All @@ -36,40 +36,48 @@ import javax.inject.Inject
* † For some reason, the only doc page for the built-in server I could find is for PhpStorm,
* but the built-in server is also available in IntelliJ IDEA.
*/
@DisableCachingByDefault(because = "logging-only task")
@UntrackedTask(because = "logging-only task")
abstract class LogHtmlPublicationLinkTask
@Inject
@DokkaInternalApi
constructor(
providers: ProviderFactory
) : DokkaBaseTask() {

/**
* A localhost server, for serving Dokka HTML.
*
* A server is required because Dokka HTML uses JavaScript.
*/
@get:Console
abstract val serverUri: Property<String>

/**
* Path to the `index.html` of the publication. Will be appended to [serverUri].
* Path to the `index.html` of the publication, relative to the root directory,
* prepended with the IntelliJ project name.
*
* The path will be appended to [serverUri].
*
* The IntelliJ built-in server requires a relative path originating from the _parent_ directory
* The IntelliJ built-in server requires a relative path originating from the root directory
* of the IntelliJ project.
*
* For example,
*
* * given an IntelliJ project path of
* * given an IntelliJ project named `MyProject` located in a directory:
* ```
* /Users/rachel/projects/my-project/
* ```
* * and the publication is generated with an index file
* ```
* /Users/rachel/projects/my-project/docs/build/dokka/html/index.html
* ````
* * then IntelliJ requires [indexHtmlPath] is
* * then [indexHtmlPath] must be
* ```
* my-project/docs/build/dokka/html/index.html
* docs/build/dokka/html/index.html
* ```
* * so that (assuming [serverUri] is `http://localhost:63342`) the logged URL is
* ```
* http://localhost:63342/my-project/docs/build/dokka/html/index.html
* http://localhost:63342/MyProject/docs/build/dokka/html/index.html
* ```
*/
@get:Console
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,20 +187,26 @@ class GradleProjectTest(
* Builder for testing a Gradle project that uses Kotlin script DSL and creates default
* `settings.gradle.kts` and `gradle.properties` files.
*
* @param[testProjectName] the path of the project directory, relative to [baseDir
* @param[projectLocation] the path of the project directory, relative to [baseDir]
* @param[rootProjectName] the name of the Gradle project, configured in the `settings.gradle.kts`
*/
fun gradleKtsProjectTest(
testProjectName: String,
projectLocation: String,
rootProjectName: String? = null,
baseDir: Path = GradleProjectTest.funcTestTempDir,
build: GradleProjectTest.() -> Unit,
): GradleProjectTest {

val rootProjectNameValue: String = rootProjectName
?: projectLocation.removeSuffix("/").substringAfterLast('/')

return gradleProjectTest(
testProjectName = testProjectName,
testProjectName = rootProjectNameValue,
baseDir = baseDir,
) {

settingsGradleKts = """
|rootProject.name = "test"
|rootProject.name = "$rootProjectNameValue"
|
|${settingsRepositories()}
|
Expand All @@ -214,19 +220,24 @@ fun gradleKtsProjectTest(
* Builder for testing a Gradle project that uses Groovy script and creates default,
* `settings.gradle`, and `gradle.properties` files.
*
* @param[testProjectName] the name of the test, which should be distinct across the project
* @param[projectLocation] the path of the project directory, relative to [baseDir]
* @param[rootProjectName] the name of the Gradle project, configured in the `settings.gradle`
*/
fun gradleGroovyProjectTest(
testProjectName: String,
projectLocation: String,
rootProjectName: String? = null,
baseDir: Path = GradleProjectTest.funcTestTempDir,
build: GradleProjectTest.() -> Unit,
): GradleProjectTest {
val rootProjectNameValue: String = rootProjectName
?: projectLocation.removeSuffix("/").substringAfterLast('/')

return gradleProjectTest(
testProjectName = testProjectName,
testProjectName = rootProjectNameValue,
baseDir = baseDir,
) {
settingsGradle = """
|rootProject.name = "test"
|rootProject.name = "$rootProjectNameValue"
|
|${settingsRepositories()}
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import org.jetbrains.dokka.gradle.utils.*

fun TestScope.initMultiModuleProject(
testName: String,
rootProjectName: String? = null,
config: GradleProjectTest.() -> Unit = {},
): GradleProjectTest {

Expand All @@ -19,7 +20,10 @@ fun TestScope.initMultiModuleProject(
.substringAfter("org.jetbrains.dokka.gradle.") // drop the package name
.replaceNonAlphaNumeric()

return gradleKtsProjectTest("$baseDirName/multi-module-hello-goodbye/$testName") {
return gradleKtsProjectTest(
projectLocation = "$baseDirName/multi-module-hello-goodbye/$testName",
rootProjectName = rootProjectName,
) {

settingsGradleKts += """
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class DokkaPluginFunctionalTest : FunSpec({
|[Internal Dokka Configuration] Provides Dokka $format ModuleOutputDirectories files for consumption by other subprojects.
|
|Capabilities
| - :test:unspecified (default capability)
| - :DokkaPluginFunctionalTest:unspecified (default capability)
|Attributes
| - org.gradle.usage = org.jetbrains.dokka
| - org.jetbrains.dokka.format = $format
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class HtmlAggregationWarningTest : FunSpec({
private val expectedWarning = /* language=text */ """
|[:dokkaGeneratePublicationHtml] org.jetbrains.dokka:all-modules-page-plugin is missing.
|
|Publication 'test' in has 2 modules, but
|Dokka Publication 'no-all-pages-plugin' has 2 Dokka modules, but
|the Dokka Generator plugins classpath does not contain
| org.jetbrains.dokka:all-modules-page-plugin
|which is required for aggregating Dokka HTML modules.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class KotlinMultiplatformFunctionalTest : FunSpec({
}

context("expect HTML site is generated") {
val projectName = "kotlin-multiplatform-project"

test("with expected HTML files") {
project.projectDir
Expand All @@ -54,26 +55,26 @@ class KotlinMultiplatformFunctionalTest : FunSpec({
.shouldContainExactlyInAnyOrder(
"html/index.html",
"html/navigation.html",
"html/test/com.project/-hello/-hello.html",
"html/test/com.project/-hello/index.html",
"html/test/com.project/-hello/say-hello.html",
"html/test/com.project/goodbye.html",
"html/test/com.project/index.html",
"html/$projectName/com.project/-hello/-hello.html",
"html/$projectName/com.project/-hello/index.html",
"html/$projectName/com.project/-hello/say-hello.html",
"html/$projectName/com.project/goodbye.html",
"html/$projectName/com.project/index.html",
)
}

test("with element-list") {
project.projectDir.resolve("build/dokka/html/test/package-list").toFile().shouldBeAFile()
project.projectDir.resolve("build/dokka/html/test/package-list").readText()
project.projectDir.resolve("build/dokka/html/$projectName/package-list").toFile().shouldBeAFile()
project.projectDir.resolve("build/dokka/html/$projectName/package-list").readText()
.sortLines()
.shouldContain( /* language=text */ """
|${'$'}dokka.format:html-v1
|${'$'}dokka.linkExtension:html
|${'$'}dokka.location:com.project////PointingToDeclaration/test/com.project/index.html
|${'$'}dokka.location:com.project//goodbye/#kotlinx.serialization.json.JsonObject/PointingToDeclaration/test/com.project/goodbye.html
|${'$'}dokka.location:com.project/Hello///PointingToDeclaration/test/com.project/-hello/index.html
|${'$'}dokka.location:com.project/Hello/Hello/#/PointingToDeclaration/test/com.project/-hello/-hello.html
|${'$'}dokka.location:com.project/Hello/sayHello/#kotlinx.serialization.json.JsonObject/PointingToDeclaration/test/com.project/-hello/say-hello.html
|${'$'}dokka.location:com.project////PointingToDeclaration/$projectName/com.project/index.html
|${'$'}dokka.location:com.project//goodbye/#kotlinx.serialization.json.JsonObject/PointingToDeclaration/$projectName/com.project/goodbye.html
|${'$'}dokka.location:com.project/Hello///PointingToDeclaration/$projectName/com.project/-hello/index.html
|${'$'}dokka.location:com.project/Hello/Hello/#/PointingToDeclaration/$projectName/com.project/-hello/-hello.html
|${'$'}dokka.location:com.project/Hello/sayHello/#kotlinx.serialization.json.JsonObject/PointingToDeclaration/$projectName/com.project/-hello/say-hello.html
|com.project
""".trimMargin()
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,22 @@ class MultiModuleFunctionalTest : FunSpec({

context("build cache relocation") {

val originalProject = initMultiModuleProject("build-cache-relocation/original/")
val originalProject = initMultiModuleProject("build-cache-relocation/original/") {
buildGradleKts += """
dokka {
moduleName.set("demo-project")
}
""".trimIndent()
}
// Create the _same_ project in a different dir, to verify that the build cache
// can be re-used and doesn't have path-sensitive inputs/outputs.
val relocatedProject = initMultiModuleProject("build-cache-relocation/relocated/project/")
val relocatedProject = initMultiModuleProject("build-cache-relocation/relocated/project/") {
buildGradleKts += """
dokka {
moduleName.set("demo-project")
}
""".trimIndent()
}

// create custom build cache dir, so it's easier to control, specify, and clean-up
val buildCacheDir = originalProject.projectDir.resolve("build-cache")
Expand Down

0 comments on commit 0ff378b

Please sign in to comment.