Skip to content

Commit

Permalink
Move parts of Dokkatoo into gradle-plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
IgnatBeresnev committed Oct 19, 2023
1 parent cdd1fed commit e7565b4
Show file tree
Hide file tree
Showing 98 changed files with 9,034 additions and 10 deletions.
397 changes: 397 additions & 0 deletions dokka-runners/gradle-plugin/api/dokkatoo-plugin.api

Large diffs are not rendered by default.

254 changes: 254 additions & 0 deletions dokka-runners/gradle-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
@file:Suppress("UnstableApiUsage") // jvm test suites & test report aggregation are incubating

import buildsrc.utils.buildDir_
import buildsrc.utils.skipTestFixturesPublications

plugins {
buildsrc.conventions.`kotlin-gradle-plugin`
kotlin("plugin.serialization")

dev.adamko.kotlin.`binary-compatibility-validator`

dev.adamko.`dokkatoo-html`
buildsrc.conventions.`maven-publishing`

`java-test-fixtures`
`jvm-test-suite`
`test-report-aggregation`
buildsrc.conventions.`maven-publish-test`
}

description = "Generates documentation for Kotlin projects (using Dokka)"

dependencies {
// ideally there should be a 'dokka-core-api' dependency (that is very thin and doesn't drag in loads of unnecessary code)
// that would be used as an implementation dependency, while dokka-core would be used as a compileOnly dependency
// https://github.com/Kotlin/dokka/issues/2933
implementation(libs.kotlin.dokkaCore)

compileOnly(libs.gradlePlugin.kotlin)
compileOnly(libs.gradlePlugin.kotlin.klibCommonizerApi)
compileOnly(libs.gradlePlugin.android)
compileOnly(libs.gradlePlugin.androidApi)

implementation(platform(libs.kotlinxSerialization.bom))
implementation(libs.kotlinxSerialization.json)

testFixturesImplementation(gradleApi())
testFixturesImplementation(gradleTestKit())

testFixturesCompileOnly(libs.kotlin.dokkaCore)
testFixturesImplementation(platform(libs.kotlinxSerialization.bom))
testFixturesImplementation(libs.kotlinxSerialization.json)

testFixturesCompileOnly(libs.kotlin.dokkaCore)

testFixturesApi(platform(libs.kotest.bom))
testFixturesApi(libs.kotest.junit5Runner)
testFixturesApi(libs.kotest.assertionsCore)
testFixturesApi(libs.kotest.assertionsJson)
testFixturesApi(libs.kotest.datatest)

// don't define test dependencies here, instead define them in the testing.suites {} configuration below
}

gradlePlugin {
isAutomatedPublishing = true

plugins.register("dokkatoo") {
id = "org.jetbrains.dokka.dokkatoo"
displayName = "Dokkatoo"
description = "Generates documentation for Kotlin projects (using Dokka)"
implementationClass = "org.jetbrains.dokka.dokkatoo.DokkatooPlugin"
}

fun registerDokkaPlugin(
pluginClass: String,
shortName: String,
longName: String = shortName,
) {
plugins.register(pluginClass) {
id = "org.jetbrains.dokka.dokkatoo-${shortName.toLowerCase()}"
displayName = "Dokkatoo $shortName"
description = "Generates $longName documentation for Kotlin projects (using Dokka)"
implementationClass = "org.jetbrains.dokka.dokkatoo.formats.$pluginClass"
}
}
registerDokkaPlugin("DokkatooGfmPlugin", "GFM", longName = "GFM (GitHub Flavoured Markdown)")
registerDokkaPlugin("DokkatooHtmlPlugin", "HTML")
registerDokkaPlugin("DokkatooJavadocPlugin", "Javadoc")
registerDokkaPlugin("DokkatooJekyllPlugin", "Jekyll")

plugins.configureEach {
website.set("https://github.com/adamko-dev/dokkatoo/")
vcsUrl.set("https://github.com/adamko-dev/dokkatoo.git")
tags.addAll(
"dokka",
"dokkatoo",
"kotlin",
"kdoc",
"android",
"documentation",
"javadoc",
"html",
"markdown",
"gfm",
"website",
)
}
}

