Skip to content

Commit

Permalink
add warning if the html log link 404s
Browse files Browse the repository at this point in the history
- add tests for log link task
- minor tidying
  • Loading branch information
aSemy committed Nov 29, 2023
1 parent 1a73111 commit 9619e4d
Show file tree
Hide file tree
Showing 8 changed files with 258 additions and 28 deletions.
9 changes: 9 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ kotlin = "1.9.0" # should match Gradle's embedded Kotlin version https://docs.gr
kotlin-dokka = "1.9.0"
kotlinx-serialization = "1.6.0"

ktor = "2.3.6"

kotest = "5.6.2"

gradlePlugin-android = "8.0.2"
Expand All @@ -24,6 +26,13 @@ kotlinxSerialization-bom = { module = "org.jetbrains.kotlinx:kotlinx-serializati
kotlinxSerialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json" }
#kotlinxSerialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" }

##region ktor
ktor-bom = { group = "io.ktor", name = "ktor-bom", version.ref = "ktor" }

ktorServer-core = { group = "io.ktor", name = "ktor-server-core" }
ktorServer-cio = { group = "io.ktor", name = "ktor-server-cio" }
##endregion


### Test libraries ###

Expand Down
6 changes: 6 additions & 0 deletions modules/dokkatoo-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,12 @@ testing.suites {
shouldRunAfter(test)
}
}

dependencies {
implementation(project.dependencies.platform(libs.ktor.bom))
implementation(libs.ktorServer.core)
implementation(libs.ktorServer.cio)
}
}

