diff options
author | Ignat Beresnev <ignat.beresnev@jetbrains.com> | 2023-01-10 13:14:43 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-10 13:14:43 +0100 |
commit | 7544a215fb580ae0c47d1f397334f150d1a1ec65 (patch) | |
tree | a30aa62c827e3ba88a498a7406ac57fa7334b270 | |
parent | 2161c397e1b1aadcf3d39c8518258e9bdb2b431a (diff) | |
download | dokka-7544a215fb580ae0c47d1f397334f150d1a1ec65.tar.gz dokka-7544a215fb580ae0c47d1f397334f150d1a1ec65.tar.bz2 dokka-7544a215fb580ae0c47d1f397334f150d1a1ec65.zip |
Revise documentation (#2728)
Co-authored-by: Sarah Haggarty <sarahhaggarty@users.noreply.github.com>
78 files changed, 5734 insertions, 626 deletions
diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 9a744d38..8bb860fe 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -19,8 +19,8 @@ jobs: id: filter with: filters: | - docs_changed: - - 'docs/**' + mkdocs_changed: + - 'mkdocs/**' working-directory: ./dokka - uses: actions/setup-java@v3 with: @@ -30,17 +30,17 @@ jobs: - uses: gradle/gradle-build-action@v2 - name: Get current dokka version run: echo "DOKKA_VERSION=`./gradlew :properties | grep '^version:.*' | cut -d ' ' -f 2`" >> $GITHUB_ENV - if: github.event_name == 'release' || steps.filter.outputs.docs_changed == 'true' + if: github.event_name == 'release' || steps.filter.outputs.mkdocs_changed == 'true' working-directory: ./dokka - name: Build docs run: ./gradlew mkdocsBuild -Pdokka_version=$DOKKA_VERSION --info - if: github.event_name == 'release' || steps.filter.outputs.docs_changed == 'true' + if: github.event_name == 'release' || steps.filter.outputs.mkdocs_changed == 'true' working-directory: ./dokka - name: Deploy uses: peaceiris/actions-gh-pages@v3 - if: github.event_name == 'release' || steps.filter.outputs.docs_changed == 'true' + if: github.event_name == 'release' || steps.filter.outputs.mkdocs_changed == 'true' with: github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./dokka/docs/build/mkdocs + publish_dir: ./dokka/mkdocs/build/mkdocs keep_files: true full_commit_message: Publish ${{ env.DOKKA_VERSION }} documentation diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 92bc9105..ca58ff4d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,7 +29,7 @@ Here's how to import and configure Dokka in IntelliJ IDEA: If you want to use/test your locally built Dokka in a project, do the following: 1. Change `dokka_version` in `gradle.properties` to something that you will use later on as the dependency version. - For instance, you can set it to something like `1.7.20-my-fix-SNAPSHOT`. + For example, you can set it to something like `1.7.20-my-fix-SNAPSHOT`. 2. Publish it to maven local (`./gradlew publishToMavenLocal`) 3. In the project you want to generate documentation for, add maven local as a plugin/dependency repository (`mavenLocal()`) diff --git a/core/api/core.api b/core/api/core.api index 7d29d872..c85a3347 100644 --- a/core/api/core.api +++ b/core/api/core.api @@ -57,10 +57,6 @@ public final class org/jetbrains/dokka/DokkaBootstrapImpl$DokkaProxyLogger : org public fun warn (Ljava/lang/String;)V } -public final class org/jetbrains/dokka/DokkaBootstrapImplKt { - public static final fun parsePerPackageOptions (Ljava/util/List;)Ljava/util/List; -} - public abstract interface class org/jetbrains/dokka/DokkaConfiguration : java/io/Serializable { public abstract fun getCacheRoot ()Ljava/io/File; public abstract fun getDelayTemplateSubstitution ()Z @@ -212,9 +208,9 @@ public final class org/jetbrains/dokka/DokkaDefaults { public static final field INSTANCE Lorg/jetbrains/dokka/DokkaDefaults; public static final field delayTemplateSubstitution Z public static final field failOnWarning Z - public static final field format Ljava/lang/String; public static final field includeNonPublic Z public static final field jdkVersion I + public static final field noAndroidSdkLink Z public static final field noJdkLink Z public static final field noStdlibLink Z public static final field offlineMode Z @@ -224,6 +220,7 @@ public final class org/jetbrains/dokka/DokkaDefaults { public static final field sourceSetDisplayName Ljava/lang/String; public static final field sourceSetName Ljava/lang/String; public static final field suppress Z + public static final field suppressGeneratedFiles Z public static final field suppressInheritedMembers Z public static final field suppressObviousFunctions Z public final fun getAnalysisPlatform ()Lorg/jetbrains/dokka/Platform; diff --git a/core/src/main/kotlin/DokkaBootstrapImpl.kt b/core/src/main/kotlin/DokkaBootstrapImpl.kt index 75c4c0af..114bade7 100644 --- a/core/src/main/kotlin/DokkaBootstrapImpl.kt +++ b/core/src/main/kotlin/DokkaBootstrapImpl.kt @@ -1,45 +1,9 @@ package org.jetbrains.dokka -import org.jetbrains.dokka.DokkaConfiguration.PackageOptions import org.jetbrains.dokka.utilities.DokkaLogger import java.util.function.BiConsumer - -fun parsePerPackageOptions(args: List<String>): List<PackageOptions> = args.map { it.split(",") }.map { - val matchingRegex = it.first() - - val options = it.subList(1, it.size) - - val deprecated = options.find { it.endsWith("skipDeprecated") }?.startsWith("+") - ?: DokkaDefaults.skipDeprecated - - val reportUndocumented = options.find { it.endsWith("reportUndocumented") }?.startsWith("+") - ?: DokkaDefaults.reportUndocumented - - val privateApi = options.find { it.endsWith("includeNonPublic") }?.startsWith("+") - ?: DokkaDefaults.includeNonPublic - - val suppress = options.find { it.endsWith("suppress") }?.startsWith("+") - ?: DokkaDefaults.suppress - - val documentedVisibilities = options - .filter { it.matches(Regex("\\+visibility:.+")) } // matches '+visibility:' with at least one symbol after the semicolon - .map { DokkaConfiguration.Visibility.fromString(it.split(":")[1]) } - .toSet() - .ifEmpty { DokkaDefaults.documentedVisibilities } - - PackageOptionsImpl( - matchingRegex, - includeNonPublic = privateApi, - documentedVisibilities = documentedVisibilities, - reportUndocumented = reportUndocumented, - skipDeprecated = !deprecated, - suppress = suppress - ) -} - - /** * Accessed with reflection */ diff --git a/core/src/main/kotlin/configuration.kt b/core/src/main/kotlin/configuration.kt index c26faf28..77384ace 100644 --- a/core/src/main/kotlin/configuration.kt +++ b/core/src/main/kotlin/configuration.kt @@ -12,30 +12,38 @@ import java.net.URL object DokkaDefaults { val moduleName: String = "root" + val moduleVersion: String? = null val outputDir = File("./dokka") - const val format: String = "html" - val cacheRoot: File? = null - const val offlineMode: Boolean = false const val failOnWarning: Boolean = false - const val delayTemplateSubstitution: Boolean = false + const val suppressObviousFunctions = true + const val suppressInheritedMembers = false + const val offlineMode: Boolean = false + + const val sourceSetDisplayName = "JVM" + const val sourceSetName = "main" + val analysisPlatform: Platform = Platform.DEFAULT + + const val suppress: Boolean = false + const val suppressGeneratedFiles: Boolean = true - const val includeNonPublic: Boolean = false - val documentedVisibilities: Set<DokkaConfiguration.Visibility> = setOf(DokkaConfiguration.Visibility.PUBLIC) - const val reportUndocumented: Boolean = false const val skipEmptyPackages: Boolean = true const val skipDeprecated: Boolean = false - const val jdkVersion: Int = 8 + + const val reportUndocumented: Boolean = false + const val noStdlibLink: Boolean = false + const val noAndroidSdkLink: Boolean = false const val noJdkLink: Boolean = false - val analysisPlatform: Platform = Platform.DEFAULT - const val suppress: Boolean = false + const val jdkVersion: Int = 8 + + const val includeNonPublic: Boolean = false + val documentedVisibilities: Set<DokkaConfiguration.Visibility> = setOf(DokkaConfiguration.Visibility.PUBLIC) - const val sourceSetDisplayName = "JVM" - const val sourceSetName = "main" - val moduleVersion: String? = null val pluginsConfiguration = mutableListOf<PluginConfigurationImpl>() - const val suppressObviousFunctions = true - const val suppressInheritedMembers = false + + const val delayTemplateSubstitution: Boolean = false + + val cacheRoot: File? = null } enum class Platform(val key: String) { @@ -88,10 +96,12 @@ data class DokkaSourceSetID( fun DokkaConfigurationImpl(json: String): DokkaConfigurationImpl = parseJson(json) /** - * Global options are applied to all packages and modules and overwrite package configuration. + * Global options can be configured and applied to all packages and modules at once, overwriting package configuration. + * + * These are handy if we have multiple source sets sharing the same global options as it reduces the size of the + * boilerplate. Otherwise, the user would be forced to repeat all these options for each source set. * - * These are handy if we have multiple sourcesets sharing the same global options as it reduces the size of the boilerplate. - * Otherwise, the user would be enforced to repeat all these options per each sourceset. + * @see [apply] to learn how to apply global configuration */ data class GlobalDokkaConfiguration( val perPackageOptions: List<PackageOptionsImpl>?, diff --git a/core/src/main/kotlin/defaultConfiguration.kt b/core/src/main/kotlin/defaultConfiguration.kt index 8c7c8b5d..66154570 100644 --- a/core/src/main/kotlin/defaultConfiguration.kt +++ b/core/src/main/kotlin/defaultConfiguration.kt @@ -71,9 +71,9 @@ data class SourceLinkDefinitionImpl( fun parseSourceLinkDefinition(srcLink: String): SourceLinkDefinitionImpl { val (path, urlAndLine) = srcLink.split('=') return SourceLinkDefinitionImpl( - File(path).canonicalPath, - URL(urlAndLine.substringBefore("#")), - urlAndLine.substringAfter("#", "").let { if (it.isEmpty()) null else "#$it" }) + localDirectory = File(path).canonicalPath, + remoteUrl = URL(urlAndLine.substringBefore("#")), + remoteLineSuffix = urlAndLine.substringAfter("#", "").let { if (it.isEmpty()) null else "#$it" }) } } } @@ -85,7 +85,7 @@ data class PackageOptionsImpl( override val reportUndocumented: Boolean?, override val skipDeprecated: Boolean, override val suppress: Boolean, - override val documentedVisibilities: Set<DokkaConfiguration.Visibility>, + override val documentedVisibilities: Set<DokkaConfiguration.Visibility>, // TODO add default to DokkaDefaults.documentedVisibilities ) : DokkaConfiguration.PackageOptions diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..686c95bd --- /dev/null +++ b/docs/README.md @@ -0,0 +1,9 @@ +# Dokka documentation + +This folder contains the Dokka documentation that is available on [kotlinlang.org](https://kotlinlang.org/). + +Our documentation is written in Markdown format with some domain specific language (DSL) constructs that are used at +JetBrains. + +If you wish to contribute to the documentation, please read through +[Kotlin documentation guidelines](https://docs.google.com/document/d/1mUuxK4xwzs3jtDGoJ5_zwYLaSEl13g_SuhODdFuh2Dc/edit). diff --git a/docs/cfg/buildprofiles.xml b/docs/cfg/buildprofiles.xml new file mode 100644 index 00000000..86c3ad59 --- /dev/null +++ b/docs/cfg/buildprofiles.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<buildprofiles> + <variables> + <enable-browser-edits>true</enable-browser-edits> + <browser-edits-url>https://github.com/Kotlin/dokka/edit/master/docs/</browser-edits-url> + <allow-indexable-eaps>true</allow-indexable-eaps> + </variables> + <build-profile product="kl"/> +</buildprofiles> diff --git a/docs/dokka.tree b/docs/dokka.tree new file mode 100644 index 00000000..73ac277e --- /dev/null +++ b/docs/dokka.tree @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE product-profile + SYSTEM "https://resources.jetbrains.com/stardust/product-profile.dtd"> + +<product-profile id="kl" + name="dokka" + start-page="dokka-introduction.md"> + + <chunk include-id="dokka"> + <toc-element id="dokka-introduction.md"/> + <toc-element id="dokka-get-started.md"/> + <toc-element toc-title="Run Dokka"> + <toc-element id="dokka-gradle.md"/> + <toc-element id="dokka-maven.md"/> + <toc-element id="dokka-cli.md"/> + </toc-element> + <toc-element toc-title="Output formats"> + <toc-element id="dokka-html.md"/> + <toc-element id="dokka-markdown.md"/> + <toc-element id="dokka-javadoc.md"/> + </toc-element> + <toc-element id="dokka-plugins.md"/> + </chunk> +</product-profile> diff --git a/docs/images/dokkaHtmlCollector-example.png b/docs/images/dokkaHtmlCollector-example.png Binary files differnew file mode 100644 index 00000000..5bd74d8d --- /dev/null +++ b/docs/images/dokkaHtmlCollector-example.png diff --git a/docs/images/dokkaHtmlMultiModule-example.png b/docs/images/dokkaHtmlMultiModule-example.png Binary files differnew file mode 100644 index 00000000..f5091f56 --- /dev/null +++ b/docs/images/dokkaHtmlMultiModule-example.png diff --git a/docs/images/javadoc-format-example.png b/docs/images/javadoc-format-example.png Binary files differnew file mode 100644 index 00000000..45ac585c --- /dev/null +++ b/docs/images/javadoc-format-example.png diff --git a/docs/images/versioning-plugin-example.png b/docs/images/versioning-plugin-example.png Binary files differnew file mode 100644 index 00000000..cd02c558 --- /dev/null +++ b/docs/images/versioning-plugin-example.png diff --git a/docs/project.ihp b/docs/project.ihp new file mode 100644 index 00000000..f9ab9b9e --- /dev/null +++ b/docs/project.ihp @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE ihp SYSTEM "https://resources.jetbrains.com/stardust/ihp.dtd"> + +<ihp version="2.0"> +<!-- <categories src="categories.list"/>--> + <module name="dokka"/> + <topics dir="topics"/> + <images dir="images"/> + <vars src="vars.list"/> + <product src="dokka.tree" version="%dokkaVersion%" /> + <settings> + <default-property element-name="toc-element" property-name="show-structure-depth" value="2"/> + </settings> +</ihp> diff --git a/docs/topics/dokka-get-started.md b/docs/topics/dokka-get-started.md new file mode 100644 index 00000000..df4ab7e5 --- /dev/null +++ b/docs/topics/dokka-get-started.md @@ -0,0 +1,95 @@ +[//]: # (title: Get started) + +Below you can find simple instructions to help you get started with Dokka. + +<tabs group="build-script"> +<tab title="Gradle Kotlin DSL" group-key="kotlin"> + +Apply the Gradle plugin for Dokka in the root build script of your project: + +```kotlin +plugins { + id("org.jetbrains.dokka") version "%dokkaVersion%" +} +``` + +When documenting [multi-project](https://docs.gradle.org/current/userguide/multi_project_builds.html) builds, you need +to apply the Gradle plugin within subprojects as well: + +```kotlin +subprojects { + apply(plugin = "org.jetbrains.dokka") +} +``` + +To generate documentation, run the following Gradle tasks: + +* `dokkaHtml` for single-project builds +* `dokkaHtmlMultiModule` for multi-project builds + +By default, the output directory is set to `/build/dokka/html` and `/build/dokka/htmlMultiModule`. + +To learn more about using Dokka with Gradle, see [Gradle](dokka-gradle.md). + +</tab> +<tab title="Gradle Groovy DSL" group-key="groovy"> + +Apply the Gradle plugin for Dokka in the root build script of your project: + +```groovy +plugins { + id 'org.jetbrains.dokka' version '%dokkaVersion%' +} +``` + +When documenting [multi-project](https://docs.gradle.org/current/userguide/multi_project_builds.html) builds, you need +to apply the Gradle plugin within subprojects as well: + +```groovy +subprojects { + apply plugin: 'org.jetbrains.dokka' +} +``` + +To generate documentation, run the following Gradle tasks: + +* `dokkaHtml` for single-project builds +* `dokkaHtmlMultiModule` for multi-project builds + +By default, the output directory is set to `/build/dokka/html` and `/build/dokka/htmlMultiModule`. + +To learn more about using Dokka with Gradle, see [Gradle](dokka-gradle.md). + +</tab> +<tab title="Maven" group-key="mvn"> + +Add the Maven plugin for Dokka to the `plugins` section of your POM file: + +```xml +<build> + <plugins> + <plugin> + <groupId>org.jetbrains.dokka</groupId> + <artifactId>dokka-maven-plugin</artifactId> + <version>%dokkaVersion%</version> + <executions> + <execution> + <phase>pre-site</phase> + <goals> + <goal>dokka</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> +</build> +``` + +To generate documentation, run the `dokka:dokka` goal. + +By default, the output directory is set to `target/dokka`. + +To learn more about using Dokka with Maven, see [Maven](dokka-maven.md). + +</tab> +</tabs> diff --git a/docs/topics/dokka-introduction.md b/docs/topics/dokka-introduction.md new file mode 100644 index 00000000..cc5cef78 --- /dev/null +++ b/docs/topics/dokka-introduction.md @@ -0,0 +1,28 @@ +[//]: # (title: Introduction) + +Dokka is an API documentation engine for Kotlin. + +Just like Kotlin itself, Dokka supports mixed-language projects. It understands Kotlin's +[KDoc comments](https://kotlinlang.org/docs/kotlin-doc.html#kdoc-syntax) and Java's +[Javadoc comments](https://www.oracle.com/technical-resources/articles/java/javadoc-tool.html). + +Dokka can generate documentation in multiple formats, including its own modern [HTML format](dokka-html.md), +multiple flavors of [Markdown](dokka-markdown.md), and Java's [Javadoc HTML](dokka-javadoc.md). + +Here are some libraries that use Dokka for their API reference documentation: + +* [kotlinx.coroutines](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/) +* [Bitmovin](https://cdn.bitmovin.com/player/android/3/docs/index.html) +* [Hexagon](https://hexagonkt.com/api/index.html) +* [Ktor](https://api.ktor.io/) +* [OkHttp](https://square.github.io/okhttp/4.x/okhttp/okhttp3/) (Markdown) + +You can run Dokka using [Gradle](dokka-gradle.md), [Maven](dokka-maven.md) or from the [command line](dokka-cli.md). It is also +[highly pluggable](dokka-plugins.md). + +See [Get started](dokka-get-started.md) to take your first steps in using Dokka. + +## Community + +Dokka has a dedicated `#dokka` channel in [Kotlin Community Slack](https://surveys.jetbrains.com/s3/kotlin-slack-sign-up) +where you can chat about Dokka, its plugins and how to develop them, as well as get in touch with maintainers. diff --git a/docs/topics/dokka-plugins.md b/docs/topics/dokka-plugins.md new file mode 100644 index 00000000..5d3501ac --- /dev/null +++ b/docs/topics/dokka-plugins.md @@ -0,0 +1,278 @@ +[//]: # (title: Dokka plugins) + +Dokka was built from the ground up to be easily extensible and highly customizable, which allows the community +to implement plugins for missing or very specific features that are not provided out of the box. + +Dokka plugins range anywhere from supporting other programming language sources to exotic output formats. You can add +support for your own KDoc tags or annotations, teach Dokka how to render different DSLs that are found in KDoc +descriptions, visually redesign Dokka's pages to be seamlessly integrated into your company's website, integrate it +with other tools and so much more. + +If you want to learn how to create Dokka plugins, see +[Developer guides](https://kotlin.github.io/dokka/%dokkaVersion%/developer_guide/introduction/). + +## Apply Dokka plugins + +Dokka plugins are published as separate artifacts, so to apply a Dokka plugin you only need to add it as a dependency. +From there, the plugin extends Dokka by itself - no further action is needed. + +> Plugins that use the same extension points or work in a similar way can interfere with each other. +> This may lead to visual bugs, general undefined behaviour or even failed builds. However, it should not lead to +> concurrency issues since Dokka does not expose any mutable data structures or objects. +> +> If you notice problems like this, it's a good idea to check which plugins are applied and what they do. +> +{type="note"} + +Let's have a look at how you can apply the [mathjax plugin](https://github.com/Kotlin/dokka/tree/master/plugins/mathjax) +to your project: + +<tabs group="build-script"> +<tab title="Kotlin" group-key="kotlin"> + +The Gradle plugin for Dokka creates convenient dependency configurations that allow you to apply plugins universally or +for a specific output format only. + +```kotlin +dependencies { + // Is applied universally + dokkaPlugin("org.jetbrains.dokka:mathjax-plugin:%dokkaVersion%") + + // Is applied for the single-module dokkaHtml task only + dokkaHtmlPlugin("org.jetbrains.dokka:kotlin-as-java-plugin:%dokkaVersion%") + + // Is applied for HTML format in multi-project builds + dokkaHtmlPartialPlugin("org.jetbrains.dokka:kotlin-as-java-plugin:%dokkaVersion%") +} +``` + +> When documenting [multi-project](dokka-gradle.md#multi-project-builds) builds, you need to apply Dokka plugins within +> subprojects as well as in their parent project. +> +{type="note"} + +</tab> +<tab title="Groovy" group-key="groovy"> + +The Gradle plugin for Dokka creates convenient dependency configurations that allow you to apply Dokka plugins universally or +for a specific output format only. + +```groovy +dependencies { + // Is applied universally + dokkaPlugin 'org.jetbrains.dokka:mathjax-plugin:%dokkaVersion%' + + // Is applied for the single-module dokkaHtml task only + dokkaHtmlPlugin 'org.jetbrains.dokka:kotlin-as-java-plugin:%dokkaVersion%' + + // Is applied for HTML format in multi-project builds + dokkaHtmlPartialPlugin 'org.jetbrains.dokka:kotlin-as-java-plugin:%dokkaVersion%' +} +``` + +> When documenting [multi-project](dokka-gradle.md#multi-project-builds) builds, you need to apply Dokka plugins within +> subprojects as well as in their parent project. +> +{type="note"} + +</tab> +<tab title="Maven" group-key="mvn"> + +```xml +<plugin> + <groupId>org.jetbrains.dokka</groupId> + <artifactId>dokka-maven-plugin</artifactId> + ... + <configuration> + <dokkaPlugins> + <plugin> + <groupId>org.jetbrains.dokka</groupId> + <artifactId>mathjax-plugin</artifactId> + <version>%dokkaVersion%</version> + </plugin> + </dokkaPlugins> + </configuration> +</plugin> +``` + +</tab> +<tab title="CLI" group-key="cli"> + +If you are using the [CLI](dokka-cli.md) runner with [command line options](dokka-cli.md#run-with-command-line-options), +Dokka plugins should be passed as `.jar` files to `-pluginsClasspath`: + +```Shell +java -jar dokka-cli-%dokkaVersion%.jar \ + -pluginsClasspath "./dokka-base-%dokkaVersion%.jar;...;./mathjax-plugin-%dokkaVersion%.jar" \ + ... +``` + +If you are using [JSON configuration](dokka-cli.md#run-with-json-configuration), Dokka plugins should be specified under +`pluginsClasspath`. + +```json +{ + ... + "pluginsClasspath": [ + "./dokka-base-%dokkaVersion%.jar", + "...", + "./mathjax-plugin-%dokkaVersion%.jar" + ], + ... +} +``` + +</tab> +</tabs> + +## Configure Dokka plugins + +Dokka plugins can also have configuration options of their own. To see which options are available, consult +the documentation of the plugins you are using. + +Let's have a look at how you can configure the `DokkaBase` plugin, which is responsible for generating [HTML](dokka-html.md) +documentation, by adding a custom image to the assets (`customAssets` option), by adding custom style sheets +(`customStyleSheets` option), and by modifying the footer message (`footerMessage` option): + +<tabs group="build-script"> +<tab title="Kotlin" group-key="kotlin"> + +Gradle's Kotlin DSL allows for type-safe plugin configuration. This is achievable by adding the plugin's artifact to +the classpath dependencies in the `buildscript` block, and then importing plugin and configuration classes: + +```kotlin +import org.jetbrains.dokka.base.DokkaBase +import org.jetbrains.dokka.gradle.DokkaTask +import org.jetbrains.dokka.base.DokkaBaseConfiguration + +buildscript { + dependencies { + classpath("org.jetbrains.dokka:dokka-base:%dokkaVersion%") + } +} + +tasks.withType<DokkaTask>().configureEach { + pluginConfiguration<DokkaBase, DokkaBaseConfiguration> { + customAssets = listOf(file("my-image.png")) + customStyleSheets = listOf(file("my-styles.css")) + footerMessage = "(c) 2022 MyOrg" + } +} +``` + +Alternatively, plugins can be configured via JSON. With this method, no additional dependencies are needed. + +```kotlin +import org.jetbrains.dokka.gradle.DokkaTask + +tasks.withType<DokkaTask>().configureEach { + val dokkaBaseConfiguration = """ + { + "customAssets": ["${file("assets/my-image.png")}"], + "customStyleSheets": ["${file("assets/my-styles.css")}"], + "footerMessage": "(c) 2022 MyOrg" + } + """ + pluginsMapConfiguration.set( + mapOf( + // fully qualified plugin name to json configuration + "org.jetbrains.dokka.base.DokkaBase" to dokkaBaseConfiguration + ) + ) +} +``` + +</tab> +<tab title="Groovy" group-key="groovy"> + +```groovy +import org.jetbrains.dokka.gradle.DokkaTask + +tasks.withType(DokkaTask.class) { + String dokkaBaseConfiguration = """ + { + "customAssets": ["${file("assets/my-image.png")}"], + "customStyleSheets": ["${file("assets/my-styles.css")}"], + "footerMessage": "(c) 2022 MyOrg" + } + """ + pluginsMapConfiguration.set( + // fully qualified plugin name to json configuration + ["org.jetbrains.dokka.base.DokkaBase": dokkaBaseConfiguration] + ) +} +``` + +</tab> +<tab title="Maven" group-key="mvn"> + +```xml +<plugin> + <groupId>org.jetbrains.dokka</groupId> + <artifactId>dokka-maven-plugin</artifactId> + ... + <configuration> + <pluginsConfiguration> + <!-- Fully qualified plugin name --> + <org.jetbrains.dokka.base.DokkaBase> + <!-- Options by name --> + <customAssets> + <asset>${project.basedir}/my-image.png</asset> + </customAssets> + <customStyleSheets> + <stylesheet>${project.basedir}/my-styles.css</stylesheet> + </customStyleSheets> + <footerMessage>(c) MyOrg 2022 Maven</footerMessage> + </org.jetbrains.dokka.base.DokkaBase> + </pluginsConfiguration> + </configuration> +</plugin> +``` + +</tab> +<tab title="CLI" group-key="cli"> + +If you are using the [CLI](dokka-cli.md) runner with [command line options](dokka-cli.md#run-with-command-line-options), +use the `-pluginsConfiguration` option that accepts JSON configuration in the form of `fullyQualifiedPluginName=json`. + +If you need to configure multiple plugins, you can pass multiple values separated by `^^`. + +```Bash +java -jar dokka-cli-%dokkaVersion%.jar \ + ... + -pluginsConfiguration "org.jetbrains.dokka.base.DokkaBase={\"customAssets\": [\"my-image.png\"], \"customStyleSheets\": [\"my-styles.css\"], \"footerMessage\": \"(c) 2022 MyOrg CLI\"}" +``` + +If you are using [JSON configuration](dokka-cli.md#run-with-json-configuration), there exists a similar +`pluginsConfiguration` array that accepts JSON configuration in `values`. + +```json +{ + "moduleName": "Dokka Example", + "pluginsConfiguration": [ + { + "fqPluginName": "org.jetbrains.dokka.base.DokkaBase", + "serializationFormat": "JSON", + "values": "{\"customAssets\": [\"my-image.png\"], \"customStyleSheets\": [\"my-styles.css\"], \"footerMessage\": \"(c) 2022 MyOrg\"}" + } + ] +} +``` + +</tab> +</tabs> + +## Notable plugins + +Here are some notable Dokka plugins that you might find useful: + +| **Name** | **Description** | +|-----------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------| +| [Android documentation plugin](https://github.com/Kotlin/dokka/tree/master/plugins/android-documentation) | Improves the documentation experience on Android | +| [Versioning plugin](https://github.com/Kotlin/dokka/tree/master/plugins/versioning) | Adds version selector and helps to organize documentation for different versions of your application/library | +| [MermaidJS HTML plugin](https://github.com/glureau/dokka-mermaid) | Renders [MermaidJS](https://mermaid-js.github.io/mermaid/#/) diagrams and visualizations found in KDocs | +| [Mathjax HTML plugin](https://github.com/Kotlin/dokka/tree/master/plugins/mathjax) | Pretty prints mathematics found in KDocs | +| [Kotlin as Java plugin](https://github.com/Kotlin/dokka/tree/master/plugins/kotlin-as-java) | Renders Kotlin signatures as seen from Java's perspective | + +If you are a Dokka plugin author and would like to add your plugin to this list, get in touch with maintainers +via [Slack](dokka-introduction.md#community) or [GitHub](https://github.com/Kotlin/dokka/).
\ No newline at end of file diff --git a/docs/topics/formats/dokka-html.md b/docs/topics/formats/dokka-html.md new file mode 100644 index 00000000..dd81b2d9 --- /dev/null +++ b/docs/topics/formats/dokka-html.md @@ -0,0 +1,282 @@ +[//]: # (title: HTML) + +HTML is Dokka's default and recommended output format. You can see an example of the final result by browsing documentation +for [kotlinx.coroutines](https://kotlinlang.org/api/kotlinx.coroutines/). + +## Generate HTML documentation + +HTML as an output format is supported by all runners. To generate HTML documentation, follow these steps depending on +your build tool or runner: + +* For [Gradle](dokka-gradle.md#generate-documentation), run `dokkaHtml` or `dokkaHtmlMultiModule` tasks. +* For [Maven](dokka-maven.md#generate-documentation), run the `dokka:dokka` goal. +* For [CLI runner](dokka-cli.md#generate-documentation), run with HTML dependencies set. + +> HTML pages generated by this format need to be hosted on a web server in order to render everything correctly. +> +> You can use any free static site hosting service, such as +> [GitHub Pages](https://docs.github.com/en/pages/getting-started-with-github-pages/about-github-pages). +> +> Locally, you can use the [built-in IntelliJ web server](https://www.jetbrains.com/help/idea/php-built-in-web-server.html). +> +{type="note"} + +## Configuration + +HTML format is Dokka's base format, so it is configurable through `DokkaBase` and `DokkaBaseConfiguration` +classes: + +<tabs group="build-script"> +<tab title="Kotlin" group-key="kotlin"> + +Via type-safe Kotlin DSL: + +```kotlin +import org.jetbrains.dokka.base.DokkaBase +import org.jetbrains.dokka.gradle.DokkaTask +import org.jetbrains.dokka.base.DokkaBaseConfiguration + +buildscript { + dependencies { + classpath("org.jetbrains.dokka:dokka-base:%dokkaVersion%") + } +} + +tasks.withType<DokkaTask>().configureEach { + pluginConfiguration<DokkaBase, DokkaBaseConfiguration> { + customAssets = listOf(file("my-image.png")) + customStyleSheets = listOf(file("my-styles.css")) + footerMessage = "(c) 2022 MyOrg" + separateInheritedMembers = false + templatesDir = file("dokka/templates") + mergeImplicitExpectActualDeclarations = false + } +} +``` + +Via JSON: + +```kotlin +import org.jetbrains.dokka.gradle.DokkaTask + +tasks.withType<DokkaTask>().configureEach { + val dokkaBaseConfiguration = """ + { + "customAssets": ["${file("assets/my-image.png")}"], + "customStyleSheets": ["${file("assets/my-styles.css")}"], + "footerMessage": "(c) 2022 MyOrg", + "separateInheritedMembers": false, + "templatesDir": "${file("dokka/templates")}", + "mergeImplicitExpectActualDeclarations": false + } + """ + pluginsMapConfiguration.set( + mapOf( + // fully qualified plugin name to json configuration + "org.jetbrains.dokka.base.DokkaBase" to dokkaBaseConfiguration + ) + ) +} +``` + +</tab> +<tab title="Groovy" group-key="groovy"> + +```groovy +import org.jetbrains.dokka.gradle.DokkaTask + +tasks.withType(DokkaTask.class) { + String dokkaBaseConfiguration = """ + { + "customAssets": ["${file("assets/my-image.png")}"], + "customStyleSheets": ["${file("assets/my-styles.css")}"], + "footerMessage": "(c) 2022 MyOrg" + "separateInheritedMembers": false, + "templatesDir": "${file("dokka/templates")}", + "mergeImplicitExpectActualDeclarations": false + } + """ + pluginsMapConfiguration.set( + // fully qualified plugin name to json configuration + ["org.jetbrains.dokka.base.DokkaBase": dokkaBaseConfiguration] + ) +} +``` + +</tab> +<tab title="Maven" group-key="mvn"> + +```xml +<plugin> + <groupId>org.jetbrains.dokka</groupId> + <artifactId>dokka-maven-plugin</artifactId> + ... + <configuration> + <pluginsConfiguration> + <!-- Fully qualified plugin name --> + <org.jetbrains.dokka.base.DokkaBase> + <!-- Options by name --> + <customAssets> + <asset>${project.basedir}/my-image.png</asset> + </customAssets> + <customStyleSheets> + <stylesheet>${project.basedir}/my-styles.css</stylesheet> + </customStyleSheets> + <footerMessage>(c) MyOrg 2022 Maven</footerMessage> + <separateInheritedMembers>false</separateInheritedMembers> + <templatesDir>${project.basedir}/dokka/templates</templatesDir> + <mergeImplicitExpectActualDeclarations>false</mergeImplicitExpectActualDeclarations> + </org.jetbrains.dokka.base.DokkaBase> + </pluginsConfiguration> + </configuration> +</plugin> +``` + +</tab> +<tab title="CLI" group-key="cli"> + +Via [command line options](dokka-cli.md#run-with-command-line-options): + +```Bash +java -jar dokka-cli-%dokkaVersion%.jar \ + ... + -pluginsConfiguration "org.jetbrains.dokka.base.DokkaBase={\"customAssets\": [\"my-image.png\"], \"customStyleSheets\": [\"my-styles.css\"], \"footerMessage\": \"(c) 2022 MyOrg\", \"separateInheritedMembers\": false, \"templatesDir\": \"dokka/templates\", \"mergeImplicitExpectActualDeclarations\": false} +" +``` + +Via [JSON configuration](dokka-cli.md#run-with-json-configuration): + +```json +{ + "moduleName": "Dokka Example", + "pluginsConfiguration": [ + { + "fqPluginName": "org.jetbrains.dokka.base.DokkaBase", + "serializationFormat": "JSON", + "values": "{\"customAssets\": [\"my-image.png\"], \"customStyleSheets\": [\"my-styles.css\"], \"footerMessage\": \"(c) 2022 MyOrg\", \"separateInheritedMembers\": false, \"templatesDir\": \"dokka/templates\", \"mergeImplicitExpectActualDeclarations\": false}" + } + ] +} +``` + +</tab> +</tabs> + +### Configuration options + +The table below contains all of the possible configuration options and their purpose. + +| **Option** | **Description** | +|-----------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `customAssets` | List of paths for image assets to be bundled with documentation. The image assets can have any file extension. For more information, see [Customizing assets](#customize-assets). | +| `customStyleSheets` | List of paths for `.css` stylesheets to be bundled with documentation and used for rendering. For more information, see [Customizing styles](#customize-styles). | +| `templatesDir` | Path to the directory containing custom HTML templates. For more information, see [Templates](#templates). | +| `footerMessage` | The text displayed in the footer. | +| `separateInheritedMembers` | This is a boolean option. If set to `true`, Dokka renders properties/functions and inherited properties/inherited functions separately. This is disabled by default. | +| `mergeImplicitExpectActualDeclarations` | This is a boolean option. If set to `true`, Dokka merges declarations that are not declared as [expect/actual](https://kotlinlang.org/docs/multiplatform-connect-to-apis.html), but have the same fully qualified name. This can be useful for legacy codebases. This is disabled by default. | + +For more information about configuring Dokka plugins, see [Configuring Dokka plugins](dokka-plugins.md#configure-dokka-plugins). + +## Customization + +To help you add your own look and feel to your documentation, the HTML format supports a number of customization options. + +### Customize styles + +You can use your own stylesheets by using the `customStyleSheets` +[configuration option](#configuration). These are applied to every page. + +It's also possible to override Dokka's default stylesheets by providing files with the same name: + +| **Stylesheet name** | **Description** | +|----------------------|--------------------------------------------------------------------| +| `style.css` | Main stylesheet, contains most of the styles used across all pages | +| `logo-styles.css` | Header logo styling | +| `prism.css` | Styles for [PrismJS](https://prismjs.com/) syntax highlighter | +| `jetbrains-mono.css` | Font styling | + +The source code for all of Dokka's stylesheets is +[available on GitHub](https://github.com/Kotlin/dokka/tree/%dokkaVersion%/plugins/base/src/main/resources/dokka/styles). + +### Customize assets + +You can provide your own images to be bundled with documentation by using the `customAssets` +[configuration option](#configuration). + +These files are copied to the `<output>/images` directory. + +It's possible to override Dokka's images and icons by providing files with the same name. The most +useful and relevant one being `logo-icon.svg`, which is the image that's used in the header. The rest is mostly icons. + +You can find all images used by Dokka on +[GitHub](https://github.com/Kotlin/dokka/tree/%dokkaVersion%/plugins/base/src/main/resources/dokka/images). + +### Change the logo + +To customize the logo, you can begin by [providing your own asset](#customize-assets) for `logo-icon.svg`. + +If you don't like how it looks, or you want to use a `.png` file instead of the default `.svg` file, +you can [override the `logo-styles.css` stylesheet](#customize-styles) to customize it. + +For an example of how to do this, see our +[custom format example project](https://github.com/Kotlin/dokka/tree/%dokkaVersion%/examples/gradle/dokka-customFormat-example). + +### Modify the footer + +You can modify text in the footer by using the `footerMessage` [configuration option](#configuration). + +### Templates + +Dokka provides the ability to modify [FreeMarker](https://freemarker.apache.org/) templates used for generating +documentation pages. + +You can change the header completely, add your own banners/menus/search, load analytics, change body styling and so on. + +Dokka uses the following templates: + +| **Template** | **Description** | +|-----------------------------------|-----------------------------------------------------------------------------------------------------------------------| +| `base.ftl` | Defines the general design of all pages to be rendered. | +| `includes/header.ft` | The page header that by default contains the logo, version, source set selector, light/dark theme switch, and search. | +| `includes/footer.ft` | The page footer that contains the `footerMessage` [configuration option](#configuration) and copyright. | +| `includes/page_metadata.ft` | Metadata used within `<head>` container. | +| `includes/source_set_selector.ft` | [The source set](https://kotlinlang.org/docs/multiplatform-discover-project.html#source-sets) selector in the header. | + +The base template is `base.ftl` and it includes all of the remaining listed templates. You can find the source code for all of Dokka's templates +[on GitHub](https://github.com/Kotlin/dokka/tree/%dokkaVersion%/plugins/base/src/main/resources/dokka/templates). + +You can override any template by using the `templatesDir` [configuration option](#configuration). Dokka searches +for the exact template names within the given directory. If it fails to find user-defined templates, it uses the +default templates. + +#### Variables + +The following variables are available inside all templates: + +| **Variable** | **Description** | +|--------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `${pageName}` | The page name | +| `${footerMessage}` | The text which is set by the `footerMessage` [configuration option](#configuration) | +| `${sourceSets}` | A nullable list of [source sets](https://kotlinlang.org/docs/multiplatform-discover-project.html#source-sets) for multi-platform pages. Each item has `name`, `platform`, and `filter` properties. | +| `${projectName}` | The project name. It's available only within the `template_cmd` directive. | +| `${pathToRoot}` | The path to root from the current page. It's useful for locating assets and is available only within the `template_cmd` directive. | + +Variables `projectName` and `pathToRoot` are available only within the `template_cmd` directive as they require more +context and thus they need to be resolved at later stages by the [MultiModule](dokka-gradle.md#multi-project-builds) task: + +```html +<@template_cmd name="projectName"> + <span>${projectName}</span> +</@template_cmd> +``` + +#### Directives + +You can also use the following Dokka-defined [directives](https://freemarker.apache.org/docs/ref_directive_userDefined.html): + +| **Variable** | **Description** | +|-----------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `<@content/>` | The main page content. | +| `<@resources/>` | Resources such as scripts and stylesheets. | +| `<@version/>` | The module version taken from configuration. If the [versioning plugin](https://github.com/Kotlin/dokka/tree/master/plugins/versioning) is applied, it is replaced with a version navigator. | + diff --git a/docs/topics/formats/dokka-javadoc.md b/docs/topics/formats/dokka-javadoc.md new file mode 100644 index 00000000..4781afcb --- /dev/null +++ b/docs/topics/formats/dokka-javadoc.md @@ -0,0 +1,93 @@ +[//]: # (title: Javadoc) + +> The Javadoc output format is still in Alpha so you may find bugs and experience migration issues when using it. +> Successful integration with tools that accept Java's Javadoc HTML as input is not guaranteed. +> **You use it at your own risk.** +> +{type="warning"} + +Dokka's Javadoc output format is a lookalike of Java's +[Javadoc HTML format](https://docs.oracle.com/en/java/javase/19/docs/api/index.html). + +It tries to visually mimic HTML pages generated by the Javadoc tool, but it's not a direct implementation +or an exact copy. + +![Screenshot of javadoc output format](javadoc-format-example.png){height=750} + +All Kotlin code and signatures are rendered as seen from Java's perspective. This is achieved with our +[Kotlin as Java Dokka plugin](https://github.com/Kotlin/dokka/tree/master/plugins/kotlin-as-java), which comes bundled and +applied by default for this format. + +The Javadoc output format is implemented as a [Dokka plugin](dokka-plugins.md), and it is maintained by the Dokka team. +It is open source and you can find the source code on [GitHub](https://github.com/Kotlin/dokka/tree/master/plugins/javadoc). + +## Generate Javadoc documentation + +> The Javadoc format does not support multiplatform projects. +> +{type="warning"} + + +<tabs group="build-script"> +<tab title="Gradle" group-key="kotlin"> + +The [Gradle plugin for Dokka](dokka-gradle.md) comes with the Javadoc output format included. You can use the following tasks: + +| **Task** | **Description** | +|-------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `dokkaJavadoc` | Generates Javadoc documentation for a single project. | +| `dokkaJavadocCollector` | A [`Collector`](dokka-gradle.md#collector-tasks) task created only for parent projects in multi-project builds. It calls `dokkaJavadoc` for every subproject and merges all outputs into a single virtual project. | + +The `javadoc.jar` file can be generated separately. For more information, see [Building `javadoc.jar`](dokka-gradle.md#build-javadoc-jar). + +</tab> +<tab title="Maven" group-key="groovy"> + +The [Maven plugin for Dokka](dokka-maven.md) comes with the Javadoc output format built in. You can generate documentation +by using the following goals: + +| **Goal** | **Description** | +|--------------------|------------------------------------------------------------------------------| +| `dokka:javadoc` | Generates documentation in Javadoc format | +| `dokka:javadocJar` | Generates a `javadoc.jar` file that contains documentation in Javadoc format | + + +</tab> +<tab title="CLI" group-key="cli"> + +Since the Javadoc output format is a [Dokka plugin](dokka-plugins.md#apply-dokka-plugins), you need to +download the plugin's [JAR file](https://mvnrepository.com/artifact/org.jetbrains.dokka/javadoc-plugin/%dokkaVersion%). + +The Javadoc output format has two dependencies that you need to provide as additional JAR files: + +* [kotlin-as-java plugin](https://mvnrepository.com/artifact/org.jetbrains.dokka/kotlin-as-java-plugin/%dokkaVersion%) +* [korte-jvm](https://mvnrepository.com/artifact/com.soywiz.korlibs.korte/korte-jvm/3.3.0) + +Via [command line options](dokka-cli.md#run-with-command-line-options): + +```Bash +java -jar dokka-cli-%dokkaVersion%.jar \ + -pluginsClasspath "./dokka-base-%dokkaVersion%.jar;...;./javadoc-plugin-%dokkaVersion%.jar" \ + ... +``` + +Via [JSON configuration](dokka-cli.md#run-with-json-configuration): + +```json +{ + ... + "pluginsClasspath": [ + "./dokka-base-%dokkaVersion%.jar", + "...", + "./kotlin-as-java-plugin-%dokkaVersion%.jar", + "./korte-jvm-3.3.0.jar", + "./javadoc-plugin-%dokkaVersion%.jar" + ], + ... +} +``` + +For more information, see [Other output formats](dokka-cli.md#other-output-formats) in the CLI runner's documentation. + +</tab> +</tabs> diff --git a/docs/topics/formats/dokka-markdown.md b/docs/topics/formats/dokka-markdown.md new file mode 100644 index 00000000..d4919a5c --- /dev/null +++ b/docs/topics/formats/dokka-markdown.md @@ -0,0 +1,172 @@ +[//]: # (title: Markdown) + +> The Markdown output formats are still in Alpha so you may find bugs and experience migration issues when using them. **You use them at your own risk.** +> +{type="warning"} + +Dokka is able to generate documentation in [GitHub Flavored](#gfm) and [Jekyll](#jekyll) compatible Markdown. + +These formats give you more freedom in terms of hosting documentation as the output can be embedded right into your +documentation website. For example, see [OkHttp's API reference](https://square.github.io/okhttp/4.x/okhttp/okhttp3/) +pages. + +Markdown output formats are implemented as [Dokka plugins](dokka-plugins.md), maintained by the Dokka team, and +they are open source. + +## GFM + +The GFM output format generates documentation in [GitHub Flavored Markdown](https://github.github.com/gfm/). + +<tabs group="build-script"> +<tab title="Gradle" group-key="kotlin"> + +The [Gradle plugin for Dokka](dokka-gradle.md) comes with the GFM output format included. You can use the following tasks with it: + +| **Task** | **Description** | +|-----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `dokkaGfm` | Generates GFM documentation for a single project. | +| `dokkaGfmMultiModule` | A [`MultiModule`](dokka-gradle.md#multi-project-builds) task created only for parent projects in multi-project builds. It generates documentation for subprojects and collects all outputs in a single place with a common table of contents. | +| `dokkaGfmCollector` | A [`Collector`](dokka-gradle.md#collector-tasks) task created only for parent projects in multi-project builds. It calls `dokkaGfm` for every subproject and merges all outputs into a single virtual project. | + +</tab> +<tab title="Maven" group-key="groovy"> + +Since GFM format is implemented as a [Dokka plugin](dokka-plugins.md#apply-dokka-plugins), you need to apply it as a plugin +dependency: + +```xml +<plugin> + <groupId>org.jetbrains.dokka</groupId> + <artifactId>dokka-maven-plugin</artifactId> + ... + <configuration> + <dokkaPlugins> + <plugin> + <groupId>org.jetbrains.dokka</groupId> + <artifactId>gfm-plugin</artifactId> + <version>%dokkaVersion%</version> + </plugin> + </dokkaPlugins> + </configuration> +</plugin> +``` + +After configuring this, running the `dokka:dokka` goal produces documentation in GFM format. + +For more information, see the Mavin plugin documentation for [Other output formats](dokka-maven.md#other-output-formats). + +</tab> +<tab title="CLI" group-key="cli"> + +Since GFM format is implemented as a [Dokka plugin](dokka-plugins.md#apply-dokka-plugins), you need to download the +[JAR file](https://mvnrepository.com/artifact/org.jetbrains.dokka/gfm-plugin/%dokkaVersion%) and pass it to +`pluginsClasspath`. + +Via [command line options](dokka-cli.md#run-with-command-line-options): + +```Bash +java -jar dokka-cli-%dokkaVersion%.jar \ + -pluginsClasspath "./dokka-base-%dokkaVersion%.jar;...;./gfm-plugin-%dokkaVersion%.jar" \ + ... +``` + +Via [JSON configuration](dokka-cli.md#run-with-json-configuration): + +```json +{ + ... + "pluginsClasspath": [ + "./dokka-base-%dokkaVersion%.jar", + "...", + "./gfm-plugin-%dokkaVersion%.jar" + ], + ... +} +``` + +For more information, see the CLI runner's documentation for [Other output formats](dokka-cli.md#other-output-formats). + +</tab> +</tabs> + +You can find the source code [on GitHub](https://github.com/Kotlin/dokka/tree/%dokkaVersion%/plugins/gfm). + +## Jekyll + +The Jekyll output format generates documentation in [Jekyll](https://jekyllrb.com/) compatible Markdown. + +<tabs group="build-script"> +<tab title="Gradle" group-key="kotlin"> + +The [Gradle plugin for Dokka](dokka-gradle.md) comes with the Jekyll output format included. You can use the following tasks with it: + +| **Task** | **Description** | +|--------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `dokkaJekyll` | Generates Jekyll documentation for a single project. | +| `dokkaJekyllMultiModule` | A [`MultiModule`](dokka-gradle.md#multi-project-builds) task created only for parent projects in multi-project builds. It generates documentation for subprojects and collects all outputs in a single place with a common table of contents. | +| `dokkaJekyllCollector` | A [`Collector`](dokka-gradle.md#collector-tasks) task created only for parent projects in multi-project builds. It calls `dokkaJekyll` for every subproject and merges all outputs into a single virtual project. | + +</tab> +<tab title="Maven" group-key="groovy"> + +Since Jekyll format is implemented as a [Dokka plugin](dokka-plugins.md#apply-dokka-plugins), you need to apply it as a plugin +dependency: + +```xml +<plugin> + <groupId>org.jetbrains.dokka</groupId> + <artifactId>dokka-maven-plugin</artifactId> + ... + <configuration> + <dokkaPlugins> + <plugin> + <groupId>org.jetbrains.dokka</groupId> + <artifactId>jekyll-plugin</artifactId> + <version>%dokkaVersion%</version> + </plugin> + </dokkaPlugins> + </configuration> +</plugin> +``` + +After configuring this, running the `dokka:dokka` goal produces documentation in GFM format. + +For more information, see the Maven plugin's documentation for [Other output formats](dokka-maven.md#other-output-formats). + +</tab> +<tab title="CLI" group-key="cli"> + +Since Jekyll format is implemented as a [Dokka plugin](dokka-plugins.md#apply-dokka-plugins), you need to download the +[JAR file](https://mvnrepository.com/artifact/org.jetbrains.dokka/jekyll-plugin/%dokkaVersion%). This format is also +based on [GFM](#gfm) format, so you need to provide it as a dependency as well. Both JARs need to be passed to +`pluginsClasspath`: + +Via [command line options](dokka-cli.md#run-with-command-line-options): + +```Bash +java -jar dokka-cli-%dokkaVersion%.jar \ + -pluginsClasspath "./dokka-base-%dokkaVersion%.jar;...;./gfm-plugin-%dokkaVersion%.jar;./jekyll-plugin-%dokkaVersion%.jar" \ + ... +``` + +Via [JSON configuration](dokka-cli.md#run-with-json-configuration): + +```json +{ + ... + "pluginsClasspath": [ + "./dokka-base-%dokkaVersion%.jar", + "...", + "./gfm-plugin-%dokkaVersion%.jar", + "./jekyll-plugin-%dokkaVersion%.jar" + ], + ... +} +``` + +For more information, see the CLI runner's documentation for [Other output formats](dokka-cli.md#other-output-formats). + +</tab> +</tabs> + +You can find the source code on [GitHub](https://github.com/Kotlin/dokka/tree/%dokkaVersion%/plugins/jekyll). diff --git a/docs/topics/runners/dokka-cli.md b/docs/topics/runners/dokka-cli.md new file mode 100644 index 00000000..fa8fa459 --- /dev/null +++ b/docs/topics/runners/dokka-cli.md @@ -0,0 +1,859 @@ +[//]: # (title: CLI) + +If for some reason you cannot use [Gradle](dokka-gradle.md) or [Maven](dokka-maven.md) build tools, Dokka has +a command line (CLI) runner for generating documentation. + +In comparison, it has the same, if not more, capabilities as the Gradle plugin for Dokka. Although it is considerably more +difficult to set up as there is no autoconfiguration, especially in multiplatform and multi-module environments. + +## Get started + +The CLI runner is published to Maven Central as a separate runnable artifact. + +You can find it on [mvnrepository](https://mvnrepository.com/artifact/org.jetbrains.dokka/dokka-cli/%dokkaVersion%) or by browsing +[maven central repository directories](https://repo1.maven.org/maven2/org/jetbrains/dokka/dokka-cli/%dokkaVersion%) directly. + +With the `dokka-cli-%dokkaVersion%.jar` file saved on your computer, run it with the `-help` option to see all +available configuration options and their description: + +```Bash +java -jar dokka-cli-%dokkaVersion%.jar -help +``` + +It also works for some nested options, such as `-sourceSet`: + +```Bash +java -jar dokka-cli-%dokkaVersion%.jar -sourceSet -help +``` + +## Generate documentation + +### Prerequisites + +Since there is no build tool to manage dependencies, you have to provide dependency `.jar` files yourself. + +Listed below are the dependencies that you need for any output format: + +| **Group** | **Artifact** | **Version** | **Link** | +|-----------------------|----------------------------|----------------|-----------------------------------------------------------------------------------------------------------------| +| `org.jetbrains.dokka` | `dokka-base` | %dokkaVersion% | [mvnrepository](https://mvnrepository.com/artifact/org.jetbrains.dokka/dokka-base/%dokkaVersion%) | +| `org.jetbrains.dokka` | `dokka-analysis` | %dokkaVersion% | [mvnrepository](https://mvnrepository.com/artifact/org.jetbrains.dokka/dokka-analysis/%dokkaVersion%) | +| `org.jetbrains.dokka` | `kotlin-analysis-compiler` | %dokkaVersion% | [mvnrepository](https://mvnrepository.com/artifact/org.jetbrains.dokka/kotlin-analysis-compiler/%dokkaVersion%) | +| `org.jetbrains.dokka` | `kotlin-analysis-intellij` | %dokkaVersion% | [mvnrepository](https://mvnrepository.com/artifact/org.jetbrains.dokka/kotlin-analysis-intellij/%dokkaVersion%) | + +Below are the additional dependencies that you need for [HTML](dokka-html.md) output format: + +| **Group** | **Artifact** | **Version** | **Link** | +|-------------------------|--------------------|-------------|--------------------------------------------------------------------------------------------------| +| `org.jetbrains.kotlinx` | `kotlinx-html-jvm` | 0.8.0 | [mvnrepository](https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-html-jvm/0.8.0) | +| `org.freemarker` | `freemarker` | 2.3.31 | [mvnrepository](https://mvnrepository.com/artifact/org.freemarker/freemarker/2.3.31) | + + +### Run with command line options + +You can pass command line options to configure the CLI runner. + +At the very least you need to provide the following options: + +* `-pluginsClasspath` - a list of absolute/relative paths to downloaded dependencies, separated by semi-colons `;` +* `-sourceSet` - an absolute path to code sources to generate documentation for +* `-outputDir` - an absolute/relative path of the documentation output directory + +```Bash +java -jar dokka-cli-%dokkaVersion%.jar \ + -pluginsClasspath "./dokka-base-%dokkaVersion%.jar;./dokka-analysis-%dokkaVersion%.jar;./kotlin-analysis-intellij-%dokkaVersion%.jar;./kotlin-analysis-compiler-%dokkaVersion%.jar;./kotlinx-html-jvm-0.8.0.jar;./freemarker-2.3.31.jar" \ + -sourceSet "-src /home/myCoolProject/src/main/kotlin" \ + -outputDir "./dokka/html" +``` + +> Due to an internal class conflict, first pass `kotlin-analysis-intellij` and only then `kotlin-analysis-compiler`. +> Otherwise you may see obscure exceptions, such as `NoSuchFieldError`. +> +{type="note"} + +Executing the given example generates documentation in [HTML](dokka-html.md) output format. + +See [Command line options](#command-line-options) for more configuration details. + +### Run with JSON configuration + +It's possible to configure the CLI runner with JSON. In this case, you need to provide an +absolute/relative path to the JSON configuration file as the first and only argument. +All other configuration options are parsed from it. + +```Bash +java -jar dokka-cli-%dokkaVersion%.jar dokka-configuration.json +``` + +At the very least, you need the following JSON configuration file: + +```json +{ + "outputDir": "./dokka/html", + "sourceSets": [ + { + "sourceSetID": { + "scopeId": "moduleName", + "sourceSetName": "main" + }, + "sourceRoots": [ + "/home/myCoolProject/src/main/kotlin" + ] + } + ], + "pluginsClasspath": [ + "./dokka-base-%dokkaVersion%.jar", + "./kotlinx-html-jvm-0.8.0.jar", + "./dokka-analysis-%dokkaVersion%.jar", + "./kotlin-analysis-intellij-%dokkaVersion%.jar", + "./kotlin-analysis-compiler-%dokkaVersion%.jar", + "./freemarker-2.3.31.jar" + ] +} +``` + +> Due to an internal class conflict, first pass `kotlin-analysis-intellij` and only then `kotlin-analysis-compiler`. +> Otherwise you may see obscure exceptions, such as `NoSuchFieldError`. +> +{type="note"} + +See [JSON configuration options](#json-configuration) for more details. + +### Other output formats + +By default, the `dokka-base` artifact contains the [HTML](dokka-html.md) output format only. + +All other output formats are implemented as [Dokka plugins](dokka-plugins.md). In order to use them, you have to put them +on the plugins classpath. + +For example, if you want to generate documentation in the experimental [GFM](dokka-markdown.md#gfm) output format, you need to download and +pass [gfm-plugin's JAR](https://mvnrepository.com/artifact/org.jetbrains.dokka/gfm-plugin/%dokkaVersion%) into +the `pluginsClasspath` configuration option. + +Via command line options: + +```Shell +java -jar dokka-cli-%dokkaVersion%.jar \ + -pluginsClasspath "./dokka-base-%dokkaVersion%.jar;...;./gfm-plugin-%dokkaVersion%.jar" \ + ... +``` + +Via JSON configuration: + +```json +{ + ... + "pluginsClasspath": [ + "./dokka-base-%dokkaVersion%.jar", + "...", + "./gfm-plugin-%dokkaVersion%.jar" + ], + ... +} +``` + +With the GFM plugin passed to `pluginsClasspath`, the CLI runner generates documentation in the GFM output format. + +For more information, see [Markdown](dokka-markdown.md) and [Javadoc](dokka-javadoc.md#generate-javadoc-documentation) pages. + +## Command line options + +To see the list of all possible command line options and their detailed description, run: + +```Bash +java -jar dokka-cli-%dokkaVersion%.jar -help +``` + +Short summary: + +| Option | Description | +|------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `moduleName` | Name of the project/module. | +| `moduleVersion` | Documented version. | +| `outputDir` | Output directory path, `./dokka` by default. | +| `sourceSet` | Configuration for a Dokka source set. Contains nested configuration options. | +| `pluginsConfiguration` | Configuration for Dokka plugins. | +| `pluginsClasspath` | List of jars with Dokka plugins and their dependencies. Accepts multiple paths separated by semicolons. | +| `offlineMode` | Whether to resolve remote files/links over network. | +| `failOnWarning` | Whether to fail documentation generation if Dokka has emitted a warning or an error. | +| `delayTemplateSubstitution` | Whether to delay substitution of some elements. Used in incremental builds of multi-module projects. | +| `noSuppressObviousFunctions` | Whether to suppress obvious functions such as those inherited from `kotlin.Any` and `java.lang.Object`. | +| `includes` | Markdown files that contain module and package documentation. Accepts multiple values separated by semicolons. | +| `suppressInheritedMembers` | Whether to suppress inherited members that aren't explicitly overridden in a given class. | +| `globalPackageOptions` | Global list of package configuration options in format `"matchingRegex,-deprecated,-privateApi,+warnUndocumented,+suppress;+visibility:PUBLIC;..."`. Accepts multiple values separated by semicolons. | +| `globalLinks` | Global external documentation links in format `{url}^{packageListUrl}`. Accepts multiple values separated by `^^`. | +| `globalSrcLink` | Global mapping between a source directory and a Web service for browsing the code. Accepts multiple paths separated by semicolons. | +| `helpSourceSet` | Prints help for the nested `-sourceSet` configuration. | +| `loggingLevel` | Logging level, possible values: `DEBUG, PROGRESS, INFO, WARN, ERROR`. | +| `help, h` | Usage info. | + +#### Source set options + +To see the list of command line options for the nested `-sourceSet` configuration, run: + +```Bash +java -jar dokka-cli-%dokkaVersion%.jar -sourceSet -help +``` + +Short summary: + +| Option | Description | +|------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `sourceSetName` | Name of the source set. | +| `displayName` | Display name of the source set, used both internally and externally. | +| `classpath` | Classpath for analysis and interactive samples. Accepts multiple paths separated by semicolons. | +| `src` | Source code roots to be analyzed and documented. Accepts multiple paths separated by semicolons. | +| `dependentSourceSets` | Names of the dependent source sets in format `moduleName/sourceSetName`. Accepts multiple paths separated by semicolons. | +| `samples` | List of directories or files that contain sample functions. Accepts multiple paths separated by semicolons. | +| `includes` | Markdown files that contain module and package documentation. Accepts multiple paths separated by semicolons. | +| `documentedVisibilities` | Visibilities to be documented. Accepts multiple values separated by semicolons. Possible values: `PUBLIC`, `PRIVATE`, `PROTECTED`, `INTERNAL`, `PACKAGE`. | +| `reportUndocumented` | Whether to report undocumented declarations. | +| `noSkipEmptyPackages` | Whether to create pages for empty packages. | +| `skipDeprecated` | Whether to skip deprecated declarations. | +| `jdkVersion` | Version of JDK to use for linking to JDK Javadocs. | +| `languageVersion` | Language version used for setting up analysis and samples. | +| `apiVersion` | Kotlin API version used for setting up analysis and samples. | +| `noStdlibLink` | Whether to generate links to the Kotlin standard library. | +| `noJdkLink` | Whether to generate links to JDK Javadocs. | +| `suppressedFiles` | Paths to files to be suppressed. Accepts multiple paths separated by semicolons. | +| `analysisPlatform` | Platform used for setting up analysis. | +| `perPackageOptions` | List of package source set configurations in format `matchingRegexp,-deprecated,-privateApi,+warnUndocumented,+suppress;...`. Accepts multiple values separated by semicolons. | +| `externalDocumentationLinks` | External documentation links in format `{url}^{packageListUrl}`. Accepts multiple values separated by `^^`. | +| `srcLink` | Mapping between a source directory and a Web service for browsing the code. Accepts multiple paths separated by semicolons. | + +## JSON configuration + +Below are some examples and detailed descriptions for each configuration section. You can also find an example +with [all configuration options](#complete-configuration) applied at the bottom of the page. + +### General configuration + +```json +{ + "moduleName": "Dokka Example", + "moduleVersion": null, + "outputDir": "./build/dokka/html", + "failOnWarning": false, + "suppressObviousFunctions": true, + "suppressInheritedMembers": false, + "offlineMode": false, + "includes": [ + "module.md" + ], + "sourceLinks": [ + { "_comment": "Options are described in a separate section" } + ], + "perPackageOptions": [ + { "_comment": "Options are described in a separate section" } + ], + "externalDocumentationLinks": [ + { "_comment": "Options are described in a separate section" } + ], + "sourceSets": [ + { "_comment": "Options are described in a separate section" } + ], + "pluginsClasspath": [ + "./dokka-base-%dokkaVersion%.jar", + "./kotlinx-html-jvm-0.8.0.jar", + "./dokka-analysis-%dokkaVersion%.jar", + "./kotlin-analysis-intellij-%dokkaVersion%.jar", + "./kotlin-analysis-compiler-%dokkaVersion%.jar", + "./freemarker-2.3.31.jar" + ] +} +``` + +<deflist collapsible="true"> + <def title="moduleName"> + <p>The display name used to refer to the module. It is used for the table of contents, navigation, logging, etc.</p> + <p>Default: <code>root</code></p> + </def> + <def title="moduleVersion"> + <p>The module version.</p> + <p>Default: empty</p> + </def> + <def title="outputDirectory"> + <p>The directory to where documentation is generated, regardless of output format.</p> + <p>Default: <code>./dokka</code></p> + </def> + <def title="failOnWarning"> + <p> + Whether to fail documentation generation if Dokka has emitted a warning or an error. + The process waits until all errors and warnings have been emitted first. + </p> + <p>This setting works well with <code>reportUndocumented</code></p> + <p>Default: <code>false</code></p> + </def> + <def title="suppressObviousFunctions"> + <p>Whether to suppress obvious functions.</p> + <p> + A function is considered to be obvious if it is: + <list> + <li> + Inherited from <code>kotlin.Any</code>, <code>Kotlin.Enum</code>, <code>java.lang.Object</code> or + <code>java.lang.Enum</code>, such as <code>equals</code>, <code>hashCode</code>, <code>toString</code>. + </li> + <li> + Synthetic (generated by the compiler) and does not have any documentation, such as + <code>dataClass.componentN</code> or <code>dataClass.copy</code>. + </li> + </list> + </p> + <p>Default: <code>true</code></p> + </def> + <def title="suppressInheritedMembers"> + <p>Whether to suppress inherited members that aren't explicitly overridden in a given class.</p> + <p> + Note: This can suppress functions such as <code>equals</code> / <code>hashCode</code> / <code>toString</code>, + but cannot suppress synthetic functions such as <code>dataClass.componentN</code> and + <code>dataClass.copy</code>. Use <code>suppressObviousFunctions</code> + for that. + </p> + <p>Default: <code>false</code></p> + </def> + <def title="offlineMode"> + <p>Whether to resolve remote files/links over your network.</p> + <p> + This includes package-lists used for generating external documentation links. + For example, to make classes from the standard library clickable. + </p> + <p> + Setting this to <code>true</code> can significantly speed up build times in certain cases, + but can also worsen documentation quality and user experience. For example, by + not resolving class/member links from your dependencies, including the standard library. + </p> + <p> + Note: You can cache fetched files locally and provide them to + Dokka as local paths. See <code>externalDocumentationLinks</code> section. + </p> + <p>Default: <code>false</code></p> + </def> + <def title="includes"> + <p> + A list of Markdown files that contain + <a href="https://kotlinlang.org/docs/reference/kotlin-doc.html#module-and-package-documentation">module and package documentation</a>. + </p> + <p>The contents of specified files are parsed and embedded into documentation as module and package descriptions.</p> + <p>This can be configured on per-package basis.</p> + </def> + <def title="sourceSets"> + <p> + Individual and additional configuration of Kotlin + <a href="https://kotlinlang.org/docs/multiplatform-discover-project.html#source-sets">source sets</a>. + </p> + <p>For a list of possible options, see <a href="#source-set-configuration">source set configuration</a>.</p> + </def> + <def title="sourceLinks"> + <p>The global configuration of source links that is applied for all source sets.</p> + <p>For a list of possible options, see <a href="#source-link-configuration">source link configuration</a>.</p> + </def> + <def title="perPackageOptions"> + <p>The global configuration of matched packages, regardless of the source set they are in.</p> + <p>For a list of possible options, see <a href="#per-package-configuration">per-package configuration</a>.</p> + </def> + <def title="externalDocumentationLinks"> + <p>The global configuration of external documentation links, regardless of the source set they are used in.</p> + <p>For a list of possible options, see <a href="#external-documentation-configuration">external documentation configuration</a>.</p> + </def> + <def title="pluginsClasspath"> + <p>A list of JAR files with Dokka plugins and their dependencies.</p> + </def> +</deflist> + +### Source set configuration + +How to configure Kotlin +[source sets](https://kotlinlang.org/docs/multiplatform-discover-project.html#source-sets): + +```json +{ + "sourceSets": [ + { + "displayName": "jvm", + "sourceSetID": { + "scopeId": "moduleName", + "sourceSetName": "main" + }, + "dependentSourceSets": [ + { + "scopeId": "dependentSourceSetScopeId", + "sourceSetName": "dependentSourceSetName" + } + ], + "documentedVisibilities": ["PUBLIC", "PRIVATE", "PROTECTED", "INTERNAL", "PACKAGE"], + "reportUndocumented": false, + "skipEmptyPackages": true, + "skipDeprecated": false, + "jdkVersion": 8, + "languageVersion": "1.7", + "apiVersion": "1.7", + "noStdlibLink": false, + "noJdkLink": false, + "includes": [ + "module.md" + ], + "analysisPlatform": "jvm", + "sourceRoots": [ + "/home/ignat/IdeaProjects/dokka-debug-mvn/src/main/kotlin" + ], + "classpath": [ + "libs/kotlin-stdlib-%kotlinVersion%.jar", + "libs/kotlin-stdlib-common-%kotlinVersion%.jar" + ], + "samples": [ + "samples/basic.kt" + ], + "suppressedFiles": [ + "src/main/kotlin/org/jetbrains/dokka/Suppressed.kt" + ], + "sourceLinks": [ + { "_comment": "Options are described in a separate section" } + ], + "perPackageOptions": [ + { "_comment": "Options are described in a separate section" } + ], + "externalDocumentationLinks": [ + { "_comment": "Options are described in a separate section" } + ] + } + ] +} +``` + +<deflist collapsible="true"> + <def title="displayName"> + <p>The display name used to refer to this source set.</p> + <p> + The name is used both externally (for example, the source set name is visible to documentation readers) and + internally (for example, for logging messages of <code>reportUndocumented</code>). + </p> + <p>The platform name can be used if you don't have a better alternative.</p> + </def> + <def title="sourceSetID"> + <p>The technical ID of the source set</p> + </def> + <def title="documentedVisibilities"> + <p>The set of visibility modifiers that should be documented.</p> + <p> + This can be used if you want to document protected/internal/private declarations, + as well as if you want to exclude public declarations and only document internal API. + </p> + <p>This can be configured on per-package basis.</p> + <p> + Possible values: + <list> + <li><code>PUBLIC</code></li> + <li><code>PRIVATE</code></li> + <li><code>PROTECTED</code></li> + <li><code>INTERNAL</code></li> + <li><code>PACKAGE</code></li> + </list> + </p> + <p>Default: <code>PUBLIC</code></p> + </def> + <def title="reportUndocumented"> + <p> + Whether to emit warnings about visible undocumented declarations, that is declarations without KDocs + after they have been filtered by <code>documentedVisibilities</code> and other filters. + </p> + <p>This setting works well with <code>failOnWarning</code>.</p> + <p>This can be configured on per-package basis.</p> + <p>Default: <code>false</code></p> + </def> + <def title="skipEmptyPackages"> + <p> + Whether to skip packages that contain no visible declarations after + various filters have been applied. + </p> + <p> + For example, if <code>skipDeprecated</code> is set to <code>true</code> and your package contains only + deprecated declarations, it is considered to be empty. + </p> + <p>Default for CLI runner is <code>false</code>.</p> + </def> + <def title="skipDeprecated"> + <p>Whether to document declarations annotated with <code>@Deprecated</code>.</p> + <p>This can be configured on per-package basis.</p> + <p>Default: <code>false</code></p> + </def> + <def title="jdkVersion"> + <p>The JDK version to use when generating external documentation links for Java types.</p> + <p> + For example, if you use <code>java.util.UUID</code> in some public declaration signature, + and this option is set to <code>8</code>, Dokka generates an external documentation link + to <a href="https://docs.oracle.com/javase/8/docs/api/java/util/UUID.html">JDK 8 Javadocs</a> for it. + </p> + </def> + <def title="languageVersion"> + <p> + <a href="https://kotlinlang.org/docs/compatibility-modes.html">The Kotlin language version</a> + used for setting up analysis and <a href="https://kotlinlang.org/docs/kotlin-doc.html#sample-identifier">@sample</a> + environment. + </p> + </def> + <def title="apiVersion"> + <p> + <a href="https://kotlinlang.org/docs/compatibility-modes.html">The Kotlin API version</a> + used for setting up analysis and <a href="https://kotlinlang.org/docs/kotlin-doc.html#sample-identifier">@sample</a> + environment. + </p> + </def> + <def title="noStdlibLink"> + <p> + Whether to generate external documentation links that lead to the API reference + documentation of Kotlin's standard library. + </p> + <p>Note: Links <b>are</b> generated when <code>noStdLibLink</code> is set to <code>false</code>.</p> + <p>Default: <code>false</code></p> + </def> + <def title="noJdkLink"> + <p>Whether to generate external documentation links to JDK's Javadocs.</p> + <p>The version of JDK Javadocs is determined by the <code>jdkVersion</code> option.</p> + <p>Note: Links <b>are</b> generated when <code>noJdkLink</code> is set to <code>false</code>.</p> + <p>Default: <code>false</code></p> + </def> + <def title="includes"> + <p> + A list of Markdown files that contain + <a href="https://kotlinlang.org/docs/reference/kotlin-doc.html#module-and-package-documentation">module and package documentation</a>. + </p> + <p>The contents of the specified files are parsed and embedded into documentation as module and package descriptions.</p> + </def> + <def title="analysisPlatform"> + <p> + Platform to be used for setting up code analysis and + <a href="https://kotlinlang.org/docs/kotlin-doc.html#sample-identifier">@sample</a> environment. + </p> + <p> + Possible values: + <list> + <li><code>jvm</code></li> + <li><code>common</code></li> + <li><code>js</code></li> + <li><code>native</code></li> + </list> + </p> + </def> + <def title="sourceRoots"> + <p> + The source code roots to be analyzed and documented. + Acceptable inputs are directories and individual <code>.kt</code> / <code>.java</code> files. + </p> + </def> + <def title="classpath"> + <p>The classpath for analysis and interactive samples.</p> + <p>This is useful if some types that come from dependencies are not resolved/picked up automatically.</p> + <p>This option accepts both <code>.jar</code> and <code>.klib</code> files.</p> + </def> + <def title="samples"> + <p> + A list of directories or files that contain sample functions which are referenced via the + <a href="https://kotlinlang.org/docs/kotlin-doc.html#sample-identifier">@sample</a> KDoc tag. + </p> + </def> + <def title="suppressedFiles"> + <p>The files to be suppressed when generating documentation.</p> + </def> + <def title="sourceLinks"> + <p>A set of parameters for source links that is applied only for this source set.</p> + <p>For a list of possible options, see <a href="#source-link-configuration">source link configuration</a>.</p> + </def> + <def title="perPackageOptions"> + <p>A set of parameters specific to matched packages within this source set.</p> + <p>For a list of possible options, see <a href="#per-package-configuration">per-package configuration</a>.</p> + </def> + <def title="externalDocumentationLinks"> + <p>A set of parameters for external documentation links that is applied only for this source set.</p> + <p>For a list of possible options, see <a href="#external-documentation-configuration">external documentation configuration</a>.</p> + </def> +</deflist> + +### Source link configuration + +The `sourceLinks` configuration block allows you to add a `source` link to each signature +that leads to the `remoteUrl` with a specific line number. (The line number is configurable by setting `remoteLineSuffix`). + +This helps readers to find the source code for each declaration. + +For an example, see the documentation for the +[`count()`](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/count.html) +function in `kotlinx.coroutines`. + +You can configure source links for all source sets together at the same time, or +[individually](#source-set-configuration): + +```json +{ + "sourceLinks": [ + { + "localDirectory": "src/main/kotlin", + "remoteUrl": "https://github.com/Kotlin/dokka/tree/master/src/main/kotlin", + "remoteLineSuffix": "#L" + } + ] +} +``` + +<deflist collapsible="true"> + <def title="localDirectory"> + <p>The path to the local source directory.</p> + </def> + <def title="remoteUrl"> + <p> + The URL of the source code hosting service that can be accessed by documentation readers, + like GitHub, GitLab, Bitbucket, etc. This URL is used to generate + source code links of declarations. + </p> + </def> + <def title="remoteLineSuffix"> + <p> + The suffix used to append the source code line number to the URL. This helps readers navigate + not only to the file, but to the specific line number of the declaration. + </p> + <p> + The number itself is appended to the specified suffix. For example, + if this option is set to <code>#L</code> and the line number is 10, the resulting URL suffix + is <code>#L10</code>. + </p> + <p> + Suffixes used by popular services: + <list> + <li>GitHub: <code>#L</code></li> + <li>GitLab: <code>#L</code></li> + <li>Bitbucket: <code>#lines-</code></li> + </list> + </p> + <p>Default: empty (no suffix)</p> + </def> +</deflist> + +### Per-package configuration + +The `perPackageOptions` configuration block allows setting some options for specific packages matched by `matchingRegex`. + +You can add package configurations for all source sets together at the same time, or +[individually](#source-set-configuration): + +```json +{ + "perPackageOptions": [ + { + "matchingRegex": ".*internal.*", + "suppress": false, + "skipDeprecated": false, + "reportUndocumented": false, + "documentedVisibilities": ["PUBLIC", "PRIVATE", "PROTECTED", "INTERNAL", "PACKAGE"] + } + ] +} +``` + +<deflist collapsible="true"> + <def title="matchingRegex"> + <p>The regular expression that is used to match the package.</p> + </def> + <def title="suppress"> + <p>Whether this package should be skipped when generating documentation.</p> + <p>Default: <code>false</code></p> + </def> + <def title="skipDeprecated"> + <p>Whether to document declarations annotated with <code>@Deprecated</code>.</p> + <p>This can be set on project/module level.</p> + <p>Default: <code>false</code></p> + </def> + <def title="reportUndocumented"> + <p> + Whether to emit warnings about visible undocumented declarations, that is declarations without KDocs + after they have been filtered by <code>documentedVisibilities</code> and other filters. + </p> + <p>This setting works well with <code>failOnWarning</code>.</p> + <p>This can be configured on source set level.</p> + <p>Default: <code>false</code></p> + </def> + <def title="documentedVisibilities"> + <p>The set of visibility modifiers that should be documented.</p> + <p> + This can be used if you want to document protected/internal/private declarations within this package, + as well as if you want to exclude public declarations and only document internal API. + </p> + <p>Can be configured on source set level.</p> + <p>Default: <code>PUBLIC</code></p> + </def> +</deflist> + +### External documentation configuration + +The `externalDocumentationLink` block allows the creation of links that lead to the externally hosted documentation of +your dependencies. + +For example, if you are using types from `kotlinx.serialization`, by default they are unclickable in your +documentation, as if they are unresolved. However, since the API reference documentation for `kotlinx.serialization` +is built by Dokka and is [published on kotlinlang.org](https://kotlinlang.org/api/kotlinx.serialization/), you can +configure external documentation links for it. Thus allowing Dokka to generate links for types from the library, making +them resolve successfully and clickable. + +You can configure external documentation links for all source sets together at the same time, or +[individually](#source-set-configuration): + +```json +{ + "externalDocumentationLinks": [ + { + "url": "https://kotlinlang.org/api/kotlinx.serialization/", + "packageListUrl": "https://kotlinlang.org/api/kotlinx.serialization/package-list" + } + ] +} +``` + +<deflist collapsible="true"> + <def title="url"> + <p>The root URL of documentation to link to. It <b>must</b> contain a trailing slash.</p> + <p> + Dokka does its best to automatically find <code>package-list</code> for the given URL, + and link declarations together. + </p> + <p> + If automatic resolution fails or if you want to use locally cached files instead, + consider setting the <code>packageListUrl</code> option. + </p> + </def> + <def title="packageListUrl"> + <p> + The exact location of a <code>package-list</code>. This is an alternative to relying on Dokka + automatically resolving it. + </p> + <p> + Package lists contain information about the documentation and the project itself, + such as module and package names. + </p> + <p>This can also be a locally cached file to avoid network calls.</p> + </def> +</deflist> + +### Complete configuration + +Below you can see all possible configuration options applied at the same time. + +```json +{ + "moduleName": "Dokka Example", + "moduleVersion": null, + "outputDir": "./build/dokka/html", + "failOnWarning": false, + "suppressObviousFunctions": true, + "suppressInheritedMembers": false, + "offlineMode": false, + "sourceLinks": [ + { + "localDirectory": "src/main/kotlin", + "remoteUrl": "https://github.com/Kotlin/dokka/tree/master/src/main/kotlin", + "remoteLineSuffix": "#L" + } + ], + "externalDocumentationLinks": [ + { + "url": "https://docs.oracle.com/javase/8/docs/api/", + "packageListUrl": "https://docs.oracle.com/javase/8/docs/api/package-list" + }, + { + "url": "https://kotlinlang.org/api/latest/jvm/stdlib/", + "packageListUrl": "https://kotlinlang.org/api/latest/jvm/stdlib/package-list" + } + ], + "perPackageOptions": [ + { + "matchingRegex": ".*internal.*", + "suppress": false, + "reportUndocumented": false, + "skipDeprecated": false, + "documentedVisibilities": ["PUBLIC", "PRIVATE", "PROTECTED", "INTERNAL", "PACKAGE"] + } + ], + "sourceSets": [ + { + "displayName": "jvm", + "sourceSetID": { + "scopeId": "moduleName", + "sourceSetName": "main" + }, + "dependentSourceSets": [ + { + "scopeId": "dependentSourceSetScopeId", + "sourceSetName": "dependentSourceSetName" + } + ], + "documentedVisibilities": ["PUBLIC", "PRIVATE", "PROTECTED", "INTERNAL", "PACKAGE"], + "reportUndocumented": false, + "skipEmptyPackages": true, + "skipDeprecated": false, + "jdkVersion": 8, + "languageVersion": "1.7", + "apiVersion": "1.7", + "noStdlibLink": false, + "noJdkLink": false, + "includes": [ + "module.md" + ], + "analysisPlatform": "jvm", + "sourceRoots": [ + "/home/ignat/IdeaProjects/dokka-debug-mvn/src/main/kotlin" + ], + "classpath": [ + "libs/kotlin-stdlib-%kotlinVersion%.jar", + "libs/kotlin-stdlib-common-%kotlinVersion%.jar" + ], + "samples": [ + "samples/basic.kt" + ], + "suppressedFiles": [ + "src/main/kotlin/org/jetbrains/dokka/Suppressed.kt" + ], + "sourceLinks": [ + { + "localDirectory": "src/main/kotlin", + "remoteUrl": "https://github.com/Kotlin/dokka/tree/master/src/main/kotlin", + "remoteLineSuffix": "#L" + } + ], + "externalDocumentationLinks": [ + { + "url": "https://docs.oracle.com/javase/8/docs/api/", + "packageListUrl": "https://docs.oracle.com/javase/8/docs/api/package-list" + }, + { + "url": "https://kotlinlang.org/api/latest/jvm/stdlib/", + "packageListUrl": "https://kotlinlang.org/api/latest/jvm/stdlib/package-list" + } + ], + "perPackageOptions": [ + { + "matchingRegex": ".*internal.*", + "suppress": false, + "reportUndocumented": false, + "skipDeprecated": false, + "documentedVisibilities": ["PUBLIC", "PRIVATE", "PROTECTED", "INTERNAL", "PACKAGE"] + } + ] + } + ], + "pluginsClasspath": [ + "./dokka-base-%dokkaVersion%.jar", + "./kotlinx-html-jvm-0.8.0.jar", + "./dokka-analysis-%dokkaVersion%.jar", + "./kotlin-analysis-intellij-%dokkaVersion%.jar", + "./kotlin-analysis-compiler-%dokkaVersion%.jar", + "./freemarker-2.3.31.jar" + ], + "pluginsConfiguration": [ + { + "fqPluginName": "org.jetbrains.dokka.base.DokkaBase", + "serializationFormat": "JSON", + "values": "{\"separateInheritedMembers\":false,\"footerMessage\":\"© 2021 pretty good Copyright\"}" + } + ], + "includes": [ + "module.md" + ] +} +``` diff --git a/docs/topics/runners/dokka-gradle.md b/docs/topics/runners/dokka-gradle.md new file mode 100644 index 00000000..21a42322 --- /dev/null +++ b/docs/topics/runners/dokka-gradle.md @@ -0,0 +1,1557 @@ +[//]: # (title: Gradle) + +To generate documentation for a Gradle-based project, you can use the +[Gradle plugin for Dokka](https://plugins.gradle.org/plugin/org.jetbrains.dokka). + +It comes with basic autoconfiguration for your project, has convenient [Gradle tasks](#generate-documentation) for +generating documentation, and provides a great deal of [configuration options](#configuration-options) to +customize the output. + +You can play around with Dokka and see how it can be configured for various projects by visiting our +[Gradle example projects](https://github.com/Kotlin/dokka/tree/%dokkaVersion%/examples/gradle). + +## Apply Dokka + +The recommended way of applying the Gradle plugin for Dokka is with the +[plugins DSL](https://docs.gradle.org/current/userguide/plugins.html#sec:plugins_block): + +<tabs group="build-script"> +<tab title="Kotlin" group-key="kotlin"> + +```kotlin +plugins { + id("org.jetbrains.dokka") version "%dokkaVersion%" +} +``` + +</tab> +<tab title="Groovy" group-key="groovy"> + +```groovy +plugins { + id 'org.jetbrains.dokka' version '%dokkaVersion%' +} +``` + +</tab> +</tabs> + +When documenting [multi-project](dokka-gradle.md#multi-project-builds) builds, you need to apply the Gradle plugin for Dokka +within subprojects as well. You can use `allprojects {}` or `subprojects {}` Gradle configurations to achieve that: + +<tabs group="build-script"> +<tab title="Gradle Kotlin DSL" group-key="kotlin"> + +```kotlin +subprojects { + apply(plugin = "org.jetbrains.dokka") +} +``` + +</tab> +<tab title="Gradle Groovy DSL" group-key="groovy"> + +```groovy +subprojects { + apply plugin: 'org.jetbrains.dokka' +} +``` + +</tab> +</tabs> + +See [Configuration examples](#configuration-examples) if you are not sure where to apply Dokka. + +> Under the hood, Dokka uses the [Kotlin Gradle plugin](https://kotlinlang.org/docs/gradle-configure-project.html#apply-the-plugin) +> to perform autoconfiguration of [source sets](https://kotlinlang.org/docs/multiplatform-discover-project.html#source-sets) +> for which documentation is to be generated. Make sure to apply the Kotlin Gradle Plugin or +> [configure source sets](#source-set-configuration) manually. +> +{type="note"} + +> If you are using Dokka in a +> [precompiled script plugin](https://docs.gradle.org/current/userguide/custom_plugins.html#sec:precompiled_plugins), +> you need to add the [Kotlin Gradle plugin](https://kotlinlang.org/docs/gradle-configure-project.html#apply-the-plugin) +> as a dependency for it to work properly: +> +> <tabs group="build-script"> +> <tab title="Kotlin" group-key="kotlin"> +> +> ```kotlin +> implementation(kotlin("gradle-plugin", "%kotlinVersion%")) +> ``` +> +> </tab> +> <tab title="Groovy" group-key="groovy"> +> +> ```groovy +> implementation 'org.jetbrains.kotlin:kotlin-gradle-plugin:%kotlinVersion%' +> ``` +> +> </tab> +> </tabs> +> +{type="note"} + +If you cannot use the plugins DSL for some reason, you can use +[the legacy method](https://docs.gradle.org/current/userguide/plugins.html#sec:old_plugin_application) of applying +plugins. + +## Generate documentation + +The Gradle plugin for Dokka comes with [HTML](dokka-html.md), [Markdown](dokka-markdown.md) and [Javadoc](dokka-javadoc.md) output formats +built in. It adds a number of tasks for generating documentation, both for [single](#single-project-builds) +and [multi-project](#multi-project-builds) builds. + +### Single-project builds + +Use the following tasks to build documentation for simple, single-project applications and libraries: + +#### Stable formats + +| **Task** | **Description** | +|----------------|-------------------------------------------------------------------------------------| +| `dokkaHtml` | Generates documentation in [HTML](dokka-html.md) format. | + +#### Experimental formats + +| **Task** | **Description** | +|----------------|-------------------------------------------------------------------------------------| +| `dokkaGfm` | Generates documentation in [GitHub Flavored Markdown](dokka-markdown.md#gfm) format. | +| `dokkaJavadoc` | Generates documentation in [Javadoc](dokka-javadoc.md) format. | +| `dokkaJekyll` | Generates documentation in [Jekyll compatible Markdown](dokka-markdown.md#jekyll) format. | + +By default, generated documentation is located in the `build/dokka/{format}` directory of your project. +The output location, among other things, can be [configured](#configuration-examples). + +### Multi-project builds + +For documenting [multi-project builds](https://docs.gradle.org/current/userguide/multi_project_builds.html), make sure +that you [apply the Gradle plugin for Dokka](#apply-dokka) within subprojects that you want to generate documentation +for, as well as in their parent project. + +#### MultiModule tasks + +`MultiModule` tasks generate documentation for each subproject individually via [`Partial`](#partial-tasks) tasks, +collect and process all outputs, and produce complete documentation with a common table of contents and resolved +cross-project references. + +Dokka creates the following tasks for **parent** projects automatically: + +#### Stable formats + +| **Task** | **Description** | +|--------------------------|------------------------------------------------------------------------| +| `dokkaHtmlMultiModule` | Generates multi-module documentation in [HTML](dokka-html.md) output format. | + +#### Experimental formats + +| **Task** | **Description** | +|--------------------------|---------------------------------------------------------------------------------------------------------| +| `dokkaGfmMultiModule` | Generates multi-module documentation in [GitHub Flavored Markdown](dokka-markdown.md#gfm) output format. | +| `dokkaJekyllMultiModule` | Generates multi-module documentation in [Jekyll compatible Markdown](dokka-markdown.md#jekyll) output format. | + +> The [Javadoc](dokka-javadoc.md) output format does not have a `MultiModule` task, but a [`Collector`](#collector-tasks) task can +> be used instead. +> +{type="note"} + +By default, you can find ready-to-use documentation under `{parentProject}/build/dokka/{format}MultiModule` directory. + +#### MultiModule results + +Given a project with the following structure: + +```text +parentProject + └── childProjectA + ├── demo + ├── ChildProjectAClass + └── childProjectB + ├── demo + ├── ChildProjectBClass +``` + +These pages are generated after running `dokkaHtmlMultiModule`: + +![Screenshot for output of dokkaHtmlMultiModule task](dokkaHtmlMultiModule-example.png){width=600} + +See our [multi-module project example](https://github.com/Kotlin/dokka/tree/master/examples/gradle/dokka-multimodule-example) +for more details. + +#### Collector tasks + +Similar to `MultiModule` tasks, `Collector` tasks are created for each parent project: `dokkaHtmlCollector`, +`dokkaGfmCollector`, `dokkaJavadocCollector` and `dokkaJekyllCollector`. + +A `Collector` task executes the corresponding [single-project task](#single-project-builds) for each subproject (for +example, +`dokkaHtml`), and merges all outputs into a single virtual project. + +The resulting documentation looks as if you have a single-project +build that contains all declarations from the subprojects. + +> Use the `dokkaJavadocCollector` task if you need to create Javadoc documentation for your multi-project build. +> +{type="tip"} + +#### Collector results + +Given a project with the following structure: + +```text +parentProject + └── childProjectA + ├── demo + ├── ChildProjectAClass + └── childProjectB + ├── demo + ├── ChildProjectBClass +``` + +These pages are generated after running `dokkaHtmlCollector`: + +![Screenshot for output of dokkaHtmlCollector task](dokkaHtmlCollector-example.png){width=800} + +See our [multi-module project example](https://github.com/Kotlin/dokka/tree/master/examples/gradle/dokka-multimodule-example) +for more details. + +#### Partial tasks + +Each subproject has `Partial` tasks created for it: `dokkaHtmlPartial`,`dokkaGfmPartial`, +and `dokkaJekyllPartial`. + +These tasks are not intended to be run independently, they are called by the parent's +[MultiModule](#multimodule-tasks) task. + +However, you can [configure](#subproject-configuration) `Partial` tasks to customize Dokka for your subprojects. + +> Output generated by `Partial` tasks contains unresolved HTML templates and references, so it cannot be used +> on its own without post-processing done by the parent's [`MultiModule`](#multimodule-tasks) task. +> +{type="warning"} + +> If you want to generate documentation for a single subproject only, use +> [single-project tasks](#single-project-builds). For example, `:subprojectName:dokkaHtml`. +> +{type="note"} + +## Build javadoc.jar + +If you want to publish your library to a repository, you may need to provide a `javadoc.jar` file that contains +API reference documentation of your library. + +For example, if you want to publish to [Maven Central](https://central.sonatype.org/), you +[must](https://central.sonatype.org/publish/requirements/) supply a `javadoc.jar` alongside your project. However, +not all repositories have that rule. + +The Gradle plugin for Dokka does not provide any way to do this out of the box, but it can be achieved with custom Gradle +tasks. One for generating documentation in [HTML](dokka-html.md) format and another one for [Javadoc](dokka-javadoc.md) format: + +<tabs group="build-script"> +<tab title="Kotlin" group-key="kotlin"> + +```kotlin +tasks.register<Jar>("dokkaHtmlJar") { + dependsOn(tasks.dokkaHtml) + from(tasks.dokkaHtml.flatMap { it.outputDirectory }) + archiveClassifier.set("html-docs") +} + +tasks.register<Jar>("dokkaJavadocJar") { + dependsOn(tasks.dokkaJavadoc) + from(tasks.dokkaJavadoc.flatMap { it.outputDirectory }) + archiveClassifier.set("javadoc") +} +``` + +</tab> +<tab title="Groovy" group-key="groovy"> + +```groovy +tasks.register('dokkaHtmlJar', Jar.class) { + dependsOn(dokkaHtml) + from(dokkaHtml) + archiveClassifier.set("html-docs") +} + +tasks.register('dokkaJavadocJar', Jar.class) { + dependsOn(dokkaJavadoc) + from(dokkaJavadoc) + archiveClassifier.set("javadoc") +} +``` + +</tab> +</tabs> + +> If you publish your library to Maven Central, you can use services like [javadoc.io](https://javadoc.io/) to +> host your library's API documentation for free and without any setup. It takes documentation pages straight +> from the `javadoc.jar`. It works well with the HTML format as demonstrated in +> [this example](https://javadoc.io/doc/com.trib3/server/latest/index.html). +> +{type="tip"} + +## Configuration examples + +Depending on the type of project that you have, the way you apply and configure Dokka differs slightly. However, +[configuration options](#configuration-options) themselves are the same, regardless of the type of your project. + +For simple and flat projects with a single `build.gradle.kts` or `build.gradle` file found in the root of your project, +see [Single-project configuration](#single-project-configuration). + +For a more complex build with subprojects and multiple nested `build.gradle.kts` or `build.gradle` files, +see [Multi-project configuration](#multi-project-configuration). + +### Single-project configuration + +Single-project builds usually have only one `build.gradle.kts` or `build.gradle` file in the root of the project, +and typically have the following structure: + +<tabs group="build-script"> +<tab title="Kotlin" group-key="kotlin"> + +Single platform: + +```text +. +├── build.gradle.kts +└── src + └── main + └── kotlin + └── HelloWorld.kt +``` + +Multiplatform: + +```text +. +├── build.gradle.kts +└── src + └── commonMain + └── kotlin + └── Common.kt + └── jvmMain + └── kotlin + └── JvmUtils.kt + └── nativeMain + └── kotlin + └── NativeUtils.kt +``` + +</tab> +<tab title="Groovy" group-key="groovy"> + +Single platform: + +```text +. +├── build.gradle +└── src + └── main + └── kotlin + └── HelloWorld.kt +``` + +Multiplatform: + +```text +. +├── build.gradle +└── src + └── commonMain + └── kotlin + └── Common.kt + └── jvmMain + └── kotlin + └── JvmUtils.kt + └── nativeMain + └── kotlin + └── NativeUtils.kt +``` + +</tab> +</tabs> + +In such projects, you need to apply Dokka and its configuration in the root `build.gradle.kts` or `build.gradle` file. + +You can configure tasks and output formats individually: + +<tabs group="build-script"> +<tab title="Kotlin" group-key="kotlin"> + +Inside `./build.gradle.kts`: + +```kotlin +plugins { + id("org.jetbrains.dokka") version "%dokkaVersion%" +} + +tasks.dokkaHtml { + outputDirectory.set(buildDir.resolve("documentation/html")) +} + +tasks.dokkaGfm { + outputDirectory.set(buildDir.resolve("documentation/markdown")) +} +``` + +</tab> +<tab title="Groovy" group-key="groovy"> + +Inside `./build.gradle`: + +```groovy +plugins { + id 'org.jetbrains.dokka' version '%dokkaVersion%' +} + +dokkaHtml { + outputDirectory.set(file("build/documentation/html")) +} + +dokkaGfm { + outputDirectory.set(file("build/documentation/markdown")) +} +``` + +</tab> +</tabs> + +Or you can configure all tasks and output formats at the same time: + +<tabs group="build-script"> +<tab title="Kotlin" group-key="kotlin"> + +Inside `./build.gradle.kts`: + +```kotlin +import org.jetbrains.dokka.gradle.DokkaTask +import org.jetbrains.dokka.gradle.DokkaTaskPartial +import org.jetbrains.dokka.DokkaConfiguration.Visibility + +plugins { + id("org.jetbrains.dokka") version "%dokkaVersion%" +} + +// Configure all single-project Dokka tasks at the same time, +// such as dokkaHtml, dokkaJavadoc and dokkaGfm. +tasks.withType<DokkaTask>().configureEach { + dokkaSourceSets.configureEach { + documentedVisibilities.set( + setOf( + Visibility.PUBLIC, + Visibility.PROTECTED, + ) + ) + + perPackageOption { + matchingRegex.set(".*internal.*") + suppress.set(true) + } + } +} +``` + +</tab> +<tab title="Groovy" group-key="groovy"> + +Inside `./build.gradle`: + +```groovy +import org.jetbrains.dokka.gradle.DokkaTask +import org.jetbrains.dokka.gradle.DokkaTaskPartial +import org.jetbrains.dokka.DokkaConfiguration.Visibility + +plugins { + id 'org.jetbrains.dokka' version '%dokkaVersion%' +} + +// Configure all single-project Dokka tasks at the same time, +// such as dokkaHtml, dokkaJavadoc and dokkaGfm. +tasks.withType(DokkaTask.class) { + dokkaSourceSets.configureEach { + documentedVisibilities.set([ + DokkaConfiguration.Visibility.PUBLIC, + DokkaConfiguration.Visibility.PROTECTED + ]) + + perPackageOption { + matchingRegex.set(".*internal.*") + suppress.set(true) + } + } +} +``` + +</tab> +</tabs> + +### Multi-project configuration + +Gradle's [multi-project builds](https://docs.gradle.org/current/userguide/multi_project_builds.html) are more complex +in structure and configuration. They usually have multiple nested `build.gradle.kts` or `build.gradle` files, and +typically have the following structure: + +<tabs group="build-script"> +<tab title="Kotlin" group-key="kotlin"> + +```text +. +├── build.gradle.kts +├── settings.gradle.kts +├── subproject-A + └── build.gradle.kts + └── src + └── main + └── kotlin + └── HelloFromA.kt +├── subproject-B + └── build.gradle.kts + └── src + └── main + └── kotlin + └── HelloFromB.kt +``` + +</tab> +<tab title="Groovy" group-key="groovy"> + +```text +. +├── build.gradle +├── settings.gradle +├── subproject-A + └── build.gradle + └── src + └── main + └── kotlin + └── HelloFromA.kt +├── subproject-B + └── build.gradle + └── src + └── main + └── kotlin + └── HelloFromB.kt +``` + +</tab> +</tabs> + +In this case, there are multiple ways of applying and configuring Dokka. + +#### Subproject configuration + +To configure subprojects in a multi-project build, you need to configure [`Partial`](#partial-tasks) tasks. + +You can configure all subprojects at the same time in the root `build.gradle.kts` or `build.gradle` file, +using Gradle's `allprojects {}` or `subprojects {}` configuration blocks: + +<tabs group="build-script"> +<tab title="Kotlin" group-key="kotlin"> + +In the root `./build.gradle.kts`: + +```kotlin +import org.jetbrains.dokka.gradle.DokkaTaskPartial + +plugins { + id("org.jetbrains.dokka") version "%dokkaVersion%" +} + +subprojects { + apply(plugin = "org.jetbrains.dokka") + + // configure only the HTML task + tasks.dokkaHtmlPartial { + outputDirectory.set(buildDir.resolve("docs/partial")) + } + + // configure all format tasks at once + tasks.withType<DokkaTaskPartial>().configureEach { + dokkaSourceSets.configureEach { + includes.from("README.md") + } + } +} +``` + +</tab> +<tab title="Groovy" group-key="groovy"> + +In the root `./build.gradle`: + +```groovy +import org.jetbrains.dokka.gradle.DokkaTaskPartial + +plugins { + id 'org.jetbrains.dokka' version '%dokkaVersion%' +} + +subprojects { + apply plugin: 'org.jetbrains.dokka' + + // configure only the HTML task + dokkaHtmlPartial { + outputDirectory.set(file("build/docs/partial")) + } + + // configure all format tasks at once + tasks.withType(DokkaTaskPartial.class) { + dokkaSourceSets.configureEach { + includes.from("README.md") + } + } +} +``` + +</tab> +</tabs> + +Alternatively, you can apply and configure Dokka within subprojects individually. + +For example, to have specific settings for the `subproject-A` subproject only, you need to apply the following code +inside `./subproject-A/build.gradle.kts`: + +<tabs group="build-script"> +<tab title="Kotlin" group-key="kotlin"> + +Inside `./subproject-A/build.gradle.kts`: + +```kotlin +apply(plugin = "org.jetbrains.dokka") + +// configuration for subproject-A only. +tasks.dokkaHtmlPartial { + outputDirectory.set(buildDir.resolve("docs/partial")) +} +``` + +</tab> +<tab title="Groovy" group-key="groovy"> + +Inside `./subproject-A/build.gradle`: + +```groovy +apply plugin: 'org.jetbrains.dokka' + +// configuration for subproject-A only. +dokkaHtmlPartial { + outputDirectory.set(file("build/docs/partial")) +} +``` + +</tab> +</tabs> + +#### Parent project configuration + +If you want to configure something which is universal across all documentation and does not belong to the +subprojects - in other words, it's a property of the parent project - you need to configure the +[`MultiModule`](#multimodule-tasks) tasks. + +For example, if you want to change the name of your project which is used in the header of the HTML documentation, +you need to apply the following inside the root `build.gradle.kts` or `build.gradle` file: + +<tabs group="build-script"> +<tab title="Kotlin" group-key="kotlin"> + +In the root `./build.gradle.kts` file: + +```kotlin +plugins { + id("org.jetbrains.dokka") version "%dokkaVersion%" +} + +tasks.dokkaHtmlMultiModule { + moduleName.set("WHOLE PROJECT NAME USED IN THE HEADER") +} +``` + +</tab> +<tab title="Groovy" group-key="groovy"> + +In the root `./build.gradle` file: + +```groovy +plugins { + id 'org.jetbrains.dokka' version '%dokkaVersion%' +} + +dokkaHtmlMultiModule { + moduleName.set("WHOLE PROJECT NAME USED IN THE HEADER") +} +``` + +</tab> +</tabs> + +## Configuration options + +Dokka has many configuration options to tailor your and your reader's experience. + +Below are some examples and detailed descriptions for each configuration section. You can also find an example +with [all configuration options](#complete-configuration) applied at the bottom of the page. + +See [Configuration examples](#configuration-examples) for more details on where to apply configuration blocks and how. + +### General configuration + +Here is an example of general configuration of any Dokka task, regardless of source set or package: + +<tabs group="build-script"> +<tab title="Kotlin" group-key="kotlin"> + +```kotlin +import org.jetbrains.dokka.gradle.DokkaTask + +// Note: To configure multi-project builds, you need +// to configure Partial tasks of the subprojects. +// See "Configuration example" section of documentation. +tasks.withType<DokkaTask>().configureEach { + moduleName.set(project.name) + moduleVersion.set(project.version.toString()) + outputDirectory.set(buildDir.resolve("dokka/$name")) + failOnWarning.set(false) + suppressObviousFunctions.set(true) + suppressInheritedMembers.set(false) + offlineMode.set(false) + + // .. + // source set configuration section + // .. +} +``` + +</tab> +<tab title="Groovy" group-key="groovy"> + +```groovy +import org.jetbrains.dokka.gradle.DokkaTask + +// Note: To configure multi-project builds, you need +// to configure Partial tasks of the subprojects. +// See "Configuration example" section of documentation. +tasks.withType(DokkaTask.class) { + moduleName.set(project.name) + moduleVersion.set(project.version.toString()) + outputDirectory.set(file("build/dokka/$name")) + failOnWarning.set(false) + suppressObviousFunctions.set(true) + suppressInheritedMembers.set(false) + offlineMode.set(false) + + // .. + // source set configuration section + // .. +} +``` + +</tab> +</tabs> + +<deflist collapsible="true"> + <def title="moduleName"> + <p>The display name used to refer to the module. It is used for the table of contents, navigation, logging, etc.</p> + <p>If set for a single-project build or a <code>MultiModule</code> task, it is used as the project name.</p> + <p>Default: Gradle project name</p> + </def> + <def title="moduleVersion"> + <p> + The module version. If set for a single-project build or a <code>MultiModule</code> task, it is used as the + project version. + </p> + <p>Default: Gradle project version</p> + </def> + <def title="outputDirectory"> + <p>The directory to where documentation is generated, regardless of format. It can be set on a per-task basis.</p> + <p> + The default is <code>{project}/{buildDir}/{format}</code>, where <code>{format}</code> is the task name with + the "dokka" prefix removed. For the <code>dokkaHtmlMultiModule</code> task, it is + <code>project/buildDir/htmlMultiModule</code>. + </p> + </def> + <def title="failOnWarning"> + <p> + Whether to fail documentation generation if Dokka has emitted a warning or an error. + The process waits until all errors and warnings have been emitted first. + </p> + <p>This setting works well with <code>reportUndocumented</code>.</p> + <p>Default: <code>false</code></p> + </def> + <def title="suppressObviousFunctions"> + <p>Whether to suppress obvious functions.</p> + <p> + A function is considered to be obvious if it is: + <list> + <li> + Inherited from <code>kotlin.Any</code>, <code>Kotlin.Enum</code>, <code>java.lang.Object</code> or + <code>java.lang.Enum</code>, such as <code>equals</code>, <code>hashCode</code>, <code>toString</code>. + </li> + <li> + Synthetic (generated by the compiler) and does not have any documentation, such as + <code>dataClass.componentN</code> or <code>dataClass.copy</code>. + </li> + </list> + </p> + <p>Default: <code>true</code></p> + </def> + <def title="suppressInheritedMembers"> + <p>Whether to suppress inherited members that aren't explicitly overridden in a given class.</p> + <p> + Note: This can suppress functions such as <code>equals</code> / <code>hashCode</code> / <code>toString</code>, + but cannot suppress synthetic functions such as <code>dataClass.componentN</code> and + <code>dataClass.copy</code>. Use <code>suppressObviousFunctions</code> + for that. + </p> + <p>Default: <code>false</code></p> + </def> + <def title="offlineMode"> + <p>Whether to resolve remote files/links over your network.</p> + <p> + This includes package-lists used for generating external documentation links. + For example, to make classes from the standard library clickable. + </p> + <p> + Setting this to <code>true</code> can significantly speed up build times in certain cases, + but can also worsen documentation quality and user experience. For example, by + not resolving class/member links from your dependencies, including the standard library. + </p> + <p> + Note: You can cache fetched files locally and provide them to + Dokka as local paths. See <code>externalDocumentationLinks</code> section. + </p> + <p>Default: <code>false</code></p> + </def> +</deflist> + +### Source set configuration + +Dokka allows configuring some options for +[Kotlin source sets](https://kotlinlang.org/docs/multiplatform-discover-project.html#source-sets): + +<tabs group="build-script"> +<tab title="Kotlin" group-key="kotlin"> + +```kotlin +import org.jetbrains.dokka.DokkaConfiguration.Visibility +import org.jetbrains.dokka.gradle.DokkaTask +import org.jetbrains.dokka.Platform +import java.net.URL + +// Note: To configure multi-project builds, you need +// to configure Partial tasks of the subprojects. +// See "Configuration example" section of documentation. +tasks.withType<DokkaTask>().configureEach { + // .. + // general configuration section + // .. + + // configuration exclusive to the 'linux' source set + named("linux") { + dependsOn("native") + sourceRoots.from(file("linux/src")) + } + + dokkaSourceSets.configureEach { + suppress.set(false) + displayName.set(name) + documentedVisibilities.set(setOf(Visibility.PUBLIC)) + reportUndocumented.set(false) + skipEmptyPackages.set(true) + skipDeprecated.set(false) + suppressGeneratedFiles.set(true) + jdkVersion.set(8) + languageVersion.set("1.7") + apiVersion.set("1.7") + noStdlibLink.set(false) + noJdkLink.set(false) + noAndroidSdkLink.set(false) + includes.from(project.files(), "packages.md", "extra.md") + platform.set(Platform.DEFAULT) + sourceRoots.from(file("src")) + classpath.from(project.files(), file("libs/dependency.jar")) + samples.from(project.files(), "samples/Basic.kt", "samples/Advanced.kt") + + sourceLink { + // Source link section + } + externalDocumentationLink { + // External documentation link section + } + perPackageOption { + // Package options section + } + } +} +``` + +</tab> +<tab title="Groovy" group-key="groovy"> + +```groovy +import org.jetbrains.dokka.DokkaConfiguration.Visibility +import org.jetbrains.dokka.gradle.DokkaTask +import org.jetbrains.dokka.Platform +import java.net.URL + +// Note: To configure multi-project builds, you need +// to configure Partial tasks of the subprojects. +// See "Configuration example" section of documentation. +tasks.withType(DokkaTask.class) { + // .. + // general configuration section + // .. + + // configuration exclusive to the 'linux' source set + named("linux") { + dependsOn("native") + sourceRoots.from(file("linux/src")) + } + + dokkaSourceSets.configureEach { + suppress.set(false) + displayName.set(name) + documentedVisibilities.set([Visibility.PUBLIC]) + reportUndocumented.set(false) + skipEmptyPackages.set(true) + skipDeprecated.set(false) + suppressGeneratedFiles.set(true) + jdkVersion.set(8) + languageVersion.set("1.7") + apiVersion.set("1.7") + noStdlibLink.set(false) + noJdkLink.set(false) + noAndroidSdkLink.set(false) + includes.from(project.files(), "packages.md", "extra.md") + platform.set(Platform.DEFAULT) + sourceRoots.from(file("src")) + classpath.from(project.files(), file("libs/dependency.jar")) + samples.from(project.files(), "samples/Basic.kt", "samples/Advanced.kt") + + sourceLink { + // Source link section + } + externalDocumentationLink { + // External documentation link section + } + perPackageOption { + // Package options section + } + } +} +``` + +</tab> +</tabs> + +<deflist collapsible="true"> + <def title="suppress"> + <p>Whether this source set should be skipped when generating documentation.</p> + <p>Default: <code>false</code></p> + </def> + <def title="displayName"> + <p>The display name used to refer to this source set.</p> + <p> + The name is used both externally (for example, as source set name visible to documentation readers) and + internally (for example, for logging messages of <code>reportUndocumented</code>). + </p> + <p>By default, the value is deduced from information provided by the Kotlin Gradle plugin.</p> + </def> + <def title="documentedVisibilities"> + <p>The set of visibility modifiers that should be documented.</p> + <p> + This can be used if you want to document protected/internal/private declarations, + as well as if you want to exclude public declarations and only document internal API. + </p> + <p>This can be configured on per-package basis.</p> + <p>Default: <code>DokkaConfiguration.Visibility.PUBLIC</code></p> + </def> + <def title="reportUndocumented"> + <p> + Whether to emit warnings about visible undocumented declarations, that is declarations without KDocs + after they have been filtered by <code>documentedVisibilities</code> and other filters. + </p> + <p>This setting works well with <code>failOnWarning</code>.</p> + <p>This can be configured on per-package basis.</p> + <p>Default: <code>false</code></p> + </def> + <def title="skipEmptyPackages"> + <p> + Whether to skip packages that contain no visible declarations after + various filters have been applied. + </p> + <p> + For example, if <code>skipDeprecated</code> is set to <code>true</code> and your package contains only + deprecated declarations, it is considered to be empty. + </p> + <p>Default: <code>true</code></p> + </def> + <def title="skipDeprecated"> + <p>Whether to document declarations annotated with <code>@Deprecated</code>.</p> + <p>This can be configured on per-package basis.</p> + <p>Default: <code>false</code></p> + </def> + <def title="suppressGeneratedFiles"> + <p>Whether to document/analyze generated files.</p> + <p> + Generated files are expected to be present under the <code>{project}/{buildDir}/generated</code> directory. + </p> + <p> + If set to <code>true</code>, it effectively adds all files from that directory to the + <code>suppressedFiles</code> option, so you can configure it manually. + </p> + <p>Default: <code>true</code></p> + </def> + <def title="jdkVersion"> + <p>The JDK version to use when generating external documentation links for Java types.</p> + <p> + For example, if you use <code>java.util.UUID</code> in some public declaration signature, + and this option is set to <code>8</code>, Dokka generates an external documentation link + to <a href="https://docs.oracle.com/javase/8/docs/api/java/util/UUID.html">JDK 8 Javadocs</a> for it. + </p> + <p>Default: JDK 8</p> + </def> + <def title="languageVersion"> + <p> + <a href="https://kotlinlang.org/docs/compatibility-modes.html">The Kotlin language version</a> + used for setting up analysis and <a href="https://kotlinlang.org/docs/kotlin-doc.html#sample-identifier">@sample</a> + environment. + </p> + <p>By default, the latest language version available to Dokka's embedded compiler is used.</p> + </def> + <def title="apiVersion"> + <p> + <a href="https://kotlinlang.org/docs/compatibility-modes.html">The Kotlin API version</a> + used for setting up analysis and <a href="https://kotlinlang.org/docs/kotlin-doc.html#sample-identifier">@sample</a> + environment. + </p> + <p>By default, it is deduced from <code>languageVersion</code>.</p> + </def> + <def title="noStdlibLink"> + <p> + Whether to generate external documentation links that lead to the API reference + documentation of Kotlin's standard library. + </p> + <p>Note: Links <b>are</b> generated when <code>noStdLibLink</code> is set to <code>false</code>.</p> + <p>Default: <code>false</code></p> + </def> + <def title="noJdkLink"> + <p>Whether to generate external documentation links to JDK's Javadocs.</p> + <p>The version of JDK Javadocs is determined by the <code>jdkVersion</code> option.</p> + <p>Note: Links <b>are</b> generated when <code>noJdkLink</code> is set to <code>false</code>.</p> + <p>Default: <code>false</code></p> + </def> + <def title="noAndroidSdkLink"> + <p>Whether to generate external documentation links to the Android SDK API reference</p> + <p>This is only relevant in Android projects, ignored otherwise.</p> + <p>Note: Links <b>are</b> generated when <code>noAndroidSdkLink</code> is set to <code>false</code>.</p> + <p>Default: <code>false</code></p> + </def> + <def title="includes"> + <p> + A list of Markdown files that contain + <a href="https://kotlinlang.org/docs/reference/kotlin-doc.html#module-and-package-documentation">module and package documentation</a>. + </p> + <p>The contents of the specified files are parsed and embedded into documentation as module and package descriptions.</p> + <p> + See <a href="https://github.com/Kotlin/dokka/tree/master/examples/gradle/dokka-gradle-example">Dokka gradle example</a> + for an example of what it looks like and how to use it. + </p> + </def> + <def title="platform"> + <p> + The platform to be used for setting up code analysis and + <a href="https://kotlinlang.org/docs/kotlin-doc.html#sample-identifier">@sample</a> environment. + </p> + <p>The default value is deduced from information provided by the Kotlin Gradle plugin.</p> + </def> + <def title="sourceRoots"> + <p> + The source code roots to be analyzed and documented. + Acceptable inputs are directories and individual <code>.kt</code> / <code>.java</code> files. + </p> + <p>By default, source roots are deduced from information provided by the Kotlin Gradle plugin.</p> + </def> + <def title="classpath"> + <p>The classpath for analysis and interactive samples.</p> + <p>This is useful if some types that come from dependencies are not resolved/picked up automatically.</p> + <p>This option accepts both <code>.jar</code> and <code>.klib</code> files.</p> + <p>By default, classpath is deduced from information provided by the Kotlin Gradle plugin.</p> + </def> + <def title="samples"> + <p> + A list of directories or files that contain sample functions which are referenced via the + <a href="https://kotlinlang.org/docs/kotlin-doc.html#sample-identifier">@sample</a> KDoc tag. + </p> + </def> +</deflist> + +### Source link configuration + +The `sourceLinks` configuration block allows you to add a `source` link to each signature +that leads to the `remoteUrl` with a specific line number. (The line number is configurable by setting `remoteLineSuffix`). + +This helps readers to find the source code for each declaration. + +For an example, see the documentation for the +[`count()`](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/count.html) +function in `kotlinx.coroutines`. + +<tabs group="build-script"> +<tab title="Kotlin" group-key="kotlin"> + +```kotlin +import org.jetbrains.dokka.gradle.DokkaTask +import java.net.URL + +// Note: To configure multi-project builds, you need +// to configure Partial tasks of the subprojects. +// See "Configuration example" section of documentation. +tasks.withType<DokkaTask>().configureEach { + // .. + // general configuration section + // .. + + dokkaSourceSets.configureEach { + // .. + // source set configuration section + // .. + + sourceLink { + localDirectory.set(projectDir.resolve("src")) + remoteUrl.set(URL("https://github.com/kotlin/dokka/tree/master/src")) + remoteLineSuffix.set("#L") + } + } +} +``` + +</tab> +<tab title="Groovy" group-key="groovy"> + +```groovy +import org.jetbrains.dokka.gradle.DokkaTask +import java.net.URL + +// Note: To configure multi-project builds, you need +// to configure Partial tasks of the subprojects. +// See "Configuration example" section of documentation. +tasks.withType(DokkaTask.class) { + // .. + // general configuration section + // .. + + dokkaSourceSets.configureEach { + // .. + // source set configuration section + // .. + + sourceLink { + localDirectory.set(file("src")) + remoteUrl.set(new URL("https://github.com/kotlin/dokka/tree/master/src")) + remoteLineSuffix.set("#L") + } + } +} +``` + +</tab> +</tabs> + +<deflist collapsible="true"> + <def title="localDirectory"> + <p> + The path to the local source directory. The path must be relative to the root of + the current project. + </p> + </def> + <def title="remoteUrl"> + <p> + The URL of the source code hosting service that can be accessed by documentation readers, + like GitHub, GitLab, Bitbucket, etc. This URL is used to generate + source code links of declarations. + </p> + </def> + <def title="remoteLineSuffix"> + <p> + The suffix used to append the source code line number to the URL. This helps readers navigate + not only to the file, but to the specific line number of the declaration. + </p> + <p> + The number itself is appended to the specified suffix. For example, + if this option is set to <code>#L</code> and the line number is 10, the resulting URL suffix + is <code>#L10</code>. + </p> + <p> + Suffixes used by popular services: + <list> + <li>GitHub: <code>#L</code></li> + <li>GitLab: <code>#L</code></li> + <li>Bitbucket: <code>#lines-</code></li> + </list> + </p> + <p>Default: <code>#L</code></p> + </def> +</deflist> + +### Package options + +The `perPackageOption` configuration block allows setting some options for specific packages matched by `matchingRegex`. + +<tabs group="build-script"> +<tab title="Kotlin" group-key="kotlin"> + +```kotlin +import org.jetbrains.dokka.DokkaConfiguration.Visibility +import org.jetbrains.dokka.gradle.DokkaTask + +// Note: To configure multi-project builds, you need +// to configure Partial tasks of the subprojects. +// See "Configuration example" section of documentation. +tasks.withType<DokkaTask>().configureEach { + // .. + // general configuration section + // .. + + dokkaSourceSets.configureEach { + // .. + // source set configuration section + // .. + + perPackageOption { + matchingRegex.set(".*api.*") + suppress.set(false) + skipDeprecated.set(false) + reportUndocumented.set(false) + documentedVisibilities.set(setOf(Visibility.PUBLIC)) + } + } +} +``` + +</tab> +<tab title="Groovy" group-key="groovy"> + +```groovy +import org.jetbrains.dokka.DokkaConfiguration.Visibility +import org.jetbrains.dokka.gradle.DokkaTask + +// Note: To configure multi-project builds, you need +// to configure Partial tasks of the subprojects. +// See "Configuration example" section of documentation. +tasks.withType(DokkaTask.class) { + // .. + // general configuration section + // .. + + dokkaSourceSets.configureEach { + // .. + // Source set configuration section + // .. + + perPackageOption { + matchingRegex.set(".*api.*") + suppress.set(false) + skipDeprecated.set(false) + reportUndocumented.set(false) + documentedVisibilities.set([Visibility.PUBLIC]) + } + } +} +``` + +</tab> +</tabs> + +<deflist collapsible="true"> + <def title="matchingRegex"> + <p>The regular expression that is used to match the package.</p> + <p>Default: <code>.*</code></p> + </def> + <def title="suppress"> + <p>Whether this package should be skipped when generating documentation.</p> + <p>Default: <code>false</code></p> + </def> + <def title="skipDeprecated"> + <p>Whether to document declarations annotated with <code>@Deprecated</code>.</p> + <p>This can be configured on source set level.</p> + <p>Default: <code>false</code></p> + </def> + <def title="reportUndocumented"> + <p> + Whether to emit warnings about visible undocumented declarations, that is declarations without KDocs + after they have been filtered by <code>documentedVisibilities</code> and other filters. + </p> + <p>This setting works well with <code>failOnWarning</code>.</p> + <p>This can be configured on source set level.</p> + <p>Default: <code>false</code></p> + </def> + <def title="documentedVisibilities"> + <p>The set of visibility modifiers that should be documented.</p> + <p> + This can be used if you want to document protected/internal/private declarations within this package, + as well as if you want to exclude public declarations and only document internal API. + </p> + <p>This can be configured on source set level.</p> + <p>Default: <code>DokkaConfiguration.Visibility.PUBLIC</code></p> + </def> +</deflist> + +### External documentation links configuration + +The `externalDocumentationLink` block allows the creation of links that lead to the externally hosted documentation of +your dependencies. + +For example, if you are using types from `kotlinx.serialization`, by default they are unclickable in your +documentation, as if they are unresolved. However, since the API reference documentation for `kotlinx.serialization` +is built by Dokka and is [published on kotlinlang.org](https://kotlinlang.org/api/kotlinx.serialization/), you can +configure external documentation links for it. Thus allowing Dokka to generate links for types from the library, making +them resolve successfully and clickable. + +By default, external documentation links for Kotlin standard library, JDK, Android SDK and AndroidX are configured. + +<tabs group="build-script"> +<tab title="Kotlin" group-key="kotlin"> + +```kotlin +import org.jetbrains.dokka.gradle.DokkaTask +import java.net.URL + +// Note: To configure multi-project builds, you need +// to configure Partial tasks of the subprojects. +// See "Configuration example" section of documentation. +tasks.withType<DokkaTask>().configureEach { + // .. + // general configuration section + // .. + + dokkaSourceSets.configureEach { + // .. + // source set configuration section + // .. + + externalDocumentationLink { + url.set(URL("https://kotlinlang.org/api/kotlinx.serialization/")) + packageListUrl.set( + rootProject.projectDir.resolve("serialization.package.list").toURL() + ) + } + } +} +``` + +</tab> +<tab title="Groovy" group-key="groovy"> + +```groovy +import org.jetbrains.dokka.gradle.DokkaTask +import java.net.URL + +// Note: To configure multi-project builds, you need +// to configure Partial tasks of the subprojects. +// See "Configuration example" section of documentation. +tasks.withType(DokkaTask.class) { + // .. + // general configuration section + // .. + + dokkaSourceSets.configureEach { + // .. + // source set configuration section + // .. + + externalDocumentationLink { + url.set(new URL("https://kotlinlang.org/api/kotlinx.serialization/")) + packageListUrl.set( + file("serialization.package.list").toURL() + ) + } + } +} +``` + +</tab> +</tabs> + +<deflist collapsible="true"> + <def title="url"> + <p>The root URL of documentation to link to. It <b>must</b> contain a trailing slash.</p> + <p> + Dokka does its best to automatically find <code>package-list</code> for the given URL, + and link declarations together. + </p> + <p> + If automatic resolution fails or if you want to use locally cached files instead, + consider setting the <code>packageListUrl</code> option. + </p> + </def> + <def title="packageListUrl"> + <p> + The exact location of a <code>package-list</code>. This is an alternative to relying on Dokka + automatically resolving it. + </p> + <p> + Package lists contain information about the documentation and the project itself, + such as module and package names. + </p> + <p>This can also be a locally cached file to avoid network calls.</p> + </def> +</deflist> + +### Complete configuration + +Below you can see all possible configuration options applied at the same time. + +<tabs group="build-script"> +<tab title="Kotlin" group-key="kotlin"> + +```kotlin +import org.jetbrains.dokka.DokkaConfiguration.Visibility +import org.jetbrains.dokka.gradle.DokkaTask +import org.jetbrains.dokka.Platform +import java.net.URL + +// Note: To configure multi-project builds, you need +// to configure Partial tasks of the subprojects. +// See "Configuration example" section of documentation. +tasks.withType<DokkaTask>().configureEach { + moduleName.set(project.name) + moduleVersion.set(project.version.toString()) + outputDirectory.set(buildDir.resolve("dokka/$name")) + failOnWarning.set(false) + suppressObviousFunctions.set(true) + suppressInheritedMembers.set(false) + offlineMode.set(false) + + dokkaSourceSets { + named("linux") { + dependsOn("native") + sourceRoots.from(file("linux/src")) + } + configureEach { + suppress.set(false) + displayName.set(name) + documentedVisibilities.set(setOf(Visibility.PUBLIC)) + reportUndocumented.set(false) + skipEmptyPackages.set(true) + skipDeprecated.set(false) + suppressGeneratedFiles.set(true) + jdkVersion.set(8) + languageVersion.set("1.7") + apiVersion.set("1.7") + noStdlibLink.set(false) + noJdkLink.set(false) + noAndroidSdkLink.set(false) + includes.from(project.files(), "packages.md", "extra.md") + platform.set(Platform.DEFAULT) + sourceRoots.from(file("src")) + classpath.from(project.files(), file("libs/dependency.jar")) + samples.from(project.files(), "samples/Basic.kt", "samples/Advanced.kt") + + sourceLink { + localDirectory.set(projectDir.resolve("src")) + remoteUrl.set(URL("https://github.com/kotlin/dokka/tree/master/src")) + remoteLineSuffix.set("#L") + } + + externalDocumentationLink { + url.set(URL("https://kotlinlang.org/api/latest/jvm/stdlib/")) + packageListUrl.set( + rootProject.projectDir.resolve("stdlib.package.list").toURL() + ) + } + + perPackageOption { + matchingRegex.set(".*api.*") + suppress.set(false) + skipDeprecated.set(false) + reportUndocumented.set(false) + documentedVisibilities.set( + setOf( + Visibility.PUBLIC, + Visibility.PRIVATE, + Visibility.PROTECTED, + Visibility.INTERNAL, + Visibility.PACKAGE + ) + ) + } + } + } +} +``` + +</tab> +<tab title="Groovy" group-key="groovy"> + +```groovy +import org.jetbrains.dokka.DokkaConfiguration.Visibility +import org.jetbrains.dokka.gradle.DokkaTask +import org.jetbrains.dokka.Platform +import java.net.URL + +// Note: To configure multi-project builds, you need +// to configure Partial tasks of the subprojects. +// See "Configuration example" section of documentation. +tasks.withType(DokkaTask.class) { + moduleName.set(project.name) + moduleVersion.set(project.version.toString()) + outputDirectory.set(file("build/dokka/$name")) + failOnWarning.set(false) + suppressObviousFunctions.set(true) + suppressInheritedMembers.set(false) + offlineMode.set(false) + + dokkaSourceSets { + named("linux") { + dependsOn("native") + sourceRoots.from(file("linux/src")) + } + configureEach { + suppress.set(false) + displayName.set(name) + documentedVisibilities.set([Visibility.PUBLIC]) + reportUndocumented.set(false) + skipEmptyPackages.set(true) + skipDeprecated.set(false) + suppressGeneratedFiles.set(true) + jdkVersion.set(8) + languageVersion.set("1.7") + apiVersion.set("1.7") + noStdlibLink.set(false) + noJdkLink.set(false) + noAndroidSdkLink.set(false) + includes.from(project.files(), "packages.md", "extra.md") + platform.set(Platform.DEFAULT) + sourceRoots.from(file("src")) + classpath.from(project.files(), file("libs/dependency.jar")) + samples.from(project.files(), "samples/Basic.kt", "samples/Advanced.kt") + + sourceLink { + localDirectory.set(file("src")) + remoteUrl.set(new URL("https://github.com/kotlin/dokka/tree/master/src")) + remoteLineSuffix.set("#L") + } + + externalDocumentationLink { + url.set(new URL("https://kotlinlang.org/api/latest/jvm/stdlib/")) + packageListUrl.set( + file("stdlib.package.list").toURL() + ) + } + + perPackageOption { + matchingRegex.set(".*api.*") + suppress.set(false) + skipDeprecated.set(false) + reportUndocumented.set(false) + documentedVisibilities.set([Visibility.PUBLIC]) + } + } + } +} +``` + +</tab> +</tabs> diff --git a/docs/topics/runners/dokka-maven.md b/docs/topics/runners/dokka-maven.md new file mode 100644 index 00000000..9bedc517 --- /dev/null +++ b/docs/topics/runners/dokka-maven.md @@ -0,0 +1,646 @@ +[//]: # (title: Maven) + +To generate documentation for a Maven-based project, you can use the Maven plugin for Dokka. + +> Compared to the [Gradle plugin for Dokka](dokka-gradle.md), the Maven plugin has only basic features and +> does not provide support for multi-module builds. +> +{type="note"} + +You can play around with Dokka and see how it can be configured for a Maven project by visiting +our [Maven example](https://github.com/Kotlin/dokka/tree/%dokkaVersion%/examples/maven) project. + +## Apply Dokka + +To apply Dokka, you need to add `dokka-maven-plugin` to the `plugins` section of your POM file: + +```xml +<build> + <plugins> + <plugin> + <groupId>org.jetbrains.dokka</groupId> + <artifactId>dokka-maven-plugin</artifactId> + <version>%dokkaVersion%</version> + <executions> + <execution> + <phase>pre-site</phase> + <goals> + <goal>dokka</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> +</build> +``` + +## Generate documentation + +The following goals are provided by the Maven plugin: + +### Stable + +| **Goal** | **Description** | +|---------------|----------------------------------------------------------------------------------------| +| `dokka:dokka` | Generates documentation with Dokka plugins applied. [HTML](dokka-html.md) format by default. | + +### Experimental + +| **Goal** | **Description** | +|--------------------|---------------------------------------------------------------------------------------------| +| `dokka:javadoc` | Generates documentation in [Javadoc](dokka-javadoc.md) format. | +| `dokka:javadocJar` | Generates a `javadoc.jar` file that contains documentation in [Javadoc](dokka-javadoc.md) format. | + +### Other output formats + +By default, the Maven plugin for Dokka builds documentation in [HTML](dokka-html.md) output format. + +All other output formats are implemented as [Dokka plugins](dokka-plugins.md). In order to generate documentation in the +desired format, you have to add it as a Dokka plugin to the configuration. + +For example, to use the experimental [GFM](dokka-markdown.md#gfm) format, you have to add `gfm-plugin` artifact: + +```xml +<plugin> + <groupId>org.jetbrains.dokka</groupId> + <artifactId>dokka-maven-plugin</artifactId> + ... + <configuration> + <dokkaPlugins> + <plugin> + <groupId>org.jetbrains.dokka</groupId> + <artifactId>gfm-plugin</artifactId> + <version>%dokkaVersion%</version> + </plugin> + </dokkaPlugins> + </configuration> +</plugin> +``` + +With this configuration, running the `dokka:dokka` goal produces documentation in GFM format. + +To learn more about Dokka plugins, see [Dokka plugins](dokka-plugins.md). + +## Build javadoc.jar + +If you want to publish your library to a repository, you may need to provide a `javadoc.jar` file that contains +API reference documentation of your library. + +For example, if you want to publish to [Maven Central](https://central.sonatype.org/), you +[must](https://central.sonatype.org/publish/requirements/) supply a `javadoc.jar` alongside your project. However, +not all repositories have that rule. + +Unlike the [Gradle plugin for Dokka](dokka-gradle.md#build-javadoc-jar), the Maven plugin comes with a ready-to-use `dokka:javadocJar` +goal. By default, it generates documentation in [Javadoc](dokka-javadoc.md) output format in the`target` folder. + +If you are not satisfied with the built-in goal or want to customize the output (for example, you want to generate +documentation in [HTML](dokka-html.md) format instead of Javadoc), similar behavior can be achieved by adding the +Maven JAR plugin with the following configuration: + +```xml +<plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <version>3.3.0</version> + <executions> + <execution> + <goals> + <goal>test-jar</goal> + </goals> + </execution> + <execution> + <id>dokka-jar</id> + <phase>package</phase> + <goals> + <goal>jar</goal> + </goals> + <configuration> + <classifier>dokka</classifier> + <classesDirectory>${project.build.directory}/dokka</classesDirectory> + <skipIfEmpty>true</skipIfEmpty> + </configuration> + </execution> + </executions> +</plugin> +``` + +The documentation and the `.jar` archive for it are then generated by running `dokka:dokka` and `jar:jar@dokka-jar` goals: + +```Bash +mvn dokka:dokka jar:jar@dokka-jar +``` + +> If you publish your library to Maven Central, you can use services like [javadoc.io](https://javadoc.io/) to +> host your library's API documentation for free and without any setup. It takes documentation pages straight +> from the `javadoc.jar`. It works well with the HTML format as demonstrated in +> [this example](https://javadoc.io/doc/com.trib3/server/latest/index.html). +> +{type="tip"} + +## Configuration example + +Maven's plugin configuration block can be used to configure Dokka. + +Here is an example of a basic configuration that only changes the output location of your documentation: + +```xml +<plugin> + <groupId>org.jetbrains.dokka</groupId> + <artifactId>dokka-maven-plugin</artifactId> + ... + <configuration> + <outputDir>${project.basedir}/target/documentation/dokka</outputDir> + </configuration> +</plugin> +``` + +## Configuration options + +Dokka has many configuration options to tailor your and your reader's experience. + +Below are some examples and detailed descriptions for each configuration section. You can also find an example +with [all configuration options](#complete-configuration) applied at the bottom of the page. + +### General configuration + +```xml +<plugin> + <groupId>org.jetbrains.dokka</groupId> + <artifactId>dokka-maven-plugin</artifactId> + <!-- ... --> + <configuration> + <skip>false</skip> + <moduleName>${project.artifactId}</moduleName> + <outputDir>${project.basedir}/target/documentation</outputDir> + <failOnWarning>false</failOnWarning> + <suppressObviousFunctions>true</suppressObviousFunctions> + <suppressInheritedMembers>false</suppressInheritedMembers> + <offlineMode>false</offlineMode> + <sourceDirectories> + <dir>${project.basedir}/src</dir> + </sourceDirectories> + <documentedVisibilities> + <visibility>PUBLIC</visibility> + <visibility>PROTECTED</visibility> + </documentedVisibilities> + <reportUndocumented>false</reportUndocumented> + <skipDeprecated>false</skipDeprecated> + <skipEmptyPackages>true</skipEmptyPackages> + <suppressedFiles> + <file>/path/to/dir</file> + <file>/path/to/file</file> + </suppressedFiles> + <jdkVersion>8</jdkVersion> + <languageVersion>1.7</languageVersion> + <apiVersion>1.7</apiVersion> + <noStdlibLink>false</noStdlibLink> + <noJdkLink>false</noJdkLink> + <includes> + <include>packages.md</include> + <include>extra.md</include> + </includes> + <classpath>${project.compileClasspathElements}</classpath> + <samples> + <dir>${project.basedir}/samples</dir> + </samples> + <sourceLinks> + <!-- Separate section --> + </sourceLinks> + <externalDocumentationLinks> + <!-- Separate section --> + </externalDocumentationLinks> + <perPackageOptions> + <!-- Separate section --> + </perPackageOptions> + </configuration> +</plugin> +``` + +<deflist collapsible="true"> + <def title="skip"> + <p>Whether to skip documentation generation.</p> + <p>Default: <code>false</code></p> + </def> + <def title="moduleName"> + <p>The display name used to refer to the project/module. It's used for the table of contents, navigation, logging, etc.</p> + <p>Default: <code>{project.artifactId}</code></p> + </def> + <def title="outputDir"> + <p>The directory to where documentation is generated, regardless of format.</p> + <p>Default: <code>{project.basedir}/target/dokka</code></p> + </def> + <def title="failOnWarning"> + <p> + Whether to fail documentation generation if Dokka has emitted a warning or an error. The process waits until + all errors and warnings have been emitted first. + </p> + <p>This setting works well with <code>reportUndocumented</code>.</p> + <p>Default: <code>false</code></p> + </def> + <def title="suppressObviousFunctions"> + <p>Whether to suppress obvious functions.</p> + <p> + A function is considered to be obvious if it is: + <list> + <li> + Inherited from <code>kotlin.Any</code>, <code>Kotlin.Enum</code>, <code>java.lang.Object</code> or + <code>java.lang.Enum</code>, such as <code>equals</code>, <code>hashCode</code>, <code>toString</code>. + </li> + <li> + Synthetic (generated by the compiler) and does not have any documentation, such as + <code>dataClass.componentN</code> or <code>dataClass.copy</code>. + </li> + </list> + </p> + <p>Default: <code>true</code></p> + </def> + <def title="suppressInheritedMembers"> + <p>Whether to suppress inherited members that aren't explicitly overridden in a given class.</p> + <p> + Note: This can suppress functions such as <code>equals</code>/<code>hashCode</code>/<code>toString</code>, + but cannot suppress synthetic functions such as <code>dataClass.componentN</code> and + <code>dataClass.copy</code>. Use <code>suppressObviousFunctions</code> for that. + </p> + <p>Default: <code>false</code></p> + </def> + <def title="offlineMode"> + <p>Whether to resolve remote files/links over your network.</p> + <p> + This includes package-lists used for generating external documentation links. + For example, to make classes from the standard library clickable. + </p> + <p> + Setting this to <code>true</code> can significantly speed up build times in certain cases, + but can also worsen documentation quality and user experience. For example, by + not resolving class/member links from your dependencies, including the standard library. + </p> + <p> + Note: You can cache fetched files locally and provide them to + Dokka as local paths. See <code>externalDocumentationLinks</code> section. + </p> + <p>Default: <code>false</code></p> + </def> + <def title="sourceDirectories"> + <p> + The source code roots to be analyzed and documented. + Acceptable inputs are directories and individual <code>.kt</code> / <code>.java</code> files. + </p> + <p>Default: <code>{project.compileSourceRoots}</code></p> + </def> + <def title="documentedVisibilities"> + <p>The set of visibility modifiers that should be documented.</p> + <p> + This can be used if you want to document protected/internal/private declarations, + as well as if you want to exclude public declarations and only document internal API. + </p> + <p>Can be configured on per-package basis.</p> + <p>Default: <code>PUBLIC</code></p> + </def> + <def title="reportUndocumented"> + <p> + Whether to emit warnings about visible undocumented declarations, that is declarations without KDocs + after they have been filtered by <code>documentedVisibilities</code> and other filters. + </p> + <p>This setting works well with <code>failOnWarning</code>.</p> + <p>This can be overridden at package level.</p> + <p>Default: <code>false</code></p> + </def> + <def title="skipDeprecated"> + <p>Whether to document declarations annotated with <code>@Deprecated</code>.</p> + <p>This can be overridden at package level.</p> + <p>Default: <code>false</code></p> + </def> + <def title="skipEmptyPackages"> + <p> + Whether to skip packages that contain no visible declarations after + various filters have been applied. + </p> + <p> + For example, if <code>skipDeprecated</code> is set to <code>true</code> and your package contains only + deprecated declarations, it is considered to be empty. + </p> + <p>Default: <code>true</code></p> + </def> + <def title="suppressedFiles"> + <p> + The directories or individual files that should be suppressed, meaning that declarations from them + are not documented. + </p> + </def> + <def title="jdkVersion"> + <p>The JDK version to use when generating external documentation links for Java types.</p> + <p> + For example, if you use <code>java.util.UUID</code> in some public declaration signature, + and this option is set to <code>8</code>, Dokka generates an external documentation link + to <a href="https://docs.oracle.com/javase/8/docs/api/java/util/UUID.html">JDK 8 Javadocs</a> for it. + </p> + <p>Default: JDK 8</p> + </def> + <def title="languageVersion"> + <p> + <a href="https://kotlinlang.org/docs/compatibility-modes.html">The Kotlin language version</a> + used for setting up analysis and <a href="https://kotlinlang.org/docs/kotlin-doc.html#sample-identifier">@sample</a> + environment. + </p> + <p>By default, the latest language version available to Dokka's embedded compiler is used.</p> + </def> + <def title="apiVersion"> + <p> + <a href="https://kotlinlang.org/docs/compatibility-modes.html">The Kotlin API version</a> + used for setting up analysis and <a href="https://kotlinlang.org/docs/kotlin-doc.html#sample-identifier">@sample</a> + environment. + </p> + <p>By default, it is deduced from <code>languageVersion</code>.</p> + </def> + <def title="noStdlibLink"> + <p> + Whether to generate external documentation links that lead to the API reference + documentation of Kotlin's standard library. + </p> + <p>Note: Links <b>are</b> generated when <code>noStdLibLink</code> is set to <code>false</code>.</p> + <p>Default: <code>false</code></p> + </def> + <def title="noJdkLink"> + <p>Whether to generate external documentation links to JDK's Javadocs.</p> + <p>The version of JDK Javadocs is determined by the <code>jdkVersion</code> option.</p> + <p>Note: Links <b>are</b> generated when <code>noJdkLink</code> is set to <code>false</code>.</p> + <p>Default: <code>false</code></p> + </def> + <def title="includes"> + <p> + A list of Markdown files that contain + <a href="https://kotlinlang.org/docs/reference/kotlin-doc.html#module-and-package-documentation">module and package documentation</a> + </p> + <p>The contents of specified files are parsed and embedded into documentation as module and package descriptions.</p> + </def> + <def title="classpath"> + <p>The classpath for analysis and interactive samples.</p> + <p> + This is useful if some types that come from dependencies are not resolved/picked up automatically. + This option accepts both <code>.jar</code> and <code>.klib</code> files. + </p> + <p>Default: <code>{project.compileClasspathElements}</code></p> + </def> + <def title="samples"> + <p> + A list of directories or files that contain sample functions which are referenced via + <a href="https://kotlinlang.org/docs/kotlin-doc.html#sample-identifier">@sample KDoc tag.</a> + </p> + </def> +</deflist> + +### Source link configuration + +The `sourceLinks` configuration block allows you to add a `source` link to each signature +that leads to the `url` with a specific line number. (The line number is configurable by setting `lineSuffix`). + +This helps readers to find the source code for each declaration. + +For an example, see the documentation for the +[`count()`](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/count.html) +function in `kotlinx.coroutines`. + +```xml +<plugin> + <groupId>org.jetbrains.dokka</groupId> + <artifactId>dokka-maven-plugin</artifactId> + <!-- ... --> + <configuration> + <sourceLinks> + <link> + <path>${project.basedir}/src</path> + <url>https://github.com/kotlin/dokka/tree/master/src</url> + <lineSuffix>#L</lineSuffix> + </link> + </sourceLinks> + </configuration> +</plugin> +``` + +<deflist collapsible="true"> + <def title="path"> + <p> + The path to the local source directory. The path must be relative to the root of the + current module. + </p> + </def> + <def title="url"> + <p> + The URL of the source code hosting service that can be accessed by documentation readers, + like GitHub, GitLab, Bitbucket, etc. This URL is used to generate + source code links of declarations. + </p> + </def> + <def title="lineSuffix"> + <p> + The suffix used to append source code line number to the URL. This helps readers navigate not only + to the file, but to the specific line number of the declaration. + </p> + <p> + The number itself is appended to the specified suffix. For example, if this option is set + to <code>#L</code> and the line number is 10, the resulting URL suffix is <code>#L10</code>. + </p> + <p> + Suffixes used by popular services: + <list> + <li>GitHub: <code>#L</code></li> + <li>GitLab: <code>#L</code></li> + <li>Bitbucket: <code>#lines-</code></li> + </list> + </p> + </def> +</deflist> + +#### External documentation links configuration + +The `externalDocumentationLink` block allows the creation of links that lead to the externally hosted documentation of +your dependencies. + +For example, if you are using types from `kotlinx.serialization`, by default they are unclickable in your +documentation, as if they are unresolved. However, since the API reference documentation for `kotlinx.serialization` +is built by Dokka and is [published on kotlinlang.org](https://kotlinlang.org/api/kotlinx.serialization/), you can +configure external documentation links for it. Thus allowing Dokka to generate links for types from the library, making +them resolve successfully and clickable. + +By default, external documentation links for Kotlin standard library and JDK are configured. + +```xml +<plugin> + <groupId>org.jetbrains.dokka</groupId> + <artifactId>dokka-maven-plugin</artifactId> + <!-- ... --> + <configuration> + <externalDocumentationLinks> + <link> + <url>https://kotlinlang.org/api/kotlinx.serialization/</url> + <packageListUrl>file:/${project.basedir}/serialization.package.list</packageListUrl> + </link> + </externalDocumentationLinks> + </configuration> +</plugin> +``` + +<deflist collapsible="true"> + <def title="url"> + <p>The root URL of documentation to link to. It <b>must</b> contain a trailing slash.</p> + <p> + Dokka does its best to automatically find the <code>package-list</code> for the given URL, + and link declarations together. + </p> + <p> + If automatic resolution fails or if you want to use locally cached files instead, + consider setting the <code>packageListUrl</code> option. + </p> + </def> + <def title="packageListUrl"> + <p> + The exact location of a <code>package-list</code>. This is an alternative to relying on Dokka + automatically resolving it. + </p> + <p> + Package lists contain information about the documentation and the project itself, + such as module and package names. + </p> + <p>This can also be a locally cached file to avoid network calls.</p> + </def> +</deflist> + +### Package options + +The `perPackageOptions` configuration block allows setting some options for specific packages matched by `matchingRegex`. + +```xml +<plugin> + <groupId>org.jetbrains.dokka</groupId> + <artifactId>dokka-maven-plugin</artifactId> + <!-- ... --> + <configuration> + <perPackageOptions> + <packageOptions> + <matchingRegex>.*api.*</matchingRegex> + <suppress>false</suppress> + <reportUndocumented>false</reportUndocumented> + <skipDeprecated>false</skipDeprecated> + <documentedVisibilities> + <visibility>PUBLIC</visibility> + <visibility>PRIVATE</visibility> + <visibility>PROTECTED</visibility> + <visibility>INTERNAL</visibility> + <visibility>PACKAGE</visibility> + </documentedVisibilities> + </packageOptions> + </perPackageOptions> + </configuration> +</plugin> +``` + +<deflist collapsible="true"> + <def title="matchingRegex"> + <p>The regular expression that is used to match the package.</p> + <p>Default: <code>.*</code></p> + </def> + <def title="suppress"> + <p>Whether this package should be skipped when generating documentation.</p> + <p>Default: <code>false</code></p> + </def> + <def title="documentedVisibilities"> + <p>The set of visibility modifiers that should be documented.</p> + <p> + This can be used if you want to document protected/internal/private declarations within this package, + as well as if you want to exclude public declarations and only document internal API. + </p> + <p>Default: <code>PUBLIC</code></p> + </def> + <def title="skipDeprecated"> + <p>Whether to document declarations annotated with <code>@Deprecated</code>.</p> + <p>This can be set on project/module level.</p> + <p>Default: <code>false</code></p> + </def> + <def title="reportUndocumented"> + <p> + Whether to emit warnings about visible undocumented declarations, that is declarations without KDocs + after they have been filtered by <code>documentedVisibilities</code> and other filters. + </p> + <p>This setting works well with <code>failOnWarning</code>.</p> + <p>Default: <code>false</code></p> + </def> +</deflist> + +### Complete configuration + +Below you can see all the possible configuration options applied at the same time. + +```xml +<plugin> + <groupId>org.jetbrains.dokka</groupId> + <artifactId>dokka-maven-plugin</artifactId> + <!-- ... --> + <configuration> + <skip>false</skip> + <moduleName>${project.artifactId}</moduleName> + <outputDir>${project.basedir}/target/documentation</outputDir> + <failOnWarning>false</failOnWarning> + <suppressObviousFunctions>true</suppressObviousFunctions> + <suppressInheritedMembers>false</suppressInheritedMembers> + <offlineMode>false</offlineMode> + <sourceDirectories> + <dir>${project.basedir}/src</dir> + </sourceDirectories> + <documentedVisibilities> + <visibility>PUBLIC</visibility> + <visibility>PRIVATE</visibility> + <visibility>PROTECTED</visibility> + <visibility>INTERNAL</visibility> + <visibility>PACKAGE</visibility> + </documentedVisibilities> + <reportUndocumented>false</reportUndocumented> + <skipDeprecated>false</skipDeprecated> + <skipEmptyPackages>true</skipEmptyPackages> + <suppressedFiles> + <file>/path/to/dir</file> + <file>/path/to/file</file> + </suppressedFiles> + <jdkVersion>8</jdkVersion> + <languageVersion>1.7</languageVersion> + <apiVersion>1.7</apiVersion> + <noStdlibLink>false</noStdlibLink> + <noJdkLink>false</noJdkLink> + <includes> + <include>packages.md</include> + <include>extra.md</include> + </includes> + <classpath>${project.compileClasspathElements}</classpath> + <samples> + <dir>${project.basedir}/samples</dir> + </samples> + <sourceLinks> + <link> + <path>${project.basedir}/src</path> + <url>https://github.com/kotlin/dokka/tree/master/src</url> + <lineSuffix>#L</lineSuffix> + </link> + </sourceLinks> + <externalDocumentationLinks> + <link> + <url>https://kotlinlang.org/api/latest/jvm/stdlib/</url> + <packageListUrl>file:/${project.basedir}/stdlib.package.list</packageListUrl> + </link> + </externalDocumentationLinks> + <perPackageOptions> + <packageOptions> + <matchingRegex>.*api.*</matchingRegex> + <suppress>false</suppress> + <reportUndocumented>false</reportUndocumented> + <skipDeprecated>false</skipDeprecated> + <documentedVisibilities> + <visibility>PUBLIC</visibility> + <visibility>PRIVATE</visibility> + <visibility>PROTECTED</visibility> + <visibility>INTERNAL</visibility> + <visibility>PACKAGE</visibility> + </documentedVisibilities> + </packageOptions> + </perPackageOptions> + </configuration> +</plugin> +``` diff --git a/docs/vars.list b/docs/vars.list new file mode 100644 index 00000000..bd5bcfc5 --- /dev/null +++ b/docs/vars.list @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<vars> + <var name="dokkaVersion" + value="1.7.20" + type="string"/> + <var name="kotlinVersion" + value="1.7.20" + type="string"/> +</vars> diff --git a/examples/maven/pom.xml b/examples/maven/pom.xml index 40525fdb..74675d6d 100644 --- a/examples/maven/pom.xml +++ b/examples/maven/pom.xml @@ -21,7 +21,7 @@ </dependencies> <build> - <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory> + <sourceDirectory>${project.basedir}/src</sourceDirectory> <plugins> <plugin> diff --git a/docs/build.gradle.kts b/mkdocs/build.gradle.kts index 1a93d550..1a93d550 100644 --- a/docs/build.gradle.kts +++ b/mkdocs/build.gradle.kts diff --git a/docs/src/doc/docs/community/plugins-list.md b/mkdocs/src/doc/docs/community/plugins-list.md index 6ae8ce4c..6ae8ce4c 100644 --- a/docs/src/doc/docs/community/plugins-list.md +++ b/mkdocs/src/doc/docs/community/plugins-list.md diff --git a/docs/src/doc/docs/community/slack.md b/mkdocs/src/doc/docs/community/slack.md index 290d4a18..290d4a18 100644 --- a/docs/src/doc/docs/community/slack.md +++ b/mkdocs/src/doc/docs/community/slack.md diff --git a/docs/src/doc/docs/developer_guide/architecture/architecture_overview.md b/mkdocs/src/doc/docs/developer_guide/architecture/architecture_overview.md index fb11f32a..fb11f32a 100644 --- a/docs/src/doc/docs/developer_guide/architecture/architecture_overview.md +++ b/mkdocs/src/doc/docs/developer_guide/architecture/architecture_overview.md diff --git a/docs/src/doc/docs/developer_guide/architecture/data_model/documentables.md b/mkdocs/src/doc/docs/developer_guide/architecture/data_model/documentables.md index 5264553d..5264553d 100644 --- a/docs/src/doc/docs/developer_guide/architecture/data_model/documentables.md +++ b/mkdocs/src/doc/docs/developer_guide/architecture/data_model/documentables.md diff --git a/docs/src/doc/docs/developer_guide/architecture/data_model/extra.md b/mkdocs/src/doc/docs/developer_guide/architecture/data_model/extra.md index 0abbc70e..0abbc70e 100644 --- a/docs/src/doc/docs/developer_guide/architecture/data_model/extra.md +++ b/mkdocs/src/doc/docs/developer_guide/architecture/data_model/extra.md diff --git a/docs/src/doc/docs/developer_guide/architecture/data_model/page_content.md b/mkdocs/src/doc/docs/developer_guide/architecture/data_model/page_content.md index 54ded235..54ded235 100644 --- a/docs/src/doc/docs/developer_guide/architecture/data_model/page_content.md +++ b/mkdocs/src/doc/docs/developer_guide/architecture/data_model/page_content.md diff --git a/docs/src/doc/docs/developer_guide/architecture/extension_points/base_extensions.md b/mkdocs/src/doc/docs/developer_guide/architecture/extension_points/base_extensions.md index 16a52fab..16a52fab 100644 --- a/docs/src/doc/docs/developer_guide/architecture/extension_points/base_extensions.md +++ b/mkdocs/src/doc/docs/developer_guide/architecture/extension_points/base_extensions.md diff --git a/docs/src/doc/docs/developer_guide/architecture/extension_points/core_extensions.md b/mkdocs/src/doc/docs/developer_guide/architecture/extension_points/core_extensions.md index 381a9596..381a9596 100644 --- a/docs/src/doc/docs/developer_guide/architecture/extension_points/core_extensions.md +++ b/mkdocs/src/doc/docs/developer_guide/architecture/extension_points/core_extensions.md diff --git a/docs/src/doc/docs/developer_guide/architecture/extension_points/introduction.md b/mkdocs/src/doc/docs/developer_guide/architecture/extension_points/introduction.md index 877d14e9..877d14e9 100644 --- a/docs/src/doc/docs/developer_guide/architecture/extension_points/introduction.md +++ b/mkdocs/src/doc/docs/developer_guide/architecture/extension_points/introduction.md diff --git a/docs/src/doc/docs/developer_guide/introduction.md b/mkdocs/src/doc/docs/developer_guide/introduction.md index feb601fe..feb601fe 100644 --- a/docs/src/doc/docs/developer_guide/introduction.md +++ b/mkdocs/src/doc/docs/developer_guide/introduction.md diff --git a/docs/src/doc/docs/developer_guide/plugin-development/introduction.md b/mkdocs/src/doc/docs/developer_guide/plugin-development/introduction.md index fbfb32ac..fbfb32ac 100644 --- a/docs/src/doc/docs/developer_guide/plugin-development/introduction.md +++ b/mkdocs/src/doc/docs/developer_guide/plugin-development/introduction.md diff --git a/docs/src/doc/docs/developer_guide/plugin-development/sample-plugin-tutorial.md b/mkdocs/src/doc/docs/developer_guide/plugin-development/sample-plugin-tutorial.md index fdea0207..fdea0207 100644 --- a/docs/src/doc/docs/developer_guide/plugin-development/sample-plugin-tutorial.md +++ b/mkdocs/src/doc/docs/developer_guide/plugin-development/sample-plugin-tutorial.md diff --git a/docs/src/doc/docs/developer_guide/workflow.md b/mkdocs/src/doc/docs/developer_guide/workflow.md index ddf37459..ddf37459 100644 --- a/docs/src/doc/docs/developer_guide/workflow.md +++ b/mkdocs/src/doc/docs/developer_guide/workflow.md diff --git a/docs/src/doc/docs/dokka_colors.css b/mkdocs/src/doc/docs/dokka_colors.css index 69a24359..69a24359 100644 --- a/docs/src/doc/docs/dokka_colors.css +++ b/mkdocs/src/doc/docs/dokka_colors.css diff --git a/docs/src/doc/docs/faq.md b/mkdocs/src/doc/docs/faq.md index ef728ca0..ef728ca0 100644 --- a/docs/src/doc/docs/faq.md +++ b/mkdocs/src/doc/docs/faq.md diff --git a/docs/src/doc/docs/favicon.svg b/mkdocs/src/doc/docs/favicon.svg index 1fea0877..1fea0877 100755 --- a/docs/src/doc/docs/favicon.svg +++ b/mkdocs/src/doc/docs/favicon.svg diff --git a/docs/src/doc/docs/images/mathjax_demo.png b/mkdocs/src/doc/docs/images/mathjax_demo.png Binary files differindex 9b14a704..9b14a704 100644 --- a/docs/src/doc/docs/images/mathjax_demo.png +++ b/mkdocs/src/doc/docs/images/mathjax_demo.png diff --git a/docs/src/doc/docs/images/mermaid_demo.png b/mkdocs/src/doc/docs/images/mermaid_demo.png Binary files differindex 0d0e27b6..0d0e27b6 100644 --- a/docs/src/doc/docs/images/mermaid_demo.png +++ b/mkdocs/src/doc/docs/images/mermaid_demo.png diff --git a/docs/src/doc/docs/index.md b/mkdocs/src/doc/docs/index.md index 0f106c04..0f106c04 100644 --- a/docs/src/doc/docs/index.md +++ b/mkdocs/src/doc/docs/index.md diff --git a/docs/src/doc/docs/survey_banner.js b/mkdocs/src/doc/docs/survey_banner.js index 2feec82e..b4592f1f 100644 --- a/docs/src/doc/docs/survey_banner.js +++ b/mkdocs/src/doc/docs/survey_banner.js @@ -5,4 +5,4 @@ window.addEventListener('load', () => { appended.innerText = "Take part in our Dokka devX survey. It helps us a lot, and gives you a chance to win a prize! -->" document.body.prepend(appended) window.scrollTo(0, 0); -})
\ No newline at end of file +}) diff --git a/docs/src/doc/docs/user_guide/applying/cli.md b/mkdocs/src/doc/docs/user_guide/applying/cli.md index 3b02add2..3b02add2 100644 --- a/docs/src/doc/docs/user_guide/applying/cli.md +++ b/mkdocs/src/doc/docs/user_guide/applying/cli.md diff --git a/docs/src/doc/docs/user_guide/applying/gradle.md b/mkdocs/src/doc/docs/user_guide/applying/gradle.md index 435824f9..435824f9 100644 --- a/docs/src/doc/docs/user_guide/applying/gradle.md +++ b/mkdocs/src/doc/docs/user_guide/applying/gradle.md diff --git a/docs/src/doc/docs/user_guide/applying/maven.md b/mkdocs/src/doc/docs/user_guide/applying/maven.md index cde6e927..cde6e927 100644 --- a/docs/src/doc/docs/user_guide/applying/maven.md +++ b/mkdocs/src/doc/docs/user_guide/applying/maven.md diff --git a/docs/src/doc/docs/user_guide/introduction.md b/mkdocs/src/doc/docs/user_guide/introduction.md index cb263ebe..cb263ebe 100644 --- a/docs/src/doc/docs/user_guide/introduction.md +++ b/mkdocs/src/doc/docs/user_guide/introduction.md diff --git a/docs/src/doc/docs/user_guide/output-formats/html.md b/mkdocs/src/doc/docs/user_guide/output-formats/html.md index 9a80a5d2..9a80a5d2 100644 --- a/docs/src/doc/docs/user_guide/output-formats/html.md +++ b/mkdocs/src/doc/docs/user_guide/output-formats/html.md diff --git a/docs/src/doc/docs/user_guide/plugins/android-plugin.md b/mkdocs/src/doc/docs/user_guide/plugins/android-plugin.md index d52c2e5a..d52c2e5a 100644 --- a/docs/src/doc/docs/user_guide/plugins/android-plugin.md +++ b/mkdocs/src/doc/docs/user_guide/plugins/android-plugin.md diff --git a/docs/src/doc/docs/user_guide/plugins/versioning-plugin.md b/mkdocs/src/doc/docs/user_guide/plugins/versioning-plugin.md index 876ec436..876ec436 100644 --- a/docs/src/doc/docs/user_guide/plugins/versioning-plugin.md +++ b/mkdocs/src/doc/docs/user_guide/plugins/versioning-plugin.md diff --git a/docs/src/doc/mkdocs.yml b/mkdocs/src/doc/mkdocs.yml index 9e101c00..9e101c00 100644 --- a/docs/src/doc/mkdocs.yml +++ b/mkdocs/src/doc/mkdocs.yml diff --git a/plugins/gfm/src/main/kotlin/org/jetbrains/dokka/gfm/GfmPlugin.kt b/plugins/gfm/src/main/kotlin/org/jetbrains/dokka/gfm/GfmPlugin.kt index b3610809..b382a462 100644 --- a/plugins/gfm/src/main/kotlin/org/jetbrains/dokka/gfm/GfmPlugin.kt +++ b/plugins/gfm/src/main/kotlin/org/jetbrains/dokka/gfm/GfmPlugin.kt @@ -43,7 +43,10 @@ class GfmPlugin : DokkaPlugin() { internal val alphaVersionNotifier by extending { CoreExtensions.postActions providing { ctx -> PostAction { - ctx.logger.info("GFM output format is in Alpha version, use at your own risk, expect bugs and migration issues") + ctx.logger.info( + "The GFM output format is still in Alpha so you may find bugs and experience migration " + + "issues when using it. You use it at your own risk." + ) } } } diff --git a/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/JavadocPlugin.kt b/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/JavadocPlugin.kt index 19dfb5c0..358e4ca3 100644 --- a/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/JavadocPlugin.kt +++ b/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/JavadocPlugin.kt @@ -86,7 +86,11 @@ class JavadocPlugin : DokkaPlugin() { internal val alphaVersionNotifier by extending { CoreExtensions.postActions providing { ctx -> PostAction { - ctx.logger.info("Javadoc output format is in Alpha version, use at your own risk, expect bugs and migration issues") + ctx.logger.info( + "The Javadoc output format is still in Alpha so you may find bugs and experience migration " + + "issues when using it. Successful integration with tools that accept Java's Javadoc " + + "HTML as input is not guaranteed. You use it at your own risk." + ) } } } diff --git a/plugins/jekyll/src/main/kotlin/JekyllPlugin.kt b/plugins/jekyll/src/main/kotlin/JekyllPlugin.kt index a6cc6cba..1ae88035 100644 --- a/plugins/jekyll/src/main/kotlin/JekyllPlugin.kt +++ b/plugins/jekyll/src/main/kotlin/JekyllPlugin.kt @@ -52,7 +52,10 @@ class JekyllPlugin : DokkaPlugin() { internal val alphaVersionNotifier by extending { CoreExtensions.postActions providing { ctx -> PostAction { - ctx.logger.info("Jekyll output format is in Alpha version, use at your own risk, expect bugs and migration issues") + ctx.logger.info( + "The Jekyll output format is still in Alpha so you may find bugs and experience migration " + + "issues when using it. You use it at your own risk." + ) } } } diff --git a/runners/cli/api/cli.api b/runners/cli/api/cli.api index cdd051cc..74769272 100644 --- a/runners/cli/api/cli.api +++ b/runners/cli/api/cli.api @@ -62,7 +62,8 @@ public final class org/jetbrains/dokka/ArgTypeVisibility : kotlinx/cli/ArgType { public final class org/jetbrains/dokka/GlobalArguments : org/jetbrains/dokka/DokkaConfiguration { public fun <init> ([Ljava/lang/String;)V - public fun getCacheRoot ()Ljava/io/File; + public synthetic fun getCacheRoot ()Ljava/io/File; + public fun getCacheRoot ()Ljava/lang/Void; public fun getDelayTemplateSubstitution ()Z public fun getFailOnWarning ()Z public fun getFinalizeCoroutines ()Z @@ -88,10 +89,13 @@ public final class org/jetbrains/dokka/GlobalArguments : org/jetbrains/dokka/Dok public fun getSuppressObviousFunctions ()Z } -public final class org/jetbrains/dokka/MainKt { +public final class org/jetbrains/dokka/LinkMapperKt { public static final fun defaultLinks (Lorg/jetbrains/dokka/DokkaConfiguration$DokkaSourceSet;)Ljava/util/List; + public static final fun parseLinks (Ljava/util/List;)Ljava/util/List; +} + +public final class org/jetbrains/dokka/MainKt { public static final fun initializeConfiguration (Lorg/jetbrains/dokka/GlobalArguments;)Lorg/jetbrains/dokka/DokkaConfiguration; public static final fun main ([Ljava/lang/String;)V - public static final fun parseLinks (Ljava/util/List;)Ljava/util/List; } diff --git a/runners/cli/src/main/kotlin/org/jetbrains/dokka/CliArgumentTypes.kt b/runners/cli/src/main/kotlin/org/jetbrains/dokka/CliArgumentTypes.kt new file mode 100644 index 00000000..f52f72fd --- /dev/null +++ b/runners/cli/src/main/kotlin/org/jetbrains/dokka/CliArgumentTypes.kt @@ -0,0 +1,91 @@ +package org.jetbrains.dokka + +import kotlinx.cli.ArgParser +import kotlinx.cli.ArgType +import kotlinx.cli.CLIEntity +import org.jetbrains.dokka.utilities.LoggingLevel +import java.io.File +import java.nio.file.Paths + + +object ArgTypeFile : ArgType<File>(true) { + override fun convert(value: kotlin.String, name: kotlin.String): File = Paths.get(value).toRealPath().toFile() + override val description: kotlin.String + get() = "{ String that represents a directory / file path }" +} + +object ArgTypePlatform : ArgType<Platform>(true) { + override fun convert(value: kotlin.String, name: kotlin.String): Platform = Platform.fromString(value) + override val description: kotlin.String + get() = "{ String that represents a Kotlin platform. Possible values: jvm/js/native/common/android }" +} + +object ArgTypeVisibility : ArgType<DokkaConfiguration.Visibility>(true) { + override fun convert(value: kotlin.String, name: kotlin.String) = DokkaConfiguration.Visibility.fromString(value) + override val description: kotlin.String + get() = "{ String that represents a visibility modifier. Possible values: ${getPossibleVisibilityValues()}" + + private fun getPossibleVisibilityValues(): kotlin.String = + DokkaConfiguration.Visibility.values().joinToString(separator = ", ") +} + +object ArgTypePlugin : ArgType<DokkaConfiguration.PluginConfiguration>(true) { + override fun convert( + value: kotlin.String, + name: kotlin.String + ): DokkaConfiguration.PluginConfiguration { + return value.split("=").let { + PluginConfigurationImpl( + fqPluginName = it[0], + serializationFormat = DokkaConfiguration.SerializationFormat.JSON, + values = it[1] + ) + } + } + + override val description: kotlin.String + get() = "{ String that represents plugin configuration. " + + "Format is {fullyQualifiedPluginName}={jsonConfiguration}. " + + "Quotation marks (`\"`) inside json must be escaped. }" +} + +object ArgTypeSourceLinkDefinition : ArgType<DokkaConfiguration.SourceLinkDefinition>(true) { + override fun convert(value: kotlin.String, name: kotlin.String): DokkaConfiguration.SourceLinkDefinition { + return if (value.isNotEmpty() && value.contains("=")) + SourceLinkDefinitionImpl.parseSourceLinkDefinition(value) + else { + throw IllegalArgumentException( + "Warning: Invalid -srcLink syntax. " + + "Expected: <path>=<url>[#lineSuffix]. No source links will be generated." + ) + } + } + + override val description: kotlin.String + get() = "{ String that represent source links. Format: {srcPath}={remotePath#lineSuffix} }" +} + +data class ArgTypeArgument(val moduleName: CLIEntity<kotlin.String>) : + ArgType<DokkaConfiguration.DokkaSourceSet>(true) { + override fun convert(value: kotlin.String, name: kotlin.String): DokkaConfiguration.DokkaSourceSet = + (if (moduleName.valueOrigin != ArgParser.ValueOrigin.UNSET && moduleName.valueOrigin != ArgParser.ValueOrigin.UNDEFINED) { + moduleName.value + } else { + DokkaDefaults.moduleName + }).let { moduleNameOrDefault -> + parseSourceSet(moduleNameOrDefault, value.split(" ").filter { it.isNotBlank() }.toTypedArray()) + } + + override val description: kotlin.String + get() = "" +} + +// Workaround for printing nested parsers help +data class ArgTypeHelpSourceSet(val moduleName: CLIEntity<kotlin.String>) : ArgType<Any>(false) { + override fun convert(value: kotlin.String, name: kotlin.String): Any = Any().also { + parseSourceSet(moduleName.value, arrayOf("-h")) + } + + override val description: kotlin.String + get() = "" +} diff --git a/runners/cli/src/main/kotlin/org/jetbrains/dokka/GlobalArguments.kt b/runners/cli/src/main/kotlin/org/jetbrains/dokka/GlobalArguments.kt new file mode 100644 index 00000000..2bda8d79 --- /dev/null +++ b/runners/cli/src/main/kotlin/org/jetbrains/dokka/GlobalArguments.kt @@ -0,0 +1,164 @@ +package org.jetbrains.dokka + +import kotlinx.cli.* +import org.jetbrains.dokka.utilities.DokkaConsoleLogger +import org.jetbrains.dokka.utilities.DokkaLogger +import org.jetbrains.dokka.utilities.LoggingLevel +import org.jetbrains.dokka.utilities.cast +import java.io.File + +class GlobalArguments(args: Array<String>) : DokkaConfiguration { + + val parser = ArgParser("dokka-cli", prefixStyle = ArgParser.OptionPrefixStyle.JVM) + + val json: String? by parser.argument(ArgType.String, description = "JSON configuration file path").optional() + + private val _moduleName = parser.option( + ArgType.String, + description = "Name of the project/module", + fullName = "moduleName" + ).default(DokkaDefaults.moduleName) + + override val moduleName: String by _moduleName + + override val moduleVersion by parser.option( + ArgType.String, + description = "Documented version", + fullName = "moduleVersion" + ) + + override val outputDir by parser.option(ArgTypeFile, description = "Output directory path, ./dokka by default") + .default(DokkaDefaults.outputDir) + + override val cacheRoot = null + + override val sourceSets by parser.option( + ArgTypeArgument(_moduleName), + description = "Configuration for a Dokka source set. Contains nested configuration.", + fullName = "sourceSet" + ).multiple() + + override val pluginsConfiguration by parser.option( + ArgTypePlugin, + description = "Configuration for Dokka plugins. Accepts multiple values separated by `^^`." + ).delimiter("^^") + + override val pluginsClasspath by parser.option( + ArgTypeFile, + fullName = "pluginsClasspath", + description = "List of jars with Dokka plugins and their dependencies. Accepts multiple paths separated by semicolons" + ).delimiter(";") + + override val offlineMode by parser.option( + ArgType.Boolean, + description = "Whether to resolve remote files/links over network" + ).default(DokkaDefaults.offlineMode) + + override val failOnWarning by parser.option( + ArgType.Boolean, + description = "Whether to fail documentation generation if Dokka has emitted a warning or an error" + ).default(DokkaDefaults.failOnWarning) + + override val delayTemplateSubstitution by parser.option( + ArgType.Boolean, + description = "Delay substitution of some elements. Used in incremental builds of multimodule projects" + ).default(DokkaDefaults.delayTemplateSubstitution) + + val noSuppressObviousFunctions: Boolean by parser.option( + ArgType.Boolean, + description = "Whether to suppress obvious functions such as inherited from `kotlin.Any` and `java.lang.Object`" + ).default(!DokkaDefaults.suppressObviousFunctions) + + override val suppressObviousFunctions: Boolean by lazy { !noSuppressObviousFunctions } + + private val _includes by parser.option( + ArgTypeFile, + fullName = "includes", + description = "Markdown files that contain module and package documentation. " + + "Accepts multiple values separated by semicolons" + ).delimiter(";") + + override val includes: Set<File> by lazy { _includes.toSet() } + + override val suppressInheritedMembers: Boolean by parser.option( + ArgType.Boolean, + description = "Whether to suppress inherited members that aren't explicitly overridden in a given class" + ).default(DokkaDefaults.suppressInheritedMembers) + + override val finalizeCoroutines: Boolean = true + + val globalPackageOptions by parser.option( + ArgType.String, + description = "Global list of package configurations in format " + + "\"matchingRegexp,-deprecated,-privateApi,+warnUndocumented,+suppress;...\". " + + "Accepts multiple values separated by semicolons. " + ).delimiter(";") + + val globalLinks by parser.option( + ArgType.String, + description = "Global external documentation links in format {url}^{packageListUrl}. " + + "Accepts multiple values separated by `^^`" + ).delimiter("^^") + + val globalSrcLink by parser.option( + ArgType.String, + description = "Global mapping between a source directory and a Web service for browsing the code. " + + "Accepts multiple paths separated by semicolons" + ).delimiter(";") + + val helpSourceSet by parser.option( + ArgTypeHelpSourceSet(_moduleName), + description = "Prints help for nested -sourceSet configuration" + ) + + val loggingLevel by parser.option( + ArgType.Choice(toVariant = { + when (it.toUpperCase().trim()) { + "DEBUG", "" -> LoggingLevel.DEBUG + "PROGRESS" -> LoggingLevel.PROGRESS + "INFO" -> LoggingLevel.INFO + "WARN" -> LoggingLevel.WARN + "ERROR" -> LoggingLevel.ERROR + else -> { + println("""Failed to deserialize logging level, got $it expected one of + |"DEBUG", "PROGRESS", "INFO", "WARN", "ERROR", falling back to DEBUG""".trimMargin()) + LoggingLevel.DEBUG + } + } + }, toString = { it.toString() } + )).default(LoggingLevel.DEBUG) + + override val modules: List<DokkaConfiguration.DokkaModuleDescription> = emptyList() + + val logger: DokkaLogger by lazy { + DokkaConsoleLogger(loggingLevel) + } + + init { + parser.parse(args) + + sourceSets.forEach { + it.perPackageOptions.cast<MutableList<DokkaConfiguration.PackageOptions>>() + .addAll(parsePerPackageOptions(globalPackageOptions)) + } + + sourceSets.forEach { + it.externalDocumentationLinks.cast<MutableSet<DokkaConfiguration.ExternalDocumentationLink>>().addAll(parseLinks(globalLinks)) + } + + globalSrcLink.forEach { + if (it.isNotEmpty() && it.contains("=")) + sourceSets.all { sourceSet -> + sourceSet.sourceLinks.cast<MutableSet<SourceLinkDefinitionImpl>>() + .add(SourceLinkDefinitionImpl.parseSourceLinkDefinition(it)) + } + else { + logger.warn("Invalid -srcLink syntax. Expected: <path>=<url>[#lineSuffix]. No source links will be generated.") + } + } + + sourceSets.forEach { + it.externalDocumentationLinks.cast<MutableSet<DokkaConfiguration.ExternalDocumentationLink>>().addAll(defaultLinks(it)) + } + } +} diff --git a/runners/cli/src/main/kotlin/org/jetbrains/dokka/LinkMapper.kt b/runners/cli/src/main/kotlin/org/jetbrains/dokka/LinkMapper.kt new file mode 100644 index 00000000..191d5067 --- /dev/null +++ b/runners/cli/src/main/kotlin/org/jetbrains/dokka/LinkMapper.kt @@ -0,0 +1,37 @@ +package org.jetbrains.dokka + +import java.io.File +import java.net.MalformedURLException +import java.net.URL + +@OptIn(ExperimentalStdlibApi::class) // for buildList +fun defaultLinks(config: DokkaConfiguration.DokkaSourceSet): MutableList<DokkaConfiguration.ExternalDocumentationLink> = + buildList<DokkaConfiguration.ExternalDocumentationLink> { + if (!config.noJdkLink) { + add(DokkaConfiguration.ExternalDocumentationLink.jdk(config.jdkVersion)) + } + + if (!config.noStdlibLink) { + add(DokkaConfiguration.ExternalDocumentationLink.kotlinStdlib()) + } + }.toMutableList() + + +fun parseLinks(links: List<String>): List<DokkaConfiguration.ExternalDocumentationLink> { + val (parsedLinks, parsedOfflineLinks) = links + .map { it.split("^").map { it.trim() }.filter { it.isNotBlank() } } + .filter { it.isNotEmpty() } + .partition { it.size == 1 } + + return parsedLinks.map { (root) -> ExternalDocumentationLink(root) } + + parsedOfflineLinks.map { (root, packageList) -> + val rootUrl = URL(root) + val packageListUrl = + try { + URL(packageList) + } catch (ex: MalformedURLException) { + File(packageList).toURI().toURL() + } + ExternalDocumentationLink(rootUrl, packageListUrl) + } +} diff --git a/runners/cli/src/main/kotlin/org/jetbrains/dokka/PackageOptionsParser.kt b/runners/cli/src/main/kotlin/org/jetbrains/dokka/PackageOptionsParser.kt new file mode 100644 index 00000000..1b9a3c56 --- /dev/null +++ b/runners/cli/src/main/kotlin/org/jetbrains/dokka/PackageOptionsParser.kt @@ -0,0 +1,34 @@ +package org.jetbrains.dokka + +internal fun parsePerPackageOptions(args: List<String>): List<DokkaConfiguration.PackageOptions> = args.map { it.split(",") }.map { + val matchingRegex = it.first() + + val options = it.subList(1, it.size) + + val deprecated = options.find { it.endsWith("skipDeprecated") }?.startsWith("+") + ?: DokkaDefaults.skipDeprecated + + val reportUndocumented = options.find { it.endsWith("reportUndocumented") }?.startsWith("+") + ?: DokkaDefaults.reportUndocumented + + val privateApi = options.find { it.endsWith("includeNonPublic") }?.startsWith("+") + ?: DokkaDefaults.includeNonPublic + + val suppress = options.find { it.endsWith("suppress") }?.startsWith("+") + ?: DokkaDefaults.suppress + + val documentedVisibilities = options + .filter { it.matches(Regex("\\+visibility:.+")) } // matches '+visibility:' with at least one symbol after the semicolon + .map { DokkaConfiguration.Visibility.fromString(it.split(":")[1]) } + .toSet() + .ifEmpty { DokkaDefaults.documentedVisibilities } + + PackageOptionsImpl( + matchingRegex, + includeNonPublic = privateApi, + documentedVisibilities = documentedVisibilities, + reportUndocumented = reportUndocumented, + skipDeprecated = !deprecated, + suppress = suppress + ) +} diff --git a/runners/cli/src/main/kotlin/org/jetbrains/dokka/SourceSetArgumentsParser.kt b/runners/cli/src/main/kotlin/org/jetbrains/dokka/SourceSetArgumentsParser.kt new file mode 100644 index 00000000..49e8f2ae --- /dev/null +++ b/runners/cli/src/main/kotlin/org/jetbrains/dokka/SourceSetArgumentsParser.kt @@ -0,0 +1,155 @@ +package org.jetbrains.dokka + +import kotlinx.cli.ArgParser +import kotlinx.cli.ArgType +import kotlinx.cli.default +import kotlinx.cli.delimiter + +internal fun parseSourceSet(moduleName: String, args: Array<String>): DokkaConfiguration.DokkaSourceSet { + + val parser = ArgParser("sourceSet", prefixStyle = ArgParser.OptionPrefixStyle.JVM) + + val sourceSetName by parser.option( + ArgType.String, + description = "Name of the source set" + ).default("main") + + val displayName by parser.option( + ArgType.String, + description = "Display name of the source set, used both internally and externally" + ).default(DokkaDefaults.sourceSetDisplayName) + + val classpath by parser.option( + ArgTypeFile, + description = "Classpath for analysis and interactive samples. Accepts multiple paths separated by semicolons" + ).delimiter(";") + + val sourceRoots by parser.option( + ArgTypeFile, + description = "Source code roots to be analyzed and documented. Accepts multiple paths separated by semicolons", + fullName = "src" + ).delimiter(";") + + val dependentSourceSets by parser.option( + ArgType.String, + description = "Names of dependent source sets in format \"moduleName/sourceSetName\". " + + "Accepts multiple paths separated by semicolons" + ).delimiter(";") + + val samples by parser.option( + ArgTypeFile, + description = "List of directories or files that contain sample functions. " + + "Accepts multiple paths separated by semicolons" + ).delimiter(";") + + val includes by parser.option( + ArgTypeFile, + description = "Markdown files that contain module and package documentation. " + + "Accepts multiple paths separated by semicolons" + ).delimiter(";") + + val includeNonPublic: Boolean by parser.option( + ArgType.Boolean, + description = "Deprecated, use documentedVisibilities") + .default(DokkaDefaults.includeNonPublic) + + val documentedVisibilities by parser.option( + ArgTypeVisibility, + description = "Visibilities to be documented. Accepts multiple values separated by semicolons" + ).delimiter(";") + + val reportUndocumented by parser.option(ArgType.Boolean, description = "Whether to report undocumented declarations") + .default(DokkaDefaults.reportUndocumented) + + val noSkipEmptyPackages by parser.option( + ArgType.Boolean, + description = "Whether to create pages for empty packages" + ).default(!DokkaDefaults.skipEmptyPackages) + + val skipEmptyPackages by lazy { !noSkipEmptyPackages } + + val skipDeprecated by parser.option(ArgType.Boolean, description = "Whether to skip deprecated declarations") + .default(DokkaDefaults.skipDeprecated) + + val jdkVersion by parser.option( + ArgType.Int, + description = "Version of JDK to use for linking to JDK Javadocs" + ).default(DokkaDefaults.jdkVersion) + + val languageVersion by parser.option( + ArgType.String, + description = "Language version used for setting up analysis and samples" + ) + + val apiVersion by parser.option( + ArgType.String, + description = "Kotlin API version used for setting up analysis and samples" + ) + + val noStdlibLink by parser.option(ArgType.Boolean, description = "Whether to generate links to Standard library") + .default(DokkaDefaults.noStdlibLink) + + val noJdkLink by parser.option(ArgType.Boolean, description = "Whether to generate links to JDK Javadocs") + .default(DokkaDefaults.noJdkLink) + + val suppressedFiles by parser.option( + ArgTypeFile, + description = "Paths to files to be suppressed. Accepts multiple paths separated by semicolons." + ).delimiter(";") + + val analysisPlatform: Platform by parser.option( + ArgTypePlatform, + description = "Platform used for setting up analysis" + ).default(DokkaDefaults.analysisPlatform) + + val perPackageOptions by parser.option( + ArgType.String, + description = "List of package source set configuration in format " + + "\"matchingRegexp,-deprecated,-privateApi,+warnUndocumented,+suppress;...\". " + + "Accepts multiple values separated by semicolons. " + ).delimiter(";") + + val externalDocumentationLinks by parser.option( + ArgType.String, + description = "External documentation links in format {url}^{packageListUrl}. " + + "Accepts multiple values separated by `^^`" + ).delimiter("^^") + + val sourceLinks by parser.option( + ArgTypeSourceLinkDefinition, + description = "Mapping between a source directory and a Web service for browsing the code. " + + "Accepts multiple paths separated by semicolons", + fullName = "srcLink" + ).delimiter(";") + + parser.parse(args) + + return object : DokkaConfiguration.DokkaSourceSet { + override val displayName = displayName + override val sourceSetID = DokkaSourceSetID(moduleName, sourceSetName) + override val classpath = classpath.toMutableList() + override val sourceRoots = sourceRoots.toMutableSet() + override val dependentSourceSets = dependentSourceSets + .map { dependentSourceSetName -> dependentSourceSetName.split('/').let { DokkaSourceSetID(it[0], it[1]) } } + .toMutableSet() + override val samples = samples.toMutableSet() + override val includes = includes.toMutableSet() + @Deprecated("Use [documentedVisibilities] property for a more flexible control over documented visibilities") + override val includeNonPublic = includeNonPublic + override val reportUndocumented = reportUndocumented + override val skipEmptyPackages = skipEmptyPackages + override val skipDeprecated = skipDeprecated + override val jdkVersion = jdkVersion + override val sourceLinks = sourceLinks.toMutableSet() + override val analysisPlatform = analysisPlatform + override val perPackageOptions = parsePerPackageOptions(perPackageOptions).toMutableList() + override val externalDocumentationLinks = parseLinks(externalDocumentationLinks).toMutableSet() + override val languageVersion = languageVersion + override val apiVersion = apiVersion + override val noStdlibLink = noStdlibLink + override val noJdkLink = noJdkLink + override val suppressedFiles = suppressedFiles.toMutableSet() + override val documentedVisibilities: Set<DokkaConfiguration.Visibility> = documentedVisibilities.toSet() + .ifEmpty { DokkaDefaults.documentedVisibilities } + } +} diff --git a/runners/cli/src/main/kotlin/org/jetbrains/dokka/main.kt b/runners/cli/src/main/kotlin/org/jetbrains/dokka/main.kt index 7fe782a9..99813f62 100644 --- a/runners/cli/src/main/kotlin/org/jetbrains/dokka/main.kt +++ b/runners/cli/src/main/kotlin/org/jetbrains/dokka/main.kt @@ -1,429 +1,28 @@ package org.jetbrains.dokka -import kotlinx.cli.* import org.jetbrains.dokka.DokkaConfiguration.ExternalDocumentationLink import org.jetbrains.dokka.utilities.* -import java.io.* -import java.net.MalformedURLException -import java.net.URL import java.nio.file.Paths -class GlobalArguments(args: Array<String>) : DokkaConfiguration { - - val parser = ArgParser("globalArguments", prefixStyle = ArgParser.OptionPrefixStyle.JVM) - - val json: String? by parser.argument(ArgType.String, description = "Json file name").optional() - - private val _moduleName = parser.option( - ArgType.String, - description = "Name of the documentation module", - fullName = "moduleName" - ).default(DokkaDefaults.moduleName) - - override val moduleName: String by _moduleName - - override val moduleVersion by parser.option( - ArgType.String, - description = "Documentation version", - fullName = "moduleVersion" - ) - - override val outputDir by parser.option(ArgTypeFile, description = "Output directory path") - .default(DokkaDefaults.outputDir) - - override val cacheRoot by parser.option( - ArgTypeFile, - description = "Path to cache folder, or 'default' to use ~/.cache/dokka, if not provided caching is disabled" - ) - - override val sourceSets by parser.option( - ArgTypeArgument(_moduleName), - description = "Single dokka source set", - fullName = "sourceSet" - ).multiple() - - override val pluginsConfiguration by parser.option( - ArgTypePlugin, - description = "Configuration for plugins in format fqPluginName=json^^fqPluginName=json..." - ).delimiter("^^") - - override val pluginsClasspath by parser.option( - ArgTypeFile, - fullName = "pluginsClasspath", - description = "List of jars with dokka plugins (allows many paths separated by the semicolon `;`)" - ).delimiter(";") - - override val offlineMode by parser.option( - ArgType.Boolean, - description = "Offline mode (do not download package lists from the Internet)" - ).default(DokkaDefaults.offlineMode) - - override val failOnWarning by parser.option( - ArgType.Boolean, - description = "Throw an exception if the generation exited with warnings" - ).default(DokkaDefaults.failOnWarning) - - override val delayTemplateSubstitution by parser.option( - ArgType.Boolean, - description = "Delay substitution of some elements (usefull for incremental builds of multimodule projects)" - ).default(DokkaDefaults.delayTemplateSubstitution) - - val noSuppressObviousFunctions: Boolean by parser.option( - ArgType.Boolean, - description = "Document generated or obvious functions like default `toString` or `equals`" - ).default(!DokkaDefaults.suppressObviousFunctions) - - override val suppressObviousFunctions: Boolean by lazy { !noSuppressObviousFunctions } - - private val _includes by parser.option( - ArgTypeFile, - fullName = "includes", - description = "Markdown files that would be displayed in multi-module page separated by the semicolon `;`)" - ).delimiter(";") - - override val includes: Set<File> by lazy { _includes.toSet() } - - override val suppressInheritedMembers: Boolean by parser.option( - ArgType.Boolean, - description = "Suppress members inherited from other classes" - ).default(DokkaDefaults.suppressInheritedMembers) - - override val finalizeCoroutines: Boolean = true - - val globalPackageOptions by parser.option( - ArgType.String, - description = "List of package source sets in format \"prefix,-deprecated,-privateApi,+warnUndocumented,+suppress;...\" " - ).delimiter(";") - - val globalLinks by parser.option( - ArgType.String, - description = "External documentation links in format url^packageListUrl^^url2..." - ).delimiter("^^") - - val globalSrcLink by parser.option( - ArgType.String, - description = "Mapping between a source directory and a Web site for browsing the code (allows many paths separated by the semicolon `;`)" - ).delimiter(";") - - val helpSourceSet by parser.option( - ArgTypeHelpSourceSet(_moduleName), - description = "Prints help for single -sourceSet" - ) - - val loggingLevel by parser.option( - ArgType.Choice(toVariant = { - when (it.toUpperCase().trim()) { - "DEBUG", "" -> LoggingLevel.DEBUG - "PROGRESS" -> LoggingLevel.PROGRESS - "INFO" -> LoggingLevel.INFO - "WARN" -> LoggingLevel.WARN - "ERROR" -> LoggingLevel.ERROR - else -> { - println("""Failed to deserialize logging level, got $it expected one of "DEBUG", "PROGRESS", "INFO", "WARN", "ERROR", falling back to DEBUG""") - LoggingLevel.DEBUG - } - } - }, toString = { it.toString() } - )).default(LoggingLevel.DEBUG) - - override val modules: List<DokkaConfiguration.DokkaModuleDescription> = emptyList() - - val logger: DokkaLogger by lazy { - DokkaConsoleLogger(loggingLevel) - } - - init { - parser.parse(args) - - sourceSets.forEach { - it.perPackageOptions.cast<MutableList<DokkaConfiguration.PackageOptions>>() - .addAll(parsePerPackageOptions(globalPackageOptions)) - } - - sourceSets.forEach { - it.externalDocumentationLinks.cast<MutableSet<ExternalDocumentationLink>>().addAll(parseLinks(globalLinks)) - } - - globalSrcLink.forEach { - if (it.isNotEmpty() && it.contains("=")) - sourceSets.all { sourceSet -> - sourceSet.sourceLinks.cast<MutableSet<SourceLinkDefinitionImpl>>() - .add(SourceLinkDefinitionImpl.parseSourceLinkDefinition(it)) - } - else { - logger.warn("Invalid -srcLink syntax. Expected: <path>=<url>[#lineSuffix]. No source links will be generated.") - } - } - - sourceSets.forEach { - it.externalDocumentationLinks.cast<MutableSet<ExternalDocumentationLink>>().addAll(defaultLinks(it)) - } - } -} - -private fun parseSourceSet(moduleName: String, args: Array<String>): DokkaConfiguration.DokkaSourceSet { - - val parser = ArgParser("sourceSet", prefixStyle = ArgParser.OptionPrefixStyle.JVM) - - val sourceSetName by parser.option( - ArgType.String, - description = "Name of the source set" - ).default("main") - - val displayName by parser.option( - ArgType.String, - description = "Displayed name of the source set" - ).default(DokkaDefaults.sourceSetDisplayName) - - val classpath by parser.option( - ArgTypeFile, - description = "Classpath for symbol resolution (allows many paths separated by the semicolon `;`)" - ).delimiter(";") - - val sourceRoots by parser.option( - ArgTypeFile, - description = "Source file or directory (allows many paths separated by the semicolon `;`)", - fullName = "src" - ).delimiter(";") - - val dependentSourceSets by parser.option( - ArgType.String, - description = "Names of dependent source sets in format \"moduleName/sourceSetName\" (allows many paths separated by the semicolon `;`)" - ).delimiter(";") - - val samples by parser.option( - ArgTypeFile, - description = "Source root for samples (allows many paths separated by the semicolon `;`)" - ).delimiter(";") - - val includes by parser.option( - ArgTypeFile, - description = "Markdown files to load (allows many paths separated by the semicolon `;`)" - ).delimiter(";") - - val includeNonPublic: Boolean by parser.option(ArgType.Boolean, description = "Include non public") - .default(DokkaDefaults.includeNonPublic) - - val documentedVisibilities by parser.option( - ArgTypeVisibility, - description = "Visibilities to be documented (allows multiple values separated by the semicolon `;`)" - ).delimiter(";") - - val reportUndocumented by parser.option(ArgType.Boolean, description = "Report undocumented members") - .default(DokkaDefaults.reportUndocumented) - - val noSkipEmptyPackages by parser.option( - ArgType.Boolean, - description = "Create index pages for empty packages" - ).default(!DokkaDefaults.skipEmptyPackages) - - val skipEmptyPackages by lazy { !noSkipEmptyPackages } - - val skipDeprecated by parser.option(ArgType.Boolean, description = "Do not output deprecated members") - .default(DokkaDefaults.skipDeprecated) - - val jdkVersion by parser.option( - ArgType.Int, - description = "Version of JDK to use for linking to JDK JavaDoc" - ).default(DokkaDefaults.jdkVersion) - - val languageVersion by parser.option( - ArgType.String, - description = "Language Version to pass to Kotlin analysis" - ) - - val apiVersion by parser.option( - ArgType.String, - description = "Kotlin Api Version to pass to Kotlin analysis" - ) - - val noStdlibLink by parser.option(ArgType.Boolean, description = "Disable documentation link to stdlib") - .default(DokkaDefaults.noStdlibLink) - - val noJdkLink by parser.option(ArgType.Boolean, description = "Disable documentation link to JDK") - .default(DokkaDefaults.noJdkLink) - - val suppressedFiles by parser.option( - ArgTypeFile, - description = "Paths to files to be suppressed (allows many paths separated by the semicolon `;`)" - ).delimiter(";") - - val analysisPlatform: Platform by parser.option( - ArgTypePlatform, - description = "Platform for analysis" - ).default(DokkaDefaults.analysisPlatform) - - val perPackageOptions by parser.option( - ArgType.String, - description = "List of package source set configuration in format \"prefix,-deprecated,-privateApi,+warnUndocumented,+suppress;...\" " - ).delimiter(";") - - val externalDocumentationLinks by parser.option( - ArgType.String, - description = "External documentation links in format url^packageListUrl^^url2..." - ).delimiter("^^") - - val sourceLinks by parser.option( - ArgTypeSourceLinkDefinition, - description = "Mapping between a source directory and a Web site for browsing the code (allows many paths separated by the semicolon `;`)", - fullName = "srcLink" - ).delimiter(";") - - parser.parse(args) - - return object : DokkaConfiguration.DokkaSourceSet { - override val displayName = displayName - override val sourceSetID = DokkaSourceSetID(moduleName, sourceSetName) - override val classpath = classpath.toMutableList() - override val sourceRoots = sourceRoots.toMutableSet() - override val dependentSourceSets = dependentSourceSets - .map { dependentSourceSetName -> dependentSourceSetName.split('/').let { DokkaSourceSetID(it[0], it[1]) } } - .toMutableSet() - override val samples = samples.toMutableSet() - override val includes = includes.toMutableSet() - @Deprecated("Use [documentedVisibilities] property for a more flexible control over documented visibilities") - override val includeNonPublic = includeNonPublic - override val reportUndocumented = reportUndocumented - override val skipEmptyPackages = skipEmptyPackages - override val skipDeprecated = skipDeprecated - override val jdkVersion = jdkVersion - override val sourceLinks = sourceLinks.toMutableSet() - override val analysisPlatform = analysisPlatform - override val perPackageOptions = parsePerPackageOptions(perPackageOptions).toMutableList() - override val externalDocumentationLinks = parseLinks(externalDocumentationLinks).toMutableSet() - override val languageVersion = languageVersion - override val apiVersion = apiVersion - override val noStdlibLink = noStdlibLink - override val noJdkLink = noJdkLink - override val suppressedFiles = suppressedFiles.toMutableSet() - override val documentedVisibilities: Set<DokkaConfiguration.Visibility> = documentedVisibilities.toSet() - .ifEmpty { DokkaDefaults.documentedVisibilities } - } -} - -object ArgTypeFile : ArgType<File>(true) { - override fun convert(value: kotlin.String, name: kotlin.String): File = Paths.get(value).toRealPath().toFile() - override val description: kotlin.String - get() = "{ String that points to file path }" -} - -object ArgTypePlatform : ArgType<Platform>(true) { - override fun convert(value: kotlin.String, name: kotlin.String): Platform = Platform.fromString(value) - override val description: kotlin.String - get() = "{ String that represents platform }" -} - -object ArgTypeVisibility : ArgType<DokkaConfiguration.Visibility>(true) { - override fun convert(value: kotlin.String, name: kotlin.String) = DokkaConfiguration.Visibility.fromString(value) - override val description: kotlin.String - get() = "{ String that represents a visibility modifier. " + - "Possible values: ${DokkaConfiguration.Visibility.values().joinToString(separator = ", ")} }" -} - -object ArgTypePlugin : ArgType<DokkaConfiguration.PluginConfiguration>(true) { - override fun convert( - value: kotlin.String, - name: kotlin.String - ): DokkaConfiguration.PluginConfiguration { - return value.split("=").let { - PluginConfigurationImpl( - fqPluginName = it[0], - serializationFormat = DokkaConfiguration.SerializationFormat.JSON, - values = it[1] - ) - } - } - - override val description: kotlin.String - get() = "{ String fqName=json, remember to escape `\"` inside json }" -} - -object ArgTypeSourceLinkDefinition : ArgType<DokkaConfiguration.SourceLinkDefinition>(true) { - override fun convert(value: kotlin.String, name: kotlin.String): DokkaConfiguration.SourceLinkDefinition = - if (value.isNotEmpty() && value.contains("=")) - SourceLinkDefinitionImpl.parseSourceLinkDefinition(value) - else { - throw IllegalArgumentException("Warning: Invalid -srcLink syntax. Expected: <path>=<url>[#lineSuffix]. No source links will be generated.") - } - - override val description: kotlin.String - get() = "{ String that represent source links }" -} - -data class ArgTypeArgument(val moduleName: CLIEntity<kotlin.String>) : - ArgType<DokkaConfiguration.DokkaSourceSet>(true) { - override fun convert(value: kotlin.String, name: kotlin.String): DokkaConfiguration.DokkaSourceSet = - (if (moduleName.valueOrigin != ArgParser.ValueOrigin.UNSET && moduleName.valueOrigin != ArgParser.ValueOrigin.UNDEFINED) { - moduleName.value - } else { - DokkaDefaults.moduleName - }).let { moduleNameOrDefault -> - parseSourceSet(moduleNameOrDefault, value.split(" ").filter { it.isNotBlank() }.toTypedArray()) - } - - override val description: kotlin.String - get() = "" -} - -// Workaround for printing nested parsers help -data class ArgTypeHelpSourceSet(val moduleName: CLIEntity<kotlin.String>) : ArgType<Any>(false) { - override fun convert(value: kotlin.String, name: kotlin.String): Any = Any().also { - parseSourceSet(moduleName.value, arrayOf("-h")) - } - - override val description: kotlin.String - get() = "" +fun main(args: Array<String>) { + val globalArguments = GlobalArguments(args) + val configuration = initializeConfiguration(globalArguments) + DokkaGenerator(configuration, globalArguments.logger).generate() } -@OptIn(ExperimentalStdlibApi::class) -fun defaultLinks(config: DokkaConfiguration.DokkaSourceSet): MutableList<ExternalDocumentationLink> = - buildList<ExternalDocumentationLink> { - if (!config.noJdkLink) { - add(ExternalDocumentationLink.jdk(config.jdkVersion)) - } +fun initializeConfiguration(globalArguments: GlobalArguments): DokkaConfiguration { + return if (globalArguments.json != null) { + val jsonContent = Paths.get(checkNotNull(globalArguments.json)).toFile().readText() + val globals = GlobalDokkaConfiguration(jsonContent) + val dokkaConfigurationImpl = DokkaConfigurationImpl(jsonContent) - if (!config.noStdlibLink) { - add(ExternalDocumentationLink.kotlinStdlib()) - } - }.toMutableList() - - -fun parseLinks(links: List<String>): List<ExternalDocumentationLink> { - val (parsedLinks, parsedOfflineLinks) = links - .map { it.split("^").map { it.trim() }.filter { it.isNotBlank() } } - .filter { it.isNotEmpty() } - .partition { it.size == 1 } - - return parsedLinks.map { (root) -> ExternalDocumentationLink(root) } + - parsedOfflineLinks.map { (root, packageList) -> - val rootUrl = URL(root) - val packageListUrl = - try { - URL(packageList) - } catch (ex: MalformedURLException) { - File(packageList).toURI().toURL() - } - ExternalDocumentationLink(rootUrl, packageListUrl) + dokkaConfigurationImpl.apply(globals).apply { + sourceSets.forEach { + it.externalDocumentationLinks.cast<MutableSet<ExternalDocumentationLink>>().addAll(defaultLinks(it)) } -} - -fun initializeConfiguration(globalArguments: GlobalArguments): DokkaConfiguration = if (globalArguments.json != null) { - val jsonContent = Paths.get(checkNotNull(globalArguments.json)).toFile().readText() - val globals = GlobalDokkaConfiguration(jsonContent) - val dokkaConfigurationImpl = DokkaConfigurationImpl(jsonContent) - - dokkaConfigurationImpl.apply(globals).apply { - sourceSets.forEach { - it.externalDocumentationLinks.cast<MutableSet<ExternalDocumentationLink>>().addAll(defaultLinks(it)) } + } else { + globalArguments } -} else { - globalArguments -} - -fun main(args: Array<String>) { - val globalArguments = GlobalArguments(args) - val configuration = initializeConfiguration(globalArguments) - DokkaGenerator(configuration, globalArguments.logger).generate() } diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaTask.kt index 2c761eef..0fb62b30 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaTask.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaTask.kt @@ -23,48 +23,160 @@ import kotlin.reflect.full.createInstance @DisableCachingByDefault(because = "Abstract super-class, not to be instantiated directly") abstract class AbstractDokkaTask : DefaultTask() { + /** + * Display name used to refer to the module. Used for ToC, navigation, logging, etc. + * + * If set for a single-project build or a MultiModule task, will be used as project name. + * + * Default is Gradle project name. + */ @Input val moduleName: Property<String> = project.objects.safeProperty<String>() .safeConvention(project.name) + /** + * Module version. + * + * If set for a single-project build or a MultiModule task, will be used + * as project version by the versioning plugin. + * + * Default is Gradle project version. + */ @Input val moduleVersion: Property<String> = project.objects.safeProperty<String>() .safeConvention(project.version.toString()) + /** + * Directory to which documentation will be generated, regardless of format. + * Can be set on per-task basis. + * + * Default is `project/buildDir/taskName.removePrefix("dokka").decapitalize()`, so + * for `dokkaHtmlMultiModule` task it will be `project/buildDir/htmlMultiModule` + */ @OutputDirectory val outputDirectory: Property<File> = project.objects.safeProperty<File>() .safeConvention(project.provider { defaultDokkaOutputDirectory() }) - @Optional - @InputDirectory - @PathSensitive(PathSensitivity.RELATIVE) - val cacheRoot: Property<File?> = project.objects.safeProperty() + /** + * Configuration for Dokka plugins. This property is not expected to be used directly - if possible, use + * [pluginConfiguration] blocks (preferred) or [pluginsMapConfiguration] instead. + */ + @Input + val pluginsConfiguration: ListProperty<in DokkaConfiguration.PluginConfiguration> = project.objects.listProperty() + /** + * JSON configuration of Dokka plugins. + * + * Key is fully qualified Dokka plugin name, value is its configuration in JSON. + * + * Example: + * + * ```kotlin + * tasks.dokkaHtml { + * val dokkaBaseConfiguration = """ + * { + * "customAssets": ["${file("assets/my-image.png")}"], + * "customStyleSheets": ["${file("assets/my-styles.css")}"], + * "footerMessage": "(c) 2022 MyOrg" + * } + * """ + * pluginsMapConfiguration.set( + * mapOf("org.jetbrains.dokka.base.DokkaBase" to dokkaBaseConfiguration) + * ) + * } + * ``` + */ @Input - val failOnWarning: Property<Boolean> = project.objects.safeProperty<Boolean>() - .safeConvention(DokkaDefaults.failOnWarning) + val pluginsMapConfiguration: MapProperty<String, String> = project.objects.mapProperty() + /** + * Whether to suppress obvious functions. + * + * A function is considered to be obvious if it is: + * - Inherited from `kotlin.Any`, `Kotlin.Enum`, `java.lang.Object` or `java.lang.Enum`, + * such as `equals`, `hashCode`, `toString`. + * - Synthetic (generated by the compiler) and does not have any documentation, such as + * `dataClass.componentN` or `dataClass.copy`. + * + * Default is `true` + */ @Input val suppressObviousFunctions: Property<Boolean> = project.objects.safeProperty<Boolean>() .safeConvention(DokkaDefaults.suppressObviousFunctions) + /** + * Whether to suppress inherited members that aren't explicitly overridden in a given class. + * + * Note: this can suppress functions such as `equals`/`hashCode`/`toString`, but cannot suppress + * synthetic functions such as `dataClass.componentN` and `dataClass.copy`. Use [suppressObviousFunctions] + * for that. + * + * Default is `false`. + */ @Input val suppressInheritedMembers: Property<Boolean> = project.objects.safeProperty<Boolean>() .safeConvention(DokkaDefaults.suppressInheritedMembers) + /** + * Whether to resolve remote files/links over network. + * + * This includes package-lists used for generating external documentation links: + * for instance, to make classes from standard library clickable. + * + * Setting this to `true` can significantly speed up build times in certain cases, + * but can also worsen documentation quality and user experience, for instance by + * not resolving some dependency's class/member links. + * + * When using offline mode, you can cache fetched files locally and provide them to + * Dokka as local paths. For instance, see [GradleExternalDocumentationLinkBuilder]. + * + * Default is `false`. + */ @Input val offlineMode: Property<Boolean> = project.objects.safeProperty<Boolean>() .safeConvention(DokkaDefaults.offlineMode) - @Input - val pluginsConfiguration: ListProperty<in DokkaConfiguration.PluginConfiguration> = project.objects.listProperty() - /** - * Used to keep compatibility with gradle using Kotlin lower than 1.3.50 + * Whether to fail documentation generation if Dokka has emitted a warning or an error. + * Will wait until all errors and warnings have been emitted first. + * + * This setting works well with [GradleDokkaSourceSetBuilder.reportUndocumented] + * + * Default is `false`. */ @Input - val pluginsMapConfiguration: MapProperty<String, String> = project.objects.mapProperty() + val failOnWarning: Property<Boolean> = project.objects.safeProperty<Boolean>() + .safeConvention(DokkaDefaults.failOnWarning) + @Optional + @InputDirectory + @PathSensitive(PathSensitivity.RELATIVE) + val cacheRoot: Property<File?> = project.objects.safeProperty() + + /** + * Type-safe configuration for a Dokka plugin. + * + * Note: this is available in Kotlin DSL only, if Dokka Gradle plugin was applied through `plugins` block + * and the configured plugin can be found on classpath, which may require adding a classpath dependency + * to `buildscript` block in case of external plugins. Some Dokka plugins, such as + * [org.jetbrains.dokka.base.DokkaBase], are on classpath by default. + * + * Example: + * + * ```kotlin + * import org.jetbrains.dokka.base.DokkaBase + * import org.jetbrains.dokka.base.DokkaBaseConfiguration + * + * tasks.dokkaHtml { + * pluginConfiguration<DokkaBase, DokkaBaseConfiguration> { + * footerMessage = "Test" + * } + * } + * ``` + * + * @param P Plugin class that extends [DokkaPlugin] + * @param T Plugin configuration class that extends [ConfigurableBlock] + */ inline fun <reified P : DokkaPlugin, reified T : ConfigurableBlock> pluginConfiguration(block: T.() -> Unit) { val instance = T::class.createInstance().apply(block) val pluginConfiguration = PluginConfigurationImpl( diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTask.kt index 76213f14..c930bc50 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTask.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTask.kt @@ -16,6 +16,33 @@ private typealias TaskPath = String @CacheableTask abstract class DokkaMultiModuleTask : AbstractDokkaParentTask() { + + /** + * List of Markdown files that contain + * [module and package documentation](https://kotlinlang.org/docs/reference/kotlin-doc.html#module-and-package-documentation). + * + * Contents of specified files will be parsed and embedded into documentation as module and package descriptions. + * + * Example of such a file: + * + * ```markdown + * # Module kotlin-demo + * + * The module shows the Dokka usage. + * + * # Package org.jetbrains.kotlin.demo + * + * Contains assorted useful stuff. + * + * ## Level 2 heading + * + * Text after this heading is also part of documentation for `org.jetbrains.kotlin.demo` + * + * # Package org.jetbrains.kotlin.demo2 + * + * Useful stuff in another package. + * ``` + */ @InputFiles @Optional @PathSensitive(PathSensitivity.RELATIVE) diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/toDokkaSourceSetImpl.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaSourceSetMapper.kt index 56c3f071..56c3f071 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/toDokkaSourceSetImpl.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaSourceSetMapper.kt diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradleDokkaSourceSetBuilder.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradleDokkaSourceSetBuilder.kt index 717527d2..6390336a 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradleDokkaSourceSetBuilder.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradleDokkaSourceSetBuilder.kt @@ -13,6 +13,29 @@ import org.jetbrains.dokka.* import java.io.File import java.net.URL +/** + * [Source set](https://kotlinlang.org/docs/multiplatform-discover-project.html#source-sets) level configuration. + * + * Can be configured in the following way with Gradle Kotlin DSL: + * + * ```kotlin + * import org.jetbrains.dokka.gradle.DokkaTask + * + * tasks.dokkaHtml { + * dokkaSourceSets { + * // configure individual source set by name + * named("customSourceSet") { + * suppress.set(true) + * } + * + * // configure all source sets at once + * configureEach { + * reportUndocumented.set(true) + * } + * } + * } + * ``` + */ open class GradleDokkaSourceSetBuilder( @Transient @get:Input val name: String, @Transient @get:Internal internal val project: Project, @@ -22,177 +45,423 @@ open class GradleDokkaSourceSetBuilder( @Input val sourceSetID: DokkaSourceSetID = sourceSetIdFactory.create(name) + /** + * Whether this source set should be skipped when generating documentation. + * + * Default is `false`. + */ @Input val suppress: Property<Boolean> = project.objects.safeProperty<Boolean>() .safeConvention(false) - @Classpath - @Optional - val classpath: ConfigurableFileCollection = project.files() - + /** + * Display name used to refer to the source set. + * + * The name will be used both externally (for example, source set name visible to documentation readers) and + * internally (for example, for logging messages of [reportUndocumented]). + * + * By default, the value is deduced from information provided by the Kotlin Gradle plugin. + */ @Input @Optional val displayName: Property<String?> = project.objects.safeProperty() + /** + * List of Markdown files that contain + * [module and package documentation](https://kotlinlang.org/docs/reference/kotlin-doc.html#module-and-package-documentation). + * + * Contents of specified files will be parsed and embedded into documentation as module and package descriptions. + * + * Example of such a file: + * + * ```markdown + * # Module kotlin-demo + * + * The module shows the Dokka usage. + * + * # Package org.jetbrains.kotlin.demo + * + * Contains assorted useful stuff. + * + * ## Level 2 heading + * + * Text after this heading is also part of documentation for `org.jetbrains.kotlin.demo` + * + * # Package org.jetbrains.kotlin.demo2 + * + * Useful stuff in another package. + * ``` + */ @InputFiles + @Optional @PathSensitive(PathSensitivity.RELATIVE) - val sourceRoots: ConfigurableFileCollection = project.objects.fileCollection() + val includes: ConfigurableFileCollection = project.files() + + /** + * Set of visibility modifiers that should be documented. + * + * This can be used if you want to document protected/internal/private declarations, + * as well as if you want to exclude public declarations and only document internal API. + * + * Can be configured on per-package basis, see [GradlePackageOptionsBuilder.documentedVisibilities]. + * + * Default is [DokkaConfiguration.Visibility.PUBLIC]. + */ + @Input + val documentedVisibilities: SetProperty<DokkaConfiguration.Visibility> = project.objects.setProperty<DokkaConfiguration.Visibility>() + .convention(DokkaDefaults.documentedVisibilities) + /** + * Specifies source sets that current source set depends on. + * + * Among other things, this information is needed to resolve + * [expect/actual](https://kotlinlang.org/docs/multiplatform-connect-to-apis.html) declarations. + * + * Prefer using [dependsOn] function to append dependent source sets to this list. + * + * By default, the values are deduced from information provided by the Kotlin Gradle plugin. + */ @Input val dependentSourceSets: SetProperty<DokkaSourceSetID> = project.objects.setProperty<DokkaSourceSetID>() .convention(emptySet()) - @InputFiles + /** + * Classpath for analysis and interactive samples. + * + * Useful if some types that come from dependencies are not resolved/picked up automatically. + * Property accepts both `.jar` and `.klib` files. + * + * By default, classpath is deduced from information provided by the Kotlin Gradle plugin. + */ + @Classpath @Optional + val classpath: ConfigurableFileCollection = project.files() + + /** + * Source code roots to be analyzed and documented. + * Accepts directories and individual `.kt` / `.java` files. + * + * Prefer using [sourceRoot] function to append source roots to this list. + * + * By default, source roots are deduced from information provided by the Kotlin Gradle plugin. + */ + @InputFiles @PathSensitive(PathSensitivity.RELATIVE) - val samples: ConfigurableFileCollection = project.files() + val sourceRoots: ConfigurableFileCollection = project.objects.fileCollection() + /** + * List of directories or files that contain sample functions which are referenced via + * [@sample](https://kotlinlang.org/docs/kotlin-doc.html#sample-identifier) KDoc tag. + */ @InputFiles @Optional @PathSensitive(PathSensitivity.RELATIVE) - val includes: ConfigurableFileCollection = project.files() - - @Input - val includeNonPublic: Property<Boolean> = project.objects.safeProperty<Boolean>() - .safeConvention(DokkaDefaults.includeNonPublic) - - @Input - val documentedVisibilities: SetProperty<DokkaConfiguration.Visibility> = project.objects.setProperty<DokkaConfiguration.Visibility>() - .convention(DokkaDefaults.documentedVisibilities) + val samples: ConfigurableFileCollection = project.files() + /** + * Whether to emit warnings about visible undocumented declarations, that is declarations without KDocs + * after they have been filtered by [documentedVisibilities]. + * + * This setting works well with [AbstractDokkaTask.failOnWarning]. + * + * Can be overridden for a specific package by setting [GradlePackageOptionsBuilder.reportUndocumented]. + * + * Default is `false`. + */ @Input val reportUndocumented: Property<Boolean> = project.objects.safeProperty<Boolean>() .safeConvention(DokkaDefaults.reportUndocumented) - @Input - val skipEmptyPackages: Property<Boolean> = project.objects.safeProperty<Boolean>() - .safeConvention(DokkaDefaults.skipEmptyPackages) - - @Input - val skipDeprecated: Property<Boolean> = project.objects.safeProperty<Boolean>() - .safeConvention(DokkaDefaults.skipDeprecated) - - @Input - val suppressGeneratedFiles: Property<Boolean> = project.objects.safeProperty<Boolean>() - .safeConvention(true) - - @Input - val jdkVersion: Property<Int> = project.objects.safeProperty<Int>() - .safeConvention(DokkaDefaults.jdkVersion) - + /** + * Specifies the location of the project source code on the Web. If provided, Dokka generates + * "source" links for each declaration. See [GradleSourceLinkBuilder] for more details. + * + * Prefer using [sourceLink] action/closure for adding source links. + */ @Nested val sourceLinks: SetProperty<GradleSourceLinkBuilder> = project.objects.setProperty<GradleSourceLinkBuilder>() .convention(emptySet()) + /** + * Allows to customize documentation generation options on a per-package basis. + * + * @see GradlePackageOptionsBuilder for details + */ @Nested val perPackageOptions: ListProperty<GradlePackageOptionsBuilder> = project.objects.listProperty<GradlePackageOptionsBuilder>() .convention(emptyList()) + /** + * Allows linking to Dokka/Javadoc documentation of the project's dependencies. + * + * Prefer using [externalDocumentationLink] action/closure for adding links. + */ @Nested val externalDocumentationLinks: SetProperty<GradleExternalDocumentationLinkBuilder> = project.objects.setProperty<GradleExternalDocumentationLinkBuilder>() .convention(emptySet()) + /** + * Platform to be used for setting up code analysis and samples. + * + * The default value is deduced from information provided by the Kotlin Gradle plugin. + */ @Input @Optional - val languageVersion: Property<String?> = project.objects.safeProperty() + val platform: Property<Platform> = project.objects.safeProperty<Platform>() + .safeConvention(Platform.DEFAULT) + /** + * Whether to skip packages that contain no visible declarations after + * various filters have been applied. + * + * For instance, if [skipDeprecated] is set to `true` and your package contains only + * deprecated declarations, it will be considered to be empty. + * + * Default is `true`. + */ @Input - @Optional - val apiVersion: Property<String?> = project.objects.safeProperty() + val skipEmptyPackages: Property<Boolean> = project.objects.safeProperty<Boolean>() + .safeConvention(DokkaDefaults.skipEmptyPackages) + /** + * Whether to document declarations annotated with [Deprecated]. + * + * Can be overridden on package level by setting [GradlePackageOptionsBuilder.skipDeprecated]. + * + * Default is `false`. + */ + @Input + val skipDeprecated: Property<Boolean> = project.objects.safeProperty<Boolean>() + .safeConvention(DokkaDefaults.skipDeprecated) + + /** + * Directories or individual files that should be suppressed, meaning declarations from them + * will be not documented. + * + * Will be concatenated with generated files if [suppressGeneratedFiles] is set to `false`. + */ + @InputFiles + @PathSensitive(PathSensitivity.RELATIVE) + val suppressedFiles: ConfigurableFileCollection = project.files() + + /** + * Whether to document/analyze generated files. + * + * Generated files are expected to be present under `{project}/{buildDir}/generated` directory. + * If set to `true`, it effectively adds all files from that directory to [suppressedFiles], so + * you can configure it manually. + * + * Default is `true`. + */ + @Input + val suppressGeneratedFiles: Property<Boolean> = project.objects.safeProperty<Boolean>() + .safeConvention(DokkaDefaults.suppressGeneratedFiles) + + /** + * Whether to generate external documentation links that lead to API reference + * documentation for Kotlin's standard library when declarations from it are used. + * + * Default is `false`, meaning links will be generated. + */ @Input val noStdlibLink: Property<Boolean> = project.objects.safeProperty<Boolean>() .safeConvention(DokkaDefaults.noStdlibLink) + /** + * Whether to generate external documentation links to JDK's Javadocs + * when declarations from it are used. + * + * The version of JDK Javadocs is determined by [jdkVersion] property. + * + * Default is `false`, meaning links will be generated. + */ @Input val noJdkLink: Property<Boolean> = project.objects.safeProperty<Boolean>() .safeConvention(DokkaDefaults.noJdkLink) + /** + * Whether to generate external documentation links for Android SDK API reference + * when declarations from it are used. + * + * Only relevant in Android projects, ignored otherwise. + * + * Default is `false`, meaning links will be generated. + */ @Input val noAndroidSdkLink: Property<Boolean> = project.objects.safeProperty<Boolean>() - .safeConvention(false) - - @InputFiles - @PathSensitive(PathSensitivity.RELATIVE) - val suppressedFiles: ConfigurableFileCollection = project.files() + .safeConvention(DokkaDefaults.noAndroidSdkLink) + + /** + * [Kotlin language version](https://kotlinlang.org/docs/compatibility-modes.html) + * used for setting up analysis and [@sample](https://kotlinlang.org/docs/kotlin-doc.html#sample-identifier) + * environment. + * + * By default, the latest language version available to Dokka's embedded compiler will be used. + */ + @Input + @Optional + val languageVersion: Property<String?> = project.objects.safeProperty() + /** + * [Kotlin API version](https://kotlinlang.org/docs/compatibility-modes.html) + * used for setting up analysis and [@sample](https://kotlinlang.org/docs/kotlin-doc.html#sample-identifier) + * environment. + * + * By default, it will be deduced from [languageVersion]. + */ @Input @Optional - val platform: Property<Platform> = project.objects.safeProperty<Platform>() - .safeConvention(Platform.DEFAULT) + val apiVersion: Property<String?> = project.objects.safeProperty() + + /** + * JDK version to use when generating external documentation links for Java types. + * + * For instance, if you use [java.util.UUID] from JDK in some public declaration signature, + * and this property is set to `8`, Dokka will generate an external documentation link + * to [JDK 8 Javadocs](https://docs.oracle.com/javase/8/docs/api/java/util/UUID.html) for it. + * + * Default is JDK 8. + */ + @Input + val jdkVersion: Property<Int> = project.objects.safeProperty<Int>() + .safeConvention(DokkaDefaults.jdkVersion) + + /** + * Deprecated. Use [documentedVisibilities] instead. + */ + @Input + val includeNonPublic: Property<Boolean> = project.objects.safeProperty<Boolean>() + .safeConvention(DokkaDefaults.includeNonPublic) fun DokkaSourceSetID(sourceSetName: String): DokkaSourceSetID = sourceSetIdFactory.create(sourceSetName) + /** + * Convenient override to **append** source sets to [dependentSourceSets] + */ fun dependsOn(sourceSet: SourceSet) { dependsOn(DokkaSourceSetID(sourceSet.name)) } + /** + * Convenient override to **append** source sets to [dependentSourceSets] + */ fun dependsOn(sourceSet: GradleDokkaSourceSetBuilder) { dependsOn(sourceSet.sourceSetID) } + /** + * Convenient override to **append** source sets to [dependentSourceSets] + */ fun dependsOn(sourceSet: DokkaConfiguration.DokkaSourceSet) { dependsOn(sourceSet.sourceSetID) } + /** + * Convenient override to **append** source sets to [dependentSourceSets] + */ fun dependsOn(sourceSetName: String) { dependsOn(DokkaSourceSetID(sourceSetName)) } + /** + * Convenient override to **append** source sets to [dependentSourceSets] + */ fun dependsOn(sourceSetID: DokkaSourceSetID) { dependentSourceSets.add(sourceSetID) } + /** + * Convenient override to **append** source roots to [sourceRoots] + */ fun sourceRoot(file: File) { sourceRoots.from(file) } + /** + * Convenient override to **append** source roots to [sourceRoots] + */ fun sourceRoot(path: String) { sourceRoot(project.file(path)) } + /** + * Closure for configuring source links, appending to [sourceLinks]. + * + * @see [GradleSourceLinkBuilder] for details. + */ @Suppress("DEPRECATION") // TODO [beresnev] ConfigureUtil will be removed in Gradle 8 fun sourceLink(c: Closure<in GradleSourceLinkBuilder>) { val configured = org.gradle.util.ConfigureUtil.configure(c, GradleSourceLinkBuilder(project)) sourceLinks.add(configured) } + /** + * Action for configuring source links, appending to [sourceLinks]. + * + * @see [GradleSourceLinkBuilder] for details. + */ fun sourceLink(action: Action<in GradleSourceLinkBuilder>) { val sourceLink = GradleSourceLinkBuilder(project) action.execute(sourceLink) sourceLinks.add(sourceLink) } + /** + * Closure for configuring package options, appending to [perPackageOptions]. + * + * @see [GradlePackageOptionsBuilder] for details. + */ @Suppress("DEPRECATION") // TODO [beresnev] ConfigureUtil will be removed in Gradle 8 fun perPackageOption(c: Closure<in GradlePackageOptionsBuilder>) { val configured = org.gradle.util.ConfigureUtil.configure(c, GradlePackageOptionsBuilder(project)) perPackageOptions.add(configured) } + /** + * Action for configuring package options, appending to [perPackageOptions]. + * + * @see [GradlePackageOptionsBuilder] for details. + */ fun perPackageOption(action: Action<in GradlePackageOptionsBuilder>) { val option = GradlePackageOptionsBuilder(project) action.execute(option) perPackageOptions.add(option) } + /** + * Closure for configuring external documentation links, appending to [externalDocumentationLinks]. + * + * @see [GradleExternalDocumentationLinkBuilder] for details. + */ @Suppress("DEPRECATION") // TODO [beresnev] ConfigureUtil will be removed in Gradle 8 fun externalDocumentationLink(c: Closure<in GradleExternalDocumentationLinkBuilder>) { val link = org.gradle.util.ConfigureUtil.configure(c, GradleExternalDocumentationLinkBuilder(project)) externalDocumentationLinks.add(link) } + /** + * Action for configuring external documentation links, appending to [externalDocumentationLinks]. + * + * See [GradleExternalDocumentationLinkBuilder] for details. + */ fun externalDocumentationLink(action: Action<in GradleExternalDocumentationLinkBuilder>) { val link = GradleExternalDocumentationLinkBuilder(project) action.execute(link) externalDocumentationLinks.add(link) } + /** + * Convenient override to **append** external documentation links to [externalDocumentationLinks]. + */ fun externalDocumentationLink(url: String, packageListUrl: String? = null) { externalDocumentationLink(URL(url), packageListUrl = packageListUrl?.let(::URL)) } + /** + * Convenient override to **append** external documentation links to [externalDocumentationLinks]. + */ fun externalDocumentationLink(url: URL, packageListUrl: URL? = null) { externalDocumentationLinks.add( GradleExternalDocumentationLinkBuilder(project).apply { diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradleDokkaSourceSetBuilderExtensions.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradleDokkaSourceSetBuilderExtensions.kt index c5c7428f..5c7c523b 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradleDokkaSourceSetBuilderExtensions.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradleDokkaSourceSetBuilderExtensions.kt @@ -3,14 +3,23 @@ package org.jetbrains.dokka.gradle import com.android.build.gradle.api.AndroidSourceSet import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet +/** + * Convenient override to **append** source sets to [GradleDokkaSourceSetBuilder.dependentSourceSets] + */ fun GradleDokkaSourceSetBuilder.dependsOn(sourceSet: KotlinSourceSet) { dependsOn(DokkaSourceSetID(sourceSet.name)) } +/** + * Convenient override to **append** source sets to [GradleDokkaSourceSetBuilder.dependentSourceSets] + */ fun GradleDokkaSourceSetBuilder.dependsOn(sourceSet: AndroidSourceSet) { dependsOn(DokkaSourceSetID(sourceSet.name)) } +/** + * Extension allowing configuration of Dokka source sets via Kotlin Gradle plugin source sets. + */ fun GradleDokkaSourceSetBuilder.kotlinSourceSet(kotlinSourceSet: KotlinSourceSet) { configureWithKotlinSourceSet(kotlinSourceSet) } diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradleExternalDocumentationLinkBuilder.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradleExternalDocumentationLinkBuilder.kt index 19d150c3..36e4f81d 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradleExternalDocumentationLinkBuilder.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradleExternalDocumentationLinkBuilder.kt @@ -10,12 +10,60 @@ import org.jetbrains.dokka.ExternalDocumentationLink import org.jetbrains.dokka.ExternalDocumentationLinkImpl import java.net.URL +/** + * Configuration builder that allows creating links leading to externally hosted + * documentation of your dependencies. + * + * For instance, if you are using types from `kotlinx.serialization`, by default + * they will be unclickable in your documentation, as if unresolved. However, + * since API reference for `kotlinx.serialization` is also built by Dokka and is + * [published on kotlinlang.org](https://kotlinlang.org/api/kotlinx.serialization/), + * you can configure external documentation links for it, allowing Dokka to generate + * documentation links for used types, making them clickable and appear resolved. + * + * Example in Gradle Kotlin DSL: + * + * ```kotlin + * externalDocumentationLink { + * url.set(URL("https://kotlinlang.org/api/kotlinx.serialization/")) + * packageListUrl.set( + * rootProject.projectDir.resolve("serialization.package.list").toURL() + * ) + * } + * ``` + */ class GradleExternalDocumentationLinkBuilder( @Transient @get:Internal internal val project: Project ) : DokkaConfigurationBuilder<ExternalDocumentationLinkImpl> { + + /** + * Root URL of documentation to link with. **Must** contain a trailing slash. + * + * Dokka will do its best to automatically find `package-list` for the given URL, and link + * declarations together. + * + * It automatic resolution fails or if you want to use locally cached files instead, + * consider providing [packageListUrl]. + * + * Example: + * + * ```kotlin + * java.net.URL("https://kotlinlang.org/api/kotlinx.serialization/") + * ``` + */ @Input val url: Property<URL?> = project.objects.safeProperty() + /** + * Specifies the exact location of a `package-list` instead of relying on Dokka + * automatically resolving it. Can also be a locally cached file to avoid network calls. + * + * Example: + * + * ```kotlin + * rootProject.projectDir.resolve("serialization.package.list").toURL() + * ``` + */ @Optional @Input val packageListUrl: Property<URL?> = project.objects.safeProperty() diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradlePackageOptionsBuilder.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradlePackageOptionsBuilder.kt index f15a6462..4e53cf81 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradlePackageOptionsBuilder.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradlePackageOptionsBuilder.kt @@ -13,33 +13,91 @@ import org.jetbrains.dokka.DokkaConfigurationBuilder import org.jetbrains.dokka.DokkaDefaults import org.jetbrains.dokka.PackageOptionsImpl - +/** + * Configuration builder that allows setting some options for specific packages + * matched by [matchingRegex]. + * + * Example in Gradle Kotlin DSL: + * + * ```kotlin + * tasks.dokkaHtml { + * dokkaSourceSets.configureEach { + * perPackageOption { + * matchingRegex.set(".*internal.*") + * suppress.set(true) + * } + * } + * } + * ``` + */ class GradlePackageOptionsBuilder( @Transient @get:Internal internal val project: Project ) : DokkaConfigurationBuilder<PackageOptionsImpl> { + + /** + * Regular expression that is used to match the package. + * + * Default is any string: `.*`. + */ @Input val matchingRegex: Property<String> = project.objects.safeProperty<String>() .safeConvention(".*") + /** + * Whether this package should be skipped when generating documentation. + * + * Default is `false`. + */ @Input - val includeNonPublic: Property<Boolean> = project.objects.safeProperty<Boolean>() - .safeConvention(DokkaDefaults.includeNonPublic) + val suppress: Property<Boolean> = project.objects.safeProperty<Boolean>() + .safeConvention(DokkaDefaults.suppress) + /** + * Set of visibility modifiers that should be documented. + * + * This can be used if you want to document protected/internal/private declarations within a + * specific package, as well as if you want to exclude public declarations and only document internal API. + * + * Can be configured for a whole source set, see [GradleDokkaSourceSetBuilder.documentedVisibilities]. + * + * Default is [DokkaConfiguration.Visibility.PUBLIC]. + */ @Input val documentedVisibilities: SetProperty<DokkaConfiguration.Visibility> = project.objects.setProperty<DokkaConfiguration.Visibility>() .convention(DokkaDefaults.documentedVisibilities) + /** + * Whether to document declarations annotated with [Deprecated]. + * + * Can be overridden on source set level by setting [GradleDokkaSourceSetBuilder.skipDeprecated]. + * + * Default is `false`. + */ + @Input + val skipDeprecated: Property<Boolean> = project.objects.safeProperty<Boolean>() + .safeConvention(DokkaDefaults.skipDeprecated) + + /** + * Whether to emit warnings about visible undocumented declarations, that is declarations from + * this package and without KDocs, after they have been filtered by [documentedVisibilities]. + * + * This setting works well with [AbstractDokkaTask.failOnWarning]. + * + * Can be overridden on source set level by setting [GradleDokkaSourceSetBuilder.reportUndocumented]. + * + * Default is `false`. + */ @Input val reportUndocumented: Property<Boolean> = project.objects.safeProperty<Boolean>() .safeConvention(DokkaDefaults.reportUndocumented) + /** + * Deprecated. Use [documentedVisibilities] instead. + */ @Input - val skipDeprecated: Property<Boolean> = project.objects.safeProperty<Boolean>() - .safeConvention(DokkaDefaults.skipDeprecated) + val includeNonPublic: Property<Boolean> = project.objects.safeProperty<Boolean>() + .safeConvention(DokkaDefaults.includeNonPublic) - @Input - val suppress: Property<Boolean> = project.objects.safeProperty<Boolean>() - .safeConvention(DokkaDefaults.suppress) override fun build(): PackageOptionsImpl = PackageOptionsImpl( matchingRegex = checkNotNull(matchingRegex.getSafe()) { "prefix not specified" }, diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradleSourceLinkBuilder.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradleSourceLinkBuilder.kt index 2ddd8056..4a0c1333 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradleSourceLinkBuilder.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradleSourceLinkBuilder.kt @@ -8,17 +8,67 @@ import org.jetbrains.dokka.SourceLinkDefinitionImpl import java.io.File import java.net.URL +/** + * Configuration builder that allows adding a `source` link to each signature + * which leads to [remoteUrl] with a specific line number (configurable by setting [remoteLineSuffix]), + * letting documentation readers find source code for each declaration. + * + * Example in Gradle Kotlin DSL: + * + * ```kotlin + * sourceLink { + * localDirectory.set(projectDir.resolve("src")) + * remoteUrl.set(URL("https://github.com/kotlin/dokka/tree/master/src")) + * remoteLineSuffix.set("#L") + * } + * ``` + */ class GradleSourceLinkBuilder( @Transient @get:Internal internal val project: Project ) : DokkaConfigurationBuilder<SourceLinkDefinitionImpl> { + /** + * Path to the local source directory. The path must be relative to the root of current project. + * + * Example: + * + * ```kotlin + * projectDir.resolve("src") + * ``` + */ @InputDirectory @PathSensitive(PathSensitivity.RELATIVE) val localDirectory: Property<File?> = project.objects.safeProperty() + /** + * URL of source code hosting service that can be accessed by documentation readers, + * like GitHub, GitLab, Bitbucket, etc. This URL will be used to generate + * source code links of declarations. + * + * Example: + * + * ```kotlin + * java.net.URL("https://github.com/username/projectname/tree/master/src")) + * ``` + */ @Input val remoteUrl: Property<URL?> = project.objects.safeProperty() + /** + * Suffix used to append source code line number to the URL. This will help readers navigate + * not only to the file, but to the specific line number of the declaration. + * + * The number itself will be appended to the specified suffix. For instance, + * if this property is set to `#L` and the line number is 10, resulting URL suffix + * will be `#L10` + * + * Suffixes used by popular services: + * - GitHub: `#L` + * - GitLab: `#L` + * - Bitbucket: `#lines-` + * + * Default is `#L`. + */ @Optional @Input val remoteLineSuffix: Property<String> = project.objects.safeProperty<String>() diff --git a/runners/maven-plugin/api/maven-plugin.api b/runners/maven-plugin/api/maven-plugin.api index 3b4ace56..28d96bd3 100644 --- a/runners/maven-plugin/api/maven-plugin.api +++ b/runners/maven-plugin/api/maven-plugin.api @@ -66,22 +66,6 @@ public abstract class org/jetbrains/dokka/maven/AbstractDokkaMojo : org/apache/m public final fun setSuppressedFiles (Ljava/util/List;)V } -public final class org/jetbrains/dokka/maven/AbstractDokkaMojo$PackageOptions : org/jetbrains/dokka/DokkaConfiguration$PackageOptions { - public fun <init> ()V - public fun getDocumentedVisibilities ()Ljava/util/Set; - public fun getIncludeNonPublic ()Z - public fun getMatchingRegex ()Ljava/lang/String; - public fun getReportUndocumented ()Ljava/lang/Boolean; - public fun getSkipDeprecated ()Z - public fun getSuppress ()Z - public fun setDocumentedVisibilities (Ljava/util/Set;)V - public fun setIncludeNonPublic (Z)V - public fun setMatchingRegex (Ljava/lang/String;)V - public fun setReportUndocumented (Z)V - public fun setSkipDeprecated (Z)V - public fun setSuppress (Z)V -} - public final class org/jetbrains/dokka/maven/DokkaJavadocJarMojo : org/jetbrains/dokka/maven/AbstractDokkaMojo { public fun <init> ()V public fun execute ()V @@ -124,6 +108,22 @@ public final class org/jetbrains/dokka/maven/MavenDokkaLogger : org/jetbrains/do public fun warn (Ljava/lang/String;)V } +public final class org/jetbrains/dokka/maven/PackageOptions : org/jetbrains/dokka/DokkaConfiguration$PackageOptions { + public fun <init> ()V + public fun getDocumentedVisibilities ()Ljava/util/Set; + public fun getIncludeNonPublic ()Z + public fun getMatchingRegex ()Ljava/lang/String; + public fun getReportUndocumented ()Ljava/lang/Boolean; + public fun getSkipDeprecated ()Z + public fun getSuppress ()Z + public fun setDocumentedVisibilities (Ljava/util/Set;)V + public fun setIncludeNonPublic (Z)V + public fun setMatchingRegex (Ljava/lang/String;)V + public fun setReportUndocumented (Z)V + public fun setSkipDeprecated (Z)V + public fun setSuppress (Z)V +} + public final class org/jetbrains/dokka/maven/SourceLinkMapItem { public fun <init> ()V public final fun getLineSuffix ()Ljava/lang/String; diff --git a/runners/maven-plugin/src/main/kotlin/DokkaMojo.kt b/runners/maven-plugin/src/main/kotlin/DokkaMojo.kt index 581d4c9e..92ab9754 100644 --- a/runners/maven-plugin/src/main/kotlin/DokkaMojo.kt +++ b/runners/maven-plugin/src/main/kotlin/DokkaMojo.kt @@ -24,28 +24,6 @@ import org.jetbrains.dokka.DokkaConfiguration.ExternalDocumentationLink import java.io.File import java.net.URL -class SourceLinkMapItem { - @Parameter(name = "path", required = true) - var path: String = "" - - @Parameter(name = "url", required = true) - var url: String = "" - - @Parameter(name = "lineSuffix") - var lineSuffix: String? = null -} - -class ExternalDocumentationLinkBuilder { - - @Parameter(name = "url", required = true) - var url: URL? = null - - @Parameter(name = "packageListUrl", required = true) - var packageListUrl: URL? = null - - fun build() = ExternalDocumentationLink(url, packageListUrl) -} - abstract class AbstractDokkaMojo(private val defaultDokkaPlugins: List<Dependency>) : AbstractMojo() { @Parameter(defaultValue = "\${project}", readonly = true, required = true) @@ -64,118 +42,303 @@ abstract class AbstractDokkaMojo(private val defaultDokkaPlugins: List<Dependenc @Component private var resolutionErrorHandler: ResolutionErrorHandler? = null - class PackageOptions : DokkaConfiguration.PackageOptions { - @Parameter - override var matchingRegex: String = ".*" - - @Parameter - @Deprecated("Use [documentedVisibilities] property for a more flexible control over documented visibilities") - override var includeNonPublic: Boolean = DokkaDefaults.includeNonPublic - - @Parameter - override var reportUndocumented: Boolean = DokkaDefaults.reportUndocumented - - @Parameter - override var skipDeprecated: Boolean = DokkaDefaults.skipDeprecated - - @Parameter - override var suppress: Boolean = DokkaDefaults.suppress - - @Parameter(property = "visibility") - override var documentedVisibilities: Set<DokkaConfiguration.Visibility> = DokkaDefaults.documentedVisibilities - } + @Parameter(defaultValue = "JVM") + var displayName: String = "JVM" @Parameter var sourceSetName: String = "JVM" + /** + * Source code roots to be analyzed and documented. + * Accepts directories and individual `.kt` / `.java` files. + * + * Default is `{project.compileSourceRoots}`. + */ @Parameter(required = true, defaultValue = "\${project.compileSourceRoots}") var sourceDirectories: List<String> = emptyList() + /** + * List of directories or files that contain sample functions which are referenced via + * [@sample](https://kotlinlang.org/docs/kotlin-doc.html#sample-identifier) KDoc tag. + */ @Parameter var samples: List<String> = emptyList() + /** + * List of Markdown files that contain + * [module and package documentation](https://kotlinlang.org/docs/reference/kotlin-doc.html#module-and-package-documentation). + * + * Contents of specified files will be parsed and embedded into documentation as module and package descriptions. + * + * Example of such a file: + * + * ```markdown + * # Module kotlin-demo + * + * The module shows the Dokka usage. + * + * # Package org.jetbrains.kotlin.demo + * + * Contains assorted useful stuff. + * + * ## Level 2 heading + * + * Text after this heading is also part of documentation for `org.jetbrains.kotlin.demo` + * + * # Package org.jetbrains.kotlin.demo2 + * + * Useful stuff in another package. + * ``` + */ @Parameter var includes: List<String> = emptyList() + /** + * Classpath for analysis and interactive samples. + * + * Useful if some types that come from dependencies are not resolved/picked up automatically. + * Property accepts both `.jar` and `.klib` files. + * + * Default is `{project.compileClasspathElements}`. + */ @Parameter(required = true, defaultValue = "\${project.compileClasspathElements}") var classpath: List<String> = emptyList() + /** + * Specifies the location of the project source code on the Web. If provided, Dokka generates + * "source" links for each declaration. See [SourceLinkMapItem] for more details. + */ @Parameter var sourceLinks: List<SourceLinkMapItem> = emptyList() + /** + * Display name used to refer to the project/module. Used for ToC, navigation, logging, etc. + * + * Default is `{project.artifactId}`. + */ @Parameter(required = true, defaultValue = "\${project.artifactId}") var moduleName: String = "" + /** + * Whether to skip documentation generation. + * + * Default is `false`. + */ @Parameter(required = false, defaultValue = "false") var skip: Boolean = false + /** + * JDK version to use when generating external documentation links for Java types. + * + * For instance, if you use [java.util.UUID] from JDK in some public declaration signature, + * and this property is set to `8`, Dokka will generate an external documentation link + * to [JDK 8 Javadocs](https://docs.oracle.com/javase/8/docs/api/java/util/UUID.html) for it. + * + * Default is JDK 8. + */ @Parameter(required = false, defaultValue = "${DokkaDefaults.jdkVersion}") var jdkVersion: Int = DokkaDefaults.jdkVersion + /** + * Whether to document declarations annotated with [Deprecated]. + * + * Can be overridden on package level by setting [PackageOptions.skipDeprecated]. + * + * Default is `false`. + */ @Parameter var skipDeprecated: Boolean = DokkaDefaults.skipDeprecated + /** + * Whether to skip packages that contain no visible declarations after + * various filters have been applied. + * + * For instance, if [skipDeprecated] is set to `true` and your package contains only + * deprecated declarations, it will be considered to be empty. + * + * Default is `true`. + */ @Parameter var skipEmptyPackages: Boolean = DokkaDefaults.skipEmptyPackages + /** + * Whether to emit warnings about visible undocumented declarations, that is declarations without KDocs + * after they have been filtered by [documentedVisibilities]. + * + * This setting works well with [failOnWarning]. + * + * Can be overridden for a specific package by setting [PackageOptions.reportUndocumented]. + * + * Default is `false`. + */ @Parameter var reportUndocumented: Boolean = DokkaDefaults.reportUndocumented + /** + * Allows to customize documentation generation options on a per-package basis. + * + * @see PackageOptions for details + */ @Parameter var perPackageOptions: List<PackageOptions> = emptyList() + /** + * Allows linking to Dokka/Javadoc documentation of the project's dependencies. + * + * @see ExternalDocumentationLinkBuilder for details + */ @Parameter var externalDocumentationLinks: List<ExternalDocumentationLinkBuilder> = emptyList() + /** + * Whether to generate external documentation links that lead to API reference + * documentation for Kotlin's standard library when declarations from it are used. + * + * Default is `false`, meaning links will be generated. + */ @Parameter(defaultValue = "${DokkaDefaults.noStdlibLink}") var noStdlibLink: Boolean = DokkaDefaults.noStdlibLink + /** + * Whether to generate external documentation links to JDK's Javadocs + * when declarations from it are used. + * + * The version of JDK Javadocs is determined by [jdkVersion] property. + * + * Default is `false`, meaning links will be generated. + */ @Parameter(defaultValue = "${DokkaDefaults.noJdkLink}") var noJdkLink: Boolean = DokkaDefaults.noJdkLink - @Parameter - var cacheRoot: String? = null - - @Parameter(defaultValue = "JVM") - var displayName: String = "JVM" - + /** + * Whether to resolve remote files/links over network. + * + * This includes package-lists used for generating external documentation links: + * for instance, to make classes from standard library clickable. + * + * Setting this to `true` can significantly speed up build times in certain cases, + * but can also worsen documentation quality and user experience, for instance by + * not resolving some dependency's class/member links. + * + * When using offline mode, you can cache fetched files locally and provide them to + * Dokka as local paths. For instance, see [ExternalDocumentationLinkBuilder]. + * + * Default is `false`. + */ @Parameter(defaultValue = "${DokkaDefaults.offlineMode}") var offlineMode: Boolean = DokkaDefaults.offlineMode + /** + * [Kotlin language version](https://kotlinlang.org/docs/compatibility-modes.html) + * used for setting up analysis and [@sample](https://kotlinlang.org/docs/kotlin-doc.html#sample-identifier) + * environment. + * + * By default, the latest language version available to Dokka's embedded compiler will be used. + */ @Parameter var languageVersion: String? = null + /** + * [Kotlin API version](https://kotlinlang.org/docs/compatibility-modes.html) + * used for setting up analysis and [@sample](https://kotlinlang.org/docs/kotlin-doc.html#sample-identifier) + * environment. + * + * By default, it will be deduced from [languageVersion]. + */ @Parameter var apiVersion: String? = null + /** + * Directories or individual files that should be suppressed, meaning declarations from them + * will be not documented. + */ @Parameter var suppressedFiles: List<String> = emptyList() - @Parameter - var platform: String = "" - - @Parameter - var includeNonPublic: Boolean = DokkaDefaults.includeNonPublic - + /** + * Set of visibility modifiers that should be documented. + * + * This can be used if you want to document protected/internal/private declarations, + * as well as if you want to exclude public declarations and only document internal API. + * + * Can be configured on per-package basis, see [PackageOptions.documentedVisibilities]. + * + * Default is [DokkaConfiguration.Visibility.PUBLIC]. + */ @Parameter(property = "visibility") var documentedVisibilities: Set<DokkaConfiguration.Visibility> = DokkaDefaults.documentedVisibilities // hack to set the default value for lists, didn't find any other safe way // maven seems to overwrite Kotlin's default initialization value, so it doesn't matter what you put there get() = field.ifEmpty { DokkaDefaults.documentedVisibilities } + /** + * Whether to fail documentation generation if Dokka has emitted a warning or an error. + * Will wait until all errors and warnings have been emitted first. + * + * This setting works well with [reportUndocumented] + * + * Default is `false`. + */ @Parameter var failOnWarning: Boolean = DokkaDefaults.failOnWarning + /** + * Whether to suppress obvious functions. + * + * A function is considered to be obvious if it is: + * - Inherited from `kotlin.Any`, `Kotlin.Enum`, `java.lang.Object` or `java.lang.Enum`, + * such as `equals`, `hashCode`, `toString`. + * - Synthetic (generated by the compiler) and does not have any documentation, such as + * `dataClass.componentN` or `dataClass.copy`. + * + * Default is `true` + */ @Parameter(defaultValue = "${DokkaDefaults.suppressObviousFunctions}") var suppressObviousFunctions: Boolean = DokkaDefaults.suppressObviousFunctions + /** + * Whether to suppress inherited members that aren't explicitly overridden in a given class. + * + * Note: this can suppress functions such as `equals`/`hashCode`/`toString`, but cannot suppress + * synthetic functions such as `dataClass.componentN` and `dataClass.copy`. Use [suppressObviousFunctions] + * for that. + * + * Default is `false`. + */ @Parameter(defaultValue = "${DokkaDefaults.suppressInheritedMembers}") var suppressInheritedMembers: Boolean = DokkaDefaults.suppressInheritedMembers + /** + * Dokka plugins to be using during documentation generation. + * + * Example: + * + * ```xml + * <dokkaPlugins> + * <plugin> + * <groupId>org.jetbrains.dokka</groupId> + * <artifactId>gfm-plugin</artifactId> + * <version>1.7.20</version> + * </plugin> + * </dokkaPlugins> + * ``` + */ @Parameter var dokkaPlugins: List<Dependency> = emptyList() get() = field + defaultDokkaPlugins + @Parameter + var cacheRoot: String? = null + + @Parameter + var platform: String = "" + + /** + * Deprecated. Use [documentedVisibilities] instead. + */ + @Parameter + var includeNonPublic: Boolean = DokkaDefaults.includeNonPublic + protected abstract fun getOutDir(): String override fun execute() { @@ -320,6 +483,12 @@ abstract class AbstractDokkaMojo(private val defaultDokkaPlugins: List<Dependenc requiresProject = true ) class DokkaMojo : AbstractDokkaMojo(emptyList()) { + + /** + * Directory to which documentation will be generated. + * + * Default is `{project.basedir}/target/dokka`. + */ @Parameter(required = true, defaultValue = "\${project.basedir}/target/dokka") var outputDir: String = "" @@ -334,6 +503,12 @@ class DokkaMojo : AbstractDokkaMojo(emptyList()) { requiresProject = true ) class DokkaJavadocMojo : AbstractDokkaMojo(listOf(javadocDependency)) { + + /** + * Directory to which documentation will be generated. + * + * Default is `{project.basedir}/target/dokkaJavadoc`. + */ @Parameter(required = true, defaultValue = "\${project.basedir}/target/dokkaJavadoc") var outputDir: String = "" @@ -348,6 +523,12 @@ class DokkaJavadocMojo : AbstractDokkaMojo(listOf(javadocDependency)) { requiresProject = true ) class DokkaJavadocJarMojo : AbstractDokkaMojo(listOf(javadocDependency)) { + + /** + * Directory to which documentation jar will be generated. + * + * Default is `{project.basedir}/target/dokkaJavadocJar`. + */ @Parameter(required = true, defaultValue = "\${project.basedir}/target/dokkaJavadocJar") var outputDir: String = "" diff --git a/runners/maven-plugin/src/main/kotlin/ExternalDocumentationLinkBuilder.kt b/runners/maven-plugin/src/main/kotlin/ExternalDocumentationLinkBuilder.kt new file mode 100644 index 00000000..8e145fd5 --- /dev/null +++ b/runners/maven-plugin/src/main/kotlin/ExternalDocumentationLinkBuilder.kt @@ -0,0 +1,63 @@ +package org.jetbrains.dokka.maven + +import org.apache.maven.plugins.annotations.Parameter +import org.jetbrains.dokka.ExternalDocumentationLink +import java.net.URL + +/** + * Configuration block that allows creating links leading to externally hosted + * documentation of your dependencies. + * + * For instance, if you are using types from `kotlinx.serialization`, by default + * they will be unclickable in your documentation, as if unresolved. However, + * since API reference for `kotlinx.serialization` is also built by Dokka and is + * [published on kotlinlang.org](https://kotlinlang.org/api/kotlinx.serialization/), + * you can configure external documentation links for it, allowing Dokka to generate + * documentation links for used types, making them clickable and appear resolved. + * + * Example: + * + * ```xml + * <externalDocumentationLinks> + * <link> + * <url>https://kotlinlang.org/api/latest/jvm/stdlib/</url> + * <packageListUrl>file:/${project.basedir}/stdlib.package.list</packageListUrl> + * </link> + * </externalDocumentationLinks> + * ``` + */ +class ExternalDocumentationLinkBuilder { + + /** + * Root URL of documentation to link with. **Must** contain a trailing slash. + * + * Dokka will do its best to automatically find `package-list` for the given URL, and link + * declarations together. + * + * It automatic resolution fails or if you want to use locally cached files instead, + * consider providing [packageListUrl]. + * + * Example: + * + * ```xml + * <url>https://kotlinlang.org/api/latest/jvm/stdlib/</url> + * ``` + */ + @Parameter(name = "url", required = true) + var url: URL? = null + + /** + * Specifies the exact location of a `package-list` instead of relying on Dokka + * automatically resolving it. Can also be a locally cached file to avoid network calls. + * + * Example: + * + * ```xml + * <packageListUrl>file:/${project.basedir}/stdlib.package.list</packageListUrl> + * ``` + */ + @Parameter(name = "packageListUrl", required = true) + var packageListUrl: URL? = null + + fun build() = ExternalDocumentationLink(url, packageListUrl) +} diff --git a/runners/maven-plugin/src/main/kotlin/PackageOptions.kt b/runners/maven-plugin/src/main/kotlin/PackageOptions.kt new file mode 100644 index 00000000..af678769 --- /dev/null +++ b/runners/maven-plugin/src/main/kotlin/PackageOptions.kt @@ -0,0 +1,85 @@ +package org.jetbrains.dokka.maven + +import org.apache.maven.plugins.annotations.Parameter +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.DokkaDefaults + +/** + * Configuration block that allows setting some options for specific packages + * matched by [matchingRegex]. + * + * Example: + * + * ```xml + * <configuration> + * <perPackageOptions> + * <packageOptions> + * <matchingRegex>.*api.*</matchingRegex> + * <suppress>false</suppress> + * <reportUndocumented>false</reportUndocumented> + * <skipDeprecated>false</skipDeprecated> + * <documentedVisibilities> + * <visibility>PUBLIC</visibility> + * <visibility>PROTECTED</visibility> + * </documentedVisibilities> + * </packageOptions> + * </perPackageOptions> + * </configuration> + * ``` + */ +class PackageOptions : DokkaConfiguration.PackageOptions { + + /** + * Regular expression that is used to match the package. + * + * If multiple packages match the same `matchingRegex`, the longest `matchingRegex` will be used. + * + * Default is any string: `.*`. + */ + @Parameter + override var matchingRegex: String = ".*" + + /** + * Whether this package should be skipped when generating documentation. + * + * Default is `false`. + */ + @Parameter + override var suppress: Boolean = DokkaDefaults.suppress + + /** + * List of visibility modifiers that should be documented. + * + * This can be used if you want to document protected/internal/private declarations within a + * specific package, as well as if you want to exclude public declarations and only document internal API. + * + * Default is [DokkaConfiguration.Visibility.PUBLIC]. + */ + @Parameter(property = "visibility") + override var documentedVisibilities: Set<DokkaConfiguration.Visibility> = DokkaDefaults.documentedVisibilities + + /** + * Whether to document declarations annotated with [Deprecated]. + * + * Can be set on project level with [AbstractDokkaMojo.skipDeprecated]. + * + * Default is `false`. + */ + @Parameter + override var skipDeprecated: Boolean = DokkaDefaults.skipDeprecated + + /** + * Whether to emit warnings about visible undocumented declarations, that is declarations from + * this package and without KDocs, after they have been filtered by [documentedVisibilities]. + * + * This setting works well with [AbstractDokkaMojo.failOnWarning]. + * + * Default is `false`. + */ + @Parameter + override var reportUndocumented: Boolean = DokkaDefaults.reportUndocumented + + @Parameter + @Deprecated("Use [documentedVisibilities] property for a more flexible control over documented visibilities") + override var includeNonPublic: Boolean = DokkaDefaults.includeNonPublic +} diff --git a/runners/maven-plugin/src/main/kotlin/SourceLinkMapItem.kt b/runners/maven-plugin/src/main/kotlin/SourceLinkMapItem.kt new file mode 100644 index 00000000..621b38d8 --- /dev/null +++ b/runners/maven-plugin/src/main/kotlin/SourceLinkMapItem.kt @@ -0,0 +1,65 @@ +package org.jetbrains.dokka.maven + +import org.apache.maven.plugins.annotations.Parameter + +/** + * Configuration block that allows adding a `source` link to each signature + * which leads to [path] with a specific line number (configurable by setting [lineSuffix]), + * letting documentation readers find source code for each declaration. + * + * Example: + * + * ```xml + * <sourceLinks> + * <link> + * <path>${project.basedir}/src</path> + * <url>https://github.com/kotlin/dokka/tree/master/src</url> + * <lineSuffix>#L</lineSuffix> + * </link> + * </sourceLinks> + * ``` + */ +class SourceLinkMapItem { + + /** + * Path to the local source directory. The path must be relative to the root of current project. + * + * Example: + * + * ```xml + * <path>${project.basedir}/src</path> + * ``` + */ + @Parameter(name = "path", required = true) + var path: String = "" + + /** + * URL of source code hosting service that can be accessed by documentation readers, + * like GitHub, GitLab, Bitbucket, etc. This URL will be used to generate + * source code links of declarations. + * + * Example: + * + * ```xml + * <url>https://github.com/username/projectname/tree/master/src</url> + * ``` + */ + @Parameter(name = "url", required = true) + var url: String = "" + + /** + * Suffix used to append source code line number to the URL. This will help readers navigate + * not only to the file, but to the specific line number of the declaration. + * + * The number itself will be appended to the specified suffix. For instance, + * if this property is set to `#L` and the line number is 10, resulting URL suffix + * will be `#L10` + * + * Suffixes used by popular services: + * - GitHub: `#L` + * - GitLab: `#L` + * - Bitbucket: `#lines-` + */ + @Parameter(name = "lineSuffix") + var lineSuffix: String? = null +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 859df2bb..677d7812 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -36,7 +36,7 @@ include("integration-tests:maven") include("test-utils") -include("docs") +include("mkdocs") pluginManagement { val kotlin_version: String by settings @@ -59,4 +59,4 @@ gradleEnterprise { termsOfServiceAgree = "yes" publishAlwaysIf(isCiBuild) } -}
\ No newline at end of file +} |