kotlin {
target {
compilations.configureEach {
// TODO Dokkatoo uses Gradle 8, while Dokka uses Gradle 7, which has an older version of Kotlin that
// doesn't include these options - so update them or update Gradle.
// compilerOptions.configure {
// freeCompilerArgs.addAll(
// "-opt-in=org.jetbrains.dokka.dokkatoo.internal.DokkatooInternalApi",
// )
// }
}
}
}

testing.suites {
withType<JvmTestSuite>().configureEach {
useJUnitJupiter()

dependencies {
implementation(project.dependencies.gradleTestKit())

implementation(project.dependencies.testFixtures(project()))

implementation(project.dependencies.platform(libs.kotlinxSerialization.bom))
implementation(libs.kotlinxSerialization.json)
}

targets.configureEach {
testTask.configure {
val projectTestTempDirPath = "$buildDir_/test-temp-dir"
inputs.property("projectTestTempDir", projectTestTempDirPath)
systemProperty("projectTestTempDir", projectTestTempDirPath)

when (testType.get()) {
TestSuiteType.FUNCTIONAL_TEST,
TestSuiteType.INTEGRATION_TEST -> {
dependsOn(tasks.matching { it.name == "publishAllPublicationsToTestRepository" })

systemProperties(
"testMavenRepoDir" to file(mavenPublishTest.testMavenRepo).canonicalPath,
)

// depend on the test-publication task, but not the test-maven repo
// (otherwise this task will never be up-to-date)
dependsOn(tasks.publishToTestMavenRepo)
}
}
}
}
}


/** Unit tests suite */
val test by getting(JvmTestSuite::class) {
description = "Standard unit tests"
}


/** Functional tests suite */
val testFunctional by registering(JvmTestSuite::class) {
description = "Tests that use Gradle TestKit to test functionality"
testType.set(TestSuiteType.FUNCTIONAL_TEST)

targets.all {
testTask.configure {
shouldRunAfter(test)
}
}
}

tasks.check { dependsOn(test, testFunctional) }
}

skipTestFixturesPublications()

val aggregateTestReports by tasks.registering(TestReport::class) {
group = LifecycleBasePlugin.VERIFICATION_GROUP
destinationDirectory.set(layout.buildDirectory.dir("reports/tests/aggregated"))

dependsOn(tasks.withType<AbstractTestTask>())

// hardcoded dirs is a bit of a hack, but a fileTree just didn't work
testResults.from("$buildDir_/test-results/test/binary")
testResults.from("$buildDir_/test-results/testFunctional/binary")
testResults.from("$buildDir_/test-results/testIntegration/binary")

doLast {
logger.lifecycle("Aggregated test report: file://${destinationDirectory.asFile.get()}/index.html")
}
}

binaryCompatibilityValidator {
ignoredMarkers.add("org.jetbrains.dokka.dokkatoo.internal.DokkatooInternalApi")
}

val dokkatooVersion = provider { project.version.toString() }

val dokkatooConstantsProperties = objects.mapProperty<String, String>().apply {
put("DOKKATOO_VERSION", dokkatooVersion)
put("DOKKA_VERSION", libs.versions.kotlin.dokka)
}

val buildConfigFileContents: Provider<TextResource> =
dokkatooConstantsProperties.map { constants ->

val vals = constants.entries
.sortedBy { it.key }
.joinToString("\n") { (k, v) ->
"""const val $k = "$v""""
}.prependIndent(" ")

resources.text.fromString(
"""
|package org.jetbrains.dokka.dokkatoo.internal
|
|@DokkatooInternalApi
|object DokkatooConstants {
|$vals
|}
|
""".trimMargin()
)
}