tasks.check { dependsOn(test, testFunctional) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import dev.adamko.dokkatoo.DokkatooExtension
import dev.adamko.dokkatoo.adapters.DokkatooAndroidAdapter
import dev.adamko.dokkatoo.adapters.DokkatooJavaAdapter
import dev.adamko.dokkatoo.adapters.DokkatooKotlinAdapter
import dev.adamko.dokkatoo.internal.*
import dev.adamko.dokkatoo.internal.DokkatooInternalApi
import javax.inject.Inject
import org.gradle.api.Plugin
import org.gradle.api.Project
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ constructor() : DokkatooFormatPlugin(formatName = "html") {
private fun DokkatooFormatPluginContext.registerLogHtmlUrlTask():
TaskProvider<LogHtmlPublicationLinkTask> {

val indexHtmlFile = dokkatooTasks.generatePublication
val generatePublicationTask = dokkatooTasks.generatePublication

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

val indexHtmlPath = indexHtmlFile.map { indexHtml ->
Expand All @@ -63,8 +65,10 @@ constructor() : DokkatooFormatPlugin(formatName = "html") {
}

return project.tasks.register<LogHtmlPublicationLinkTask>(
"logLink" + dokkatooTasks.generatePublication.name.uppercaseFirstChar()
"logLink" + generatePublicationTask.name.uppercaseFirstChar()
) {
// default port of IntelliJ built-in server is defined in the docs
// https://www.jetbrains.com/help/idea/settings-debugger.html#24aabda8
serverUri.convention("http://localhost:63342")
this.indexHtmlPath.convention(indexHtmlPath)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,24 @@ import org.gradle.api.tasks.Console
import org.gradle.api.tasks.TaskAction
import org.gradle.kotlin.dsl.*
import org.gradle.work.DisableCachingByDefault
import org.slf4j.LoggerFactory

/**
* Prints an HTTP link in the console when the HTML publication is generated.
*
* The HTML publication requires a web server, since it loads resources via javascript.
*
* By default, it uses
* [IntelliJ's built-in server](https://www.jetbrains.com/help/idea/php-built-in-web-server.html)
* [IntelliJ's built-in server](https://www.jetbrains.com/help/phpstorm/php-built-in-web-server.html#ws_html_preview_output_built_in_browser)†
* to host the file.
*
*
* This task can be disabled using the [ENABLE_TASK_PROPERTY_NAME] project property.
*
* ---
*
* † For some reason there 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")
abstract class LogHtmlPublicationLinkTask
Expand Down Expand Up @@ -56,7 +63,7 @@ constructor(
* ```
* /Users/rachel/projects/my-project/docs/build/dokka/html/index.html
* ````
* * then IntelliJ requires the [indexHtmlPath] is
* * then IntelliJ requires [indexHtmlPath] is
* ```
* my-project/docs/build/dokka/html/index.html
* ```
Expand Down Expand Up @@ -85,17 +92,37 @@ constructor(
super.onlyIf("task is enabled via property") {
logHtmlPublicationLinkTaskEnabled.get()
}

super.onlyIf("${::serverUri.name} is present") {
!serverUri.orNull.isNullOrBlank()
}

super.onlyIf("${::indexHtmlPath.name} is present") {
!indexHtmlPath.orNull.isNullOrBlank()
}
}

@TaskAction
fun exec() {
val serverUri = serverUri.orNull
val filePath = indexHtmlPath.orNull
val serverUri = serverUri.get()
val indexHtmlPath = indexHtmlPath.get()

if (serverUri != null && !filePath.isNullOrBlank()) {
val link = URI(serverUri).appendPath(filePath).toString()
logger.info(
"LogHtmlPublicationLinkTask received variables " +
"serverUri:$serverUri, " +
"indexHtmlPath:$indexHtmlPath"
)

logger.lifecycle("Generated Dokka HTML publication: $link")
val link = URI(serverUri).appendPath(indexHtmlPath)

logger.lifecycle("Generated Dokka HTML publication: $link")

val statusCode = httpGet(link).statusCode()
if (statusCode !in 200..299) {
logger.warn(
"Warning: $link returned unsuccessful status code $statusCode. " +
"Does the index.html file exist, or is the server misconfigured?"
)
}
}

Expand All @@ -110,27 +137,27 @@ constructor(
*/
internal abstract class ServerActiveCheck : ValueSource<Boolean, ServerActiveCheck.Parameters> {

private val logger = LoggerFactory.getLogger(ServerActiveCheck::class.java)

interface Parameters : ValueSourceParameters {
/** E.g. `http://localhost:63342` */
/**
* IntelliJ built-in server's default address is `http://localhost:63342`
* See https://www.jetbrains.com/help/idea/settings-debugger.html.
*/
val uri: Property<String>
}

override fun obtain(): Boolean {
try {
return try {
val uri = URI.create(parameters.uri.get())
val client = HttpClient.newHttpClient()
val request = HttpRequest
.newBuilder()
.uri(uri)
.timeout(Duration.ofSeconds(1))
.GET()
.build()
val response = client.send(request, HttpResponse.BodyHandlers.ofString())
val response = httpGet(uri)

// don't care about the status - only if the server is available
return response.statusCode() > 0
logger.info("got ${response.statusCode()} from $uri")
response.statusCode() > 0
} catch (ex: Exception) {
return false
logger.info("could not reach URI ${parameters.uri.get()}: $ex")
false
}
}
}
Expand All @@ -140,8 +167,10 @@ constructor(
* Control whether the [LogHtmlPublicationLinkTask] task is enabled. Useful for disabling the
* task locally, or in CI/CD, or for tests.
*
* It can be set in any `gradle.properties` file. For example, on a specific machine:
*
* ```properties
* #$GRADLE_USER_HOME/gradle.properties
* # $GRADLE_USER_HOME/gradle.properties
* dev.adamko.dokkatoo.tasks.logHtmlPublicationLinkEnabled=false
* ```
*
Expand All @@ -152,5 +181,16 @@ constructor(
* ```
*/
const val ENABLE_TASK_PROPERTY_NAME = "dev.adamko.dokkatoo.tasks.logHtmlPublicationLinkEnabled"

private fun httpGet(uri: URI): HttpResponse<String> {
val client = HttpClient.newHttpClient()
val request = HttpRequest
.newBuilder()
.uri(uri)
.timeout(Duration.ofSeconds(1))
.GET()
.build()
return client.send(request, HttpResponse.BodyHandlers.ofString())
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,19 @@ class GradleProjectTest(
baseDir: Path = funcTestTempDir,
) : this(projectDir = baseDir.resolve(testProjectName))

/** Args that will be added to every [runner] */
val defaultRunnerArgs: MutableList<String> = mutableListOf(
// disable the logging task so the tests work consistently on local machines and CI/CD
"-P" + "dev.adamko.dokkatoo.tasks.logHtmlPublicationLinkEnabled=false"
)

val runner: GradleRunner
get() = GradleRunner.create()
.withProjectDir(projectDir.toFile())
.withJvmArguments(
"-XX:MaxMetaspaceSize=512m",
"-XX:+AlwaysPreTouch", // https://github.com/gradle/gradle/issues/3093#issuecomment-387259298
).addArguments(
// disable the logging task so the tests work consistently on local machines and CI/CD
"-P" + "dev.adamko.dokkatoo.tasks.logHtmlPublicationLinkEnabled=false"
)
).addArguments(*defaultRunnerArgs.toTypedArray())

val testMavenRepoRelativePath: String =
projectDir.relativize(testMavenRepoDir).toFile().invariantSeparatorsPath
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class DokkatooPluginFunctionalTest : FunSpec({
}

test("expect Dokka Plugin creates Dokka outgoing variants") {
val build = testProject.runner
testProject.runner
.addArguments("outgoingVariants", "-q")
.build {
val variants = output.invariantNewlines().replace('\\', '/')
Expand Down
Loading

0 comments on commit 9619e4d

Please sign in to comment.