val generateDokkatooConstants by tasks.registering(Sync::class) {
group = project.name

val buildConfigFileContents = buildConfigFileContents

from(buildConfigFileContents) {
rename { "DokkatooConstants.kt" }
into("dev/adamko/dokkatoo/internal/")
}

into(layout.buildDirectory.dir("generated-source/main/kotlin/"))
}

kotlin.sourceSets.main {
kotlin.srcDir(generateDokkatooConstants.map { it.destinationDir })
}

dokkatoo {
dokkatooSourceSets.configureEach {
externalDocumentationLinks.register("gradle") {
// https://docs.gradle.org/current/javadoc/index.html
url("https://docs.gradle.org/${gradle.gradleVersion}/javadoc/")
}
sourceLink {
localDirectory.set(file("src/main/kotlin"))
val relativeProjectPath = projectDir.relativeToOrNull(rootDir)?.invariantSeparatorsPath ?: ""
remoteUrl("https://github.com/adamko-dev/dokkatoo/tree/main/$relativeProjectPath/src/main/kotlin")
}
}
}
19 changes: 19 additions & 0 deletions dokka-runners/gradle-plugin/buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import org.gradle.kotlin.dsl.support.expectedKotlinDslPluginsVersion

plugins {
`kotlin-dsl`
}

dependencies {
implementation("org.gradle.kotlin:gradle-kotlin-dsl-plugins:$expectedKotlinDslPluginsVersion")
implementation(libs.gradlePlugin.bcvMu)
implementation(libs.gradlePlugin.dokkatoo)
implementation(libs.gradlePlugin.gradlePublishPlugin)
implementation("org.jetbrains.kotlin:kotlin-serialization:$embeddedKotlinVersion")
}

java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(11))
}
}
31 changes: 31 additions & 0 deletions dokka-runners/gradle-plugin/buildSrc/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/

rootProject.name = "buildSrc"

pluginManagement {
repositories {
mavenCentral()
gradlePluginPortal()
google()
}
}

@Suppress("UnstableApiUsage")
dependencyResolutionManagement {

repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)

repositories {
mavenCentral()
gradlePluginPortal()
google()
}

versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package buildsrc.conventions

import org.jetbrains.kotlin.util.suffixIfNot


/**
* Utilities for preparing Android projects
*/

plugins {
base
id("buildsrc.conventions.base")
}


val androidSdkDirPath: Provider<String> = providers
// first try getting the SDK installed on via GitHub step setup-android
.environmentVariable("ANDROID_SDK_ROOT").map(::File)
// else get the project-local SDK
.orElse(layout.projectDirectory.file("projects/ANDROID_SDK").asFile)
.map { it.invariantSeparatorsPath }


val createAndroidLocalPropertiesFile by tasks.registering {

val localPropertiesFile = temporaryDir.resolve("local.properties")
outputs.file(localPropertiesFile).withPropertyName("localPropertiesFile")

val androidSdkDirPath = androidSdkDirPath
inputs.property("androidSdkDirPath", androidSdkDirPath)

doLast {
localPropertiesFile.apply {
parentFile.mkdirs()
createNewFile()
writeText(
"""
|# DO NOT EDIT - Generated by $path
|
|sdk.dir=${androidSdkDirPath.get()}
|
""".trimMargin()
)
}
}
}


val updateAndroidLocalProperties by tasks.registering {

// find all local.properties files
val localPropertiesFiles = layout.projectDirectory.dir("projects")
.asFileTree
.matching { include("**/local.properties") }
.files

outputs.files(localPropertiesFiles).withPropertyName("localPropertiesFiles")

val androidSdkDirPath = androidSdkDirPath
inputs.property("androidSdkDirPath", androidSdkDirPath)

doLast {
localPropertiesFiles
.filter { it.exists() }
.forEach { file ->
file.writeText(
file.useLines { lines ->
lines.joinToString("\n") { line ->
when {
line.startsWith("sdk.dir=") -> "sdk.dir=${androidSdkDirPath.get()}"
else -> line
}
}.suffixIfNot("\n")
}
)
}
}
}
Loading

0 comments on commit e7565b4

Please sign in to comment.