diff --git a/core/api/core.api b/core/api/core.api index 7d29d872bc..f466ed71e0 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 @@ -215,6 +211,7 @@ public final class org/jetbrains/dokka/DokkaDefaults { 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 +221,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; @@ -365,6 +363,7 @@ public final class org/jetbrains/dokka/GlobalDokkaConfiguration { public final class org/jetbrains/dokka/PackageOptionsImpl : org/jetbrains/dokka/DokkaConfiguration$PackageOptions { public fun (Ljava/lang/String;ZLjava/lang/Boolean;ZZLjava/util/Set;)V + public synthetic fun (Ljava/lang/String;ZLjava/lang/Boolean;ZZLjava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Ljava/lang/String; public final fun component2 ()Z public final fun component3 ()Ljava/lang/Boolean; diff --git a/core/src/main/kotlin/DokkaBootstrapImpl.kt b/core/src/main/kotlin/DokkaBootstrapImpl.kt index 75c4c0afe9..114bade7d2 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): List = 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 c26faf2877..77384acee5 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 = 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 = setOf(DokkaConfiguration.Visibility.PUBLIC) - const val sourceSetDisplayName = "JVM" - const val sourceSetName = "main" - val moduleVersion: String? = null val pluginsConfiguration = mutableListOf() - 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?, diff --git a/core/src/main/kotlin/defaultConfiguration.kt b/core/src/main/kotlin/defaultConfiguration.kt index 8c7c8b5da4..6615457085 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, + override val documentedVisibilities: Set, // TODO add default to DokkaDefaults.documentedVisibilities ) : DokkaConfiguration.PackageOptions diff --git a/docs/topics/formats/html.md b/docs/topics/formats/html.md index 36f92055c5..2d0c6f6774 100644 --- a/docs/topics/formats/html.md +++ b/docs/topics/formats/html.md @@ -22,7 +22,8 @@ This format comes standard in all runners: ## Configuration -HTML format is Dokka's base format, so it is configurable through `DokkaBase` and `DokkaBaseConfiguration`: +HTML format is Dokka's base format, so it is configurable through `DokkaBase` and `DokkaBaseConfiguration` +classes: @@ -160,7 +161,7 @@ Via [JSON configuration](cli.md#running-with-json-configuration): -For details, see [configuring Dokka plugins](plugins_introduction.md#configuring-dokka-plugins) section. +For more details, see [configuring Dokka plugins](plugins_introduction.md#configuring-dokka-plugins) topic. ### Configuration options @@ -176,7 +177,7 @@ For details, see [configuring Dokka plugins](plugins_introduction.md#configuring ## Customization -HTML format is highly customizable to the point where you wouldn't be able to tell it was generated by Dokka. +HTML format provides a number of customization options. ### Customizing styles @@ -192,7 +193,7 @@ Files with the same name will be overwritten, so it is possible to override styl | `prism.css` | Styles for [PrismJS](https://prismjs.com/) syntax highlighter | | `jetbrains-mono.css` | Font styling | -All of these are +Source code for all of the used styles is [available on GitHub](https://github.com/Kotlin/dokka/tree/%dokkaVersion%/plugins/base/src/main/resources/dokka/styles). ### Customizing assets @@ -203,7 +204,7 @@ You can provide your own images to be bundled with documentation by setting `cus Files with the same name will be overwritten, so it is possible to override images and icons that Dokka uses. 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 view all images used by Dokka on +You can find all images used by Dokka on [GitHub](https://github.com/Kotlin/dokka/tree/%dokkaVersion%/plugins/base/src/main/resources/dokka/images). ### Changing the logo @@ -211,10 +212,10 @@ You can view all images used by Dokka on To customize the logo, you can begin by [providing your own asset](#customizing-assets) for `logo-icon.svg`. If your image has similar size, it should not look out of place. -However, if your image has different dimensions or you want to use a `.png` image instead of the default `.svg`, -you can [override `logo-styles.css` stylesheet](#customizing-styles). +However, if your image has different dimensions or you want to use a `.png` image instead of the default `.svg` file, +you can [override `logo-styles.css` stylesheet](#customizing-styles) and make it fit. -For more details, see +For an example of how to do it, see [custom format example project](https://github.com/Kotlin/dokka/tree/%dokkaVersion%/examples/gradle/dokka-customFormat-example). ### Modifying footer @@ -226,7 +227,7 @@ You can modify the footer message by setting `footerMessage` [configuration prop Dokka provides the ability to modify [FreeMarker](https://freemarker.apache.org/) templates used for generating documentation pages. -You can completely change the header, add your own banners/menus/search, load analytics, change body styling and so on. +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: @@ -238,7 +239,7 @@ Dokka uses the following templates: | `includes/page_metadata.ft` | Metadata used within `` container. | | `includes/source_set_selector.ft` | [Source set](https://kotlinlang.org/docs/multiplatform-discover-project.html#source-sets) selector in the header. | -`base.ftl` template is the base template and it includes all the other ones. You can find all templates +`base.ftl` template is the base template and it includes all the other ones. You can find source code for all templates [on GitHub](https://github.com/Kotlin/dokka/tree/%dokkaVersion%/plugins/base/src/main/resources/dokka/templates). You can override any template by setting `templatesDir` [configuration property](#configuration). Dokka will look @@ -268,11 +269,11 @@ context and thus need to be resolved at later stages by the [MultiModule](gradle #### Directives -Dokka-defined [directives](https://freemarker.apache.org/docs/ref_directive_userDefined.html) can also be used: +You can also use the following Dokka-defined [directives](https://freemarker.apache.org/docs/ref_directive_userDefined.html): -| **Variable** | **Description** | -|----------------------------|----------------------------------------------------------------------------------------------------------------------------------------| -| `<@content/>` | Main page content. | -| `<@resources/>` | Resources such as scripts and stylesheets. | -| `<@version/>` | Module version taken from configuration. If [versioning plugin](versioning.md) is applied, it will be replaced with version navigator. | +| **Variable** | **Description** | +|-----------------|----------------------------------------------------------------------------------------------------------------------------------------| +| `<@content/>` | Main page content. | +| `<@resources/>` | Resources such as scripts and stylesheets. | +| `<@version/>` | Module version taken from configuration. If [versioning plugin](versioning.md) is applied, it will be replaced with version navigator. | diff --git a/docs/topics/formats/markdown.md b/docs/topics/formats/markdown.md index edae3fed6a..42ed18cf64 100644 --- a/docs/topics/formats/markdown.md +++ b/docs/topics/formats/markdown.md @@ -10,7 +10,7 @@ These formats give you more freedom in terms of hosting documentation as the out documentation website. For example, see [OkHttp's API reference](https://square.github.io/okhttp/4.x/okhttp/okhttp3/) pages. -Markdown output formats are rendering [Dokka plugin](plugins_introduction.md), maintained by the Dokka team, and +Markdown output formats are rendering [Dokka plugins](plugins_introduction.md), maintained by the Dokka team, and they are open source. ## GFM diff --git a/docs/topics/overview.md b/docs/topics/overview.md index bbdd0c84ae..f88a9d884a 100644 --- a/docs/topics/overview.md +++ b/docs/topics/overview.md @@ -111,3 +111,8 @@ Learn more about Maven configuration in a separate [topic dedicated to Maven](ma + +## 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 itself, its plugins and how to develop them, and get in touch with maintainers. diff --git a/docs/topics/plugins/plugins_introduction.md b/docs/topics/plugins/plugins_introduction.md index af352cfa27..3b162e0c3e 100644 --- a/docs/topics/plugins/plugins_introduction.md +++ b/docs/topics/plugins/plugins_introduction.md @@ -17,12 +17,14 @@ Dokka plugins are published as separate artifacts, so to apply a Dokka plugin yo From there, the plugin will extend Dokka by itself - no extra actions 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. If you notice anything of that -> nature, it's a good idea to check which plugins are applied and what they do. +> 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 any problems of such nature, 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 [mathjax plugin](https://github.com/Kotlin/dokka/tree/master/plugins/mathjax) +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: @@ -125,7 +127,7 @@ If you are using [JSON configuration](cli.md#running-with-json-configuration), D ## Configuring Dokka plugins -Dokka plugins can also have configuration options of their own. Consult plugin's documentation to see which +Dokka plugins can also have configuration options of their own. Consult used plugin's documentation to see which options are available. Let's have a look at how you can configure `DokkaBase` plugin, which is responsible for generating [HTML](html.md) diff --git a/docs/topics/plugins/versioning.md b/docs/topics/plugins/versioning.md index 8148682474..9cdbeebfb3 100644 --- a/docs/topics/plugins/versioning.md +++ b/docs/topics/plugins/versioning.md @@ -9,9 +9,12 @@ with seamless switching between them. This, in turn, provides better experience > {type="note"} +Visit [versioning plugin example project](https://github.com/Kotlin/dokka/tree/1.7.20/examples/gradle/dokka-versioning-multimodule-example) +to see it in action as well as how it can be configured. + ## Applying the plugin -You can apply Versioning plugin the same way as other [Dokka plugins](plugins_introduction.md#applying-dokka-plugins): +You can apply the versioning plugin the same way as other [Dokka plugins](plugins_introduction.md#applying-dokka-plugins): @@ -100,13 +103,13 @@ Via [JSON configuration](cli.md#running-with-json-configuration): Versioning plugin has a number of optional configuration properties: -| **Property** | **Description** | -|--------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `version` | Version of your application/library for which documentation is going to be generated. This will be the version in the dropdown menu. | -| `versionsOrdering` | Optional list of strings that represents the order in which versions should appear in the dropdown. Must match version string exactly. First item of the list is the topmost in the dropdown. | -| `olderVersionsDir` | Optional path to a parent folder that contains other documentation versions. Requires a certain [directory structure](#directory-structure). | -| `olderVersions` | Optional list of paths to other documentation versions. Must point to Dokka's outputs directly. Useful if different versions are scattered and cannot be put into a single directory. | -| `renderVersionsNavigationOnAllPages` | Optional boolean indicating whether to render navigation dropdown on all pages. True by default. | +| **Property** | **Description** | +|--------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `version` | Version of your application/library for which documentation is going to be generated. This will be the version in the dropdown menu. | +| `versionsOrdering` | Optional list of strings that represents the order in which versions should appear in the dropdown menu. Must match versions string exactly. First item of the list is the topmost in the dropdown. | +| `olderVersionsDir` | Optional path to a parent folder that contains other documentation versions. Requires a certain [directory structure](#directory-structure). | +| `olderVersions` | Optional list of paths to other documentation versions. Must point to Dokka's outputs directly. Useful if different versions are scattered and cannot be put into a single directory. | +| `renderVersionsNavigationOnAllPages` | Optional boolean indicating whether to render navigation dropdown on all pages. True by default. | #### Directory structure @@ -267,15 +270,15 @@ can begin publishing versioned documentation right away. The main idea behind it is the following: -1. One directory will contains all versions of your documentation. For instance, `documentation/version/{version_string}`. +1. One directory will contain all versions of your documentation. For instance, `documentation/version/{doc_version}`. This is your archive, you will need to preserve it for future builds. 2. Output directory of all new builds will be set to that directory as well, under `documentation/version/{new_version}` 3. When new builds are executed, the plugin will look for previous versions of documentation in the archive directory. 4. Once new documentation has been generated, it needs to be **copied** to some place accessible by the user: GitHub pages, nginx static directories, and so on. It needs to be copied and not moved because Dokka will still need this version for future builds, otherwise there will be a gap in the archive. -5. Once it has been safely copied away, you can remove `older` directory from the archived version. This helps reduce - the overhead of each version bundling all previous versions as these files are effectively duplicate. +5. Once it has been safely copied away, you can remove `older` directory from the newly generated and archived version. + This helps reduce the overhead of each version bundling all previous versions, as these files are effectively duplicates. ```kotlin import org.jetbrains.dokka.versioning.VersioningPlugin diff --git a/docs/topics/runners/cli.md b/docs/topics/runners/cli.md index 556bdd8698..59999ee34f 100644 --- a/docs/topics/runners/cli.md +++ b/docs/topics/runners/cli.md @@ -70,7 +70,7 @@ java -jar dokka-cli-%dokkaVersion%.jar \ Executing the given example should generate documentation in [HTML](html.md) format. -See [all command line arguments](#command-line-arguments) for more details. +See [command line arguments](#command-line-arguments) for more configuration details. ### Running with JSON configuration @@ -88,7 +88,7 @@ At the very least, you would need the following configuration: "sourceSets": [ { "sourceSetID": { - "scopeId": "html", + "scopeId": "moduleName", "sourceSetName": "main" }, "sourceRoots": [ @@ -152,16 +152,585 @@ needed. For more information, see [Markdown](markdown.md) and [Javadoc](javadoc.md#geneatring-javadoc-documentation) topics. -## Configuration +## Command line arguments -### Command line arguments +You can see short descriptions for command line arguments by running: -TODO paste output of `-help` after correcting in-code descriptions. +```Bash +java -jar dokka-cli-%dokkaVersion%.jar -help +``` + +Summary: + +- `-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. +- `-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` -> Delay substitution of some elements. Used in incremental builds of + multimodule projects. +- `-noSuppressObviousFunctions` -> Whether to suppress obvious functions such as 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 configurations 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 nested `-sourceSet` configuration. +- `-loggingLevel` -> Logging level, possible values: `DEBUG, PROGRESS, INFO, WARN, ERROR`. +- `-help, -h` -> Usage info. + +#### Source set arguments + +You can also see short descriptions for nested `-sourceSet` configuration: -### JSON configuration +```Bash +java -jar dokka-cli-%dokkaVersion%.jar -sourceSet -help +``` -TODO add descriptions for each setting as a separate entry in a table -TODO add a link to Dokka's api reference, to DokkaConfiguration class +Summary: + +- `-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 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. +- `-includeNonPublic` -> Deprecated, use `documentedVisibilities`. + Possible values: `PUBLIC`, `PRIVATE`, `PROTECTED`, `INTERNAL`, `PACKAGE`. +- `-documentedVisibilities` -> Visibilities to be documented. Accepts multiple values separated by semicolons. +- `-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 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 configuration 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. +- `-help`, `-h` -> Usage info + +## JSON configuration + +Below you will find examples and detailed descriptions for each configuration section. You can also find an example +with [all configuration options](#complete-configuration) applied at once at the very bottom. + +### 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" + ] +} +``` + + + +

Display name used to refer to the module. Used for ToC, navigation, logging, etc.

+

Default is root.

+
+ +

Module version.

+

Default is empty.

+
+ +

Directory to which documentation will be generated, regardless of format.

+

Default is ./dokka

+
+ +

+ 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.

+
+ +

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.

    +
    + +

    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.

    +
    + +

    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. +

    +

    + Note: you can cache fetched files locally and provide them to + Dokka as local paths. See externalDocumentationLinks. +

    +

    Default is false.

    +
    + +

    + List of Markdown files that contain + module and package documentation. +

    +

    Contents of specified files will be parsed and embedded into documentation as module and package descriptions.

    +

    Can be configured on per-package basis.

    +
    + +

    + Individual and additional configuration of Kotlin + source sets. +

    +

    For a list of possible options, see source set configuration.

    +
    + +

    Global configuration of source links that will be applied for all source sets.

    +

    For a list of possible options, see source link configuration.

    +
    + +

    Global configuration of matched packages, regardless of the source set they are in.

    +

    For a list of possible options, see per-package configuration.

    +
    + +

    Global configuration of external documentation links, regardless of the source set they are used in.

    +

    For a list of possible options, see external documentation configuration.

    +
    + +

    List of jars with Dokka plugins and their dependencies.

    +
    +
    + +### Source set configuration + +Configuration of 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" } + ] + } + ] +} +``` + + + +

    Display name used to refer to the source set.

    +

    + The name will be used both externally (for example, as source set name visible to documentation readers) and + internally (for example, for logging messages of reportUndocumented). +

    +

    Platform name could be used if you don't have a better alternative.

    +
    + +

    Technical ID of the source set

    +
    + +

    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.

    +

    + Possible values: + +

  • PUBLIC
  • +
  • PRIVATE
  • +
  • PROTECTED
  • +
  • INTERNAL
  • +
  • PACKAGE
  • + +

    +

    Default is PUBLIC.

    +
    + +

    + 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

    +

    Default is false.

    +
    + +

    + 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 for CLI runner is false.

    +
    + +

    Whether to document declarations annotated with @Deprecated.

    +

    Can be overridden on package level.

    +

    Default is 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 for it. +

    +
    + +

    + Kotlin language version + used for setting up analysis and @sample + environment. +

    +
    + +

    + Kotlin API version + used for setting up analysis and @sample + environment. +

    +
    + +

    + 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.

    +
    + +

    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.

    +
    + +

    + List of Markdown files that contain + module and package documentation. +

    +

    Contents of specified files will be parsed and embedded into documentation as module and package descriptions.

    +
    + +

    + Platform to be used for setting up code analysis and + @sample environment. +

    +

    The default value is deduced from information provided by the Kotlin Gradle plugin.

    +

    + Possible values: + +

  • jvm
  • +
  • common
  • +
  • js
  • +
  • native
  • + +

    +
    + +

    + Source code roots to be analyzed and documented. + Accepts directories and individual .kt / .java files. +

    +
    + +

    + Classpath for analysis and interactive samples. If you use a declaration from a dependency, + it should be present on the classpath to be resolved. +

    +

    Property accepts both .jar and .klib files.

    +
    + +

    + List of directories or files that contain sample functions which are referenced via + @sample KDoc tag. +

    +
    + +

    Files to be suppressed when generating documentation.

    +
    + +

    Configuration of source links that will be applied only for this source set.

    +

    For a list of possible options, see source link configuration.

    +
    + +

    Configuration specific to matched packages within this source set.

    +

    For a list of possible options, see per-package configuration.

    +
    + +

    Configuration of external documentation links that will be applied only for this source set.

    +

    For a list of possible options, see external documentation configuration.

    +
    +
    + +### Source link configuration + +Configuration block 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. + +For an example, see documentation for +[count](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/count.html) +function from `kotlinx.coroutines`. + +Configurable for all source sets at once, or [for each source set individually](#source-set-configuration) + +```json +{ + "sourceLinks": [ + { + "localDirectory": "src/main/kotlin", + "remoteUrl": "https://github.com/Kotlin/dokka/tree/master/src/main/kotlin", + "remoteLineSuffix": "#L" + } + ] +} +``` + + + +

    Path to the local source directory.

    +
    + +

    + 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. +

    +
    + +

    + 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 empty (no suffix).

    +
    +
    + +### Per-package configuration + +Configuration block that allows setting some options for specific packages matched by `matchingRegex`. + +Configurable for all source sets at once, or [for each source set individually](#source-set-configuration) + +```json +{ + "perPackageOptions": [ + { + "matchingRegex": ".*internal.*", + "suppress": false, + "skipDeprecated": false, + "reportUndocumented": false, + "documentedVisibilities": ["PUBLIC", "PRIVATE", "PROTECTED", "INTERNAL", "PACKAGE"] + } + ] +} +``` + + + +

    Regular expression that is used to match the package.

    +
    + +

    Whether this package should be skipped when generating documentation.

    +

    Default is false.

    +
    + +

    Whether to document declarations annotated with @Deprecated.

    +

    Can be set on project/module level.

    +

    Default is false.

    +
    + +

    + 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 failOnWarning.

    +

    Can be configured on source set level.

    +

    Default is false.

    +
    + +

    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 on source set level.

    +

    Default is PUBLIC.

    +
    +
    + +### External documentation configuration + +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 links for used types, making them clickable +and appear resolved. + +Configurable for all source sets at once, or [for each source set individually](#source-set-configuration) + +```json +{ + "externalDocumentationLinks": [ + { + "url": "https://kotlinlang.org/api/kotlinx.serialization/", + "packageListUrl": "https://kotlinlang.org/api/kotlinx.serialization/package-list" + } + ] +} +``` + + + +

    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. +

    +

    + If automatic resolution fails or if you want to use locally cached files instead, + consider providing packageListUrl. +

    +
    + +

    + 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. +

    +
    +
    + +### Complete configuration + +Below you can see all possible configuration options applied at once. ```json { @@ -202,7 +771,7 @@ TODO add a link to Dokka's api reference, to DokkaConfiguration class { "displayName": "jvm", "sourceSetID": { - "scopeId": "html", + "scopeId": "moduleName", "sourceSetName": "main" }, "dependentSourceSets": [ @@ -282,7 +851,6 @@ TODO add a link to Dokka's api reference, to DokkaConfiguration class ], "includes": [ "module.md" - ], - "finalizeCoroutines": true + ] } ``` diff --git a/docs/topics/runners/gradle.md b/docs/topics/runners/gradle.md index 08729be8a8..78b2b75943 100644 --- a/docs/topics/runners/gradle.md +++ b/docs/topics/runners/gradle.md @@ -2,10 +2,13 @@ To generate documentation for a Gradle-based project, you can use [Dokka Gradle plugin](#applying-the-plugin). -It comes with basic autoconfiguration (including multimodule and multiplatform projects), has convenient +It comes with basic autoconfiguration (including multi-project and multiplatform builds), has convenient [Gradle tasks](#generating-documentation) for generating documentation, and provides a great deal of [configuration options](#configuration) to customize output. +You can play around with Dokka and see how it can be configured for various projects by visiting +[Gradle example projects](https://github.com/Kotlin/dokka/tree/%dokkaVersion%/examples/gradle). + ## Applying the plugin The recommended way of applying the plugin is via @@ -32,31 +35,57 @@ plugins {
    -> Under the hood, Dokka uses [Kotlin Gradle plugin](https://kotlinlang.org/docs/gradle.html) to perform autoconfiguration +When documenting [multi-project](gradle.md#multi-project-builds) builds, you need to apply Dokka in subprojects as well. +You can use `allprojects {}` and `subprojects {}` Gradle configurations to achieve that: + + + + +```kotlin +subprojects { + apply(plugin = "org.jetbrains.dokka") +} +``` + + + + +```groovy +subprojects { + apply plugin: 'org.jetbrains.dokka' +} +``` + + + + +> Under the hood, Dokka uses [Kotlin Gradle plugin](https://kotlinlang.org/docs/gradle.html) to perform +> autoconfiguration > of [source sets](https://kotlinlang.org/docs/multiplatform-discover-project.html#source-sets) for which documentation -> should be generated, so make sure Kotlin Gradle Plugin is applied as well, or configure source sets manually. +> should be generated, so make sure Kotlin Gradle Plugin is applied as well, or +> [configure source sets](#source-set-configuration) manually. > -{type="note"} +{type="note"} -> If you are using Dokka in a -> [precompiled script plugin](https://docs.gradle.org/current/userguide/custom_plugins.html#sec:precompiled_plugins), +> If you are using Dokka in a +> [precompiled script plugin](https://docs.gradle.org/current/userguide/custom_plugins.html#sec:precompiled_plugins), > you will have to add [Kotlin Gradle plugin](https://kotlinlang.org/docs/gradle.html) as a dependency in order for > it to work properly: > > > -> +> > ```kotlin > implementation(kotlin("gradle-plugin", "%kotlinVersion%")) > ``` -> +> > > -> +> > ```groovy > implementation 'org.jetbrains.kotlin:kotlin-gradle-plugin:%kotlinVersion%' > ``` -> +> > > > @@ -69,7 +98,8 @@ plugins. ## Generating documentation Dokka's Gradle plugin comes with [HTML](html.md), [Markdown](markdown.md) and [Javadoc](javadoc.md) formats built in, -and adds a number of tasks for generating documentation, both for [single](#single-project-builds) and [multi-project](#multi-project-builds) builds. +and adds a number of tasks for generating documentation, both for [single](#single-project-builds) +and [multi-project](#multi-project-builds) builds. ### Single project builds @@ -94,31 +124,8 @@ Output location, among other things, can be [configured](#configuration) separat ### Multi-project builds -For documenting [multi-project builds](https://docs.gradle.org/current/userguide/multi_project_builds.html), you need -to apply the Dokka plugin in subprojects that you want to generate documentation for as well as in their parent project. - -You can use `allprojects {}` and `subprojects {}` Gradle configurations to achieve that: - - - - -```kotlin -subprojects { - apply(plugin = "org.jetbrains.dokka") -} -``` - - - - -```groovy -subprojects { - apply plugin: 'org.jetbrains.dokka' -} -``` - - - +For documenting [multi-project builds](https://docs.gradle.org/current/userguide/multi_project_builds.html), make sure +you apply the Dokka plugin in subprojects that you want to generate documentation for, as well as in their parent project. #### MultiModule tasks @@ -172,28 +179,29 @@ for more details. #### Partial tasks Each subproject will have _partial_ tasks created for it: `dokkaHtmlPartial`,`dokkaGfmPartial`, -and `dokkaJekyllPartial`. +and `dokkaJekyllPartial`. -These tasks are not intended to be used independently and exist only to be called by the parent's MultiModule task. +These tasks are not intended to be used independently and exist only to be called by the parent's +[MultiModule](#multimodule-tasks) task. Output generated by partial tasks contains non-displayable formatting along with unresolved templates and references. -> If you want to generate documentation for a single subproject only, use +> If you want to generate documentation for a single subproject only, use > [single project tasks](#single-project-builds). For instance, `:subproject:dokkaHtml`. #### Collector tasks -Similar to MultiModule tasks, _Collector_ tasks will be created for each parent project: `dokkaHtmlCollector`, +Similar to MultiModule tasks, _Collector_ tasks will be created for each parent project: `dokkaHtmlCollector`, `dokkaGfmCollector`, `dokkaJavadocCollector` and `dokkaJekyllCollector`. A Collector task executes corresponding [single project task](#single-project-builds) for each subproject (for example, -`dokkaHtml`), and merges all outputs into a single virtual project. +`dokkaHtml`), and merges all outputs into a single virtual project. Resulting documentation will look as if you have a single project build that contains all declarations from the subprojects. > Use `dokkaJavadocCollector` task if you need to create Javadoc documentation for your multi-project build. -> +> {type="tip"} #### Collector results @@ -219,8 +227,9 @@ for more details. ## Building javadoc.jar -In order to publish your library to a repository, you may need to provide a `javadoc.jar` file that contains API reference -documentation. +In order to publish your library to a repository, you may need to provide a `javadoc.jar` file that contains API +reference +documentation. Dokka's Gradle plugin 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](html.md) format and another one for [Javadoc](javadoc.md) format: @@ -262,16 +271,16 @@ tasks.register('dokkaJavadocJar', Jar.class) {
    -> If you publish your library to Maven Central, you can use services like [javadoc.io](https://javadoc.io/) to +> If you publish your library to Maven Central, you can use services like [javadoc.io](https://javadoc.io/) to > host of your library's API documentation for free and without any setup - it will take documentation pages straight -> from the artifact. It works with both HTML and Javadoc formats as demonstrated by +> from the artifact. It works with both HTML and Javadoc formats as demonstrated by > [this example](https://javadoc.io/doc/com.trib3/server/latest/index.html). -> +> {type="tip"} ## Configuration -You can configure tasks/formats individually +You can configure tasks/formats individually: @@ -292,16 +301,6 @@ tasks.dokkaHtmlPartial { } ``` -If you applied Dokka with the [buildscript block](https://docs.gradle.org/current/userguide/plugins.html#sec:old_plugin_application): - -```kotlin -import org.jetbrains.dokka.gradle.DokkaTask - -tasks.named("dokkaHtml") { - outputDirectory.set(buildDir.resolve("documentation/html")) -} -``` - @@ -323,8 +322,8 @@ dokkaHtmlPartial { -Alternatively, you can configure all tasks/formats at once, including [MultiModule](#multi-project-builds), -[Partial](#partial-tasks) and [Collector](#collector-tasks) tasks as well. This is often the simplest solution. +Alternatively, you can configure all tasks/formats at once, including [MultiModule](#multi-project-builds), +[Partial](#partial-tasks) and [Collector](#collector-tasks) tasks: @@ -334,7 +333,8 @@ import org.jetbrains.dokka.gradle.DokkaTask import org.jetbrains.dokka.gradle.DokkaTaskPartial import org.jetbrains.dokka.DokkaConfiguration.Visibility -// configure all dokka tasks, including multimodule, partial and collector +// configure all dokka tasks, including multimodule, +// partial and collector ones tasks.withType().configureEach { dokkaSourceSets.configureEach { documentedVisibilities.set( @@ -367,7 +367,8 @@ tasks.withType(DokkaTaskPartial::class).configureEach { import org.jetbrains.dokka.gradle.DokkaTask import org.jetbrains.dokka.gradle.DokkaTaskPartial -// configure all dokka tasks, including multimodule, partial and collector +// configure all dokka tasks, including multimodule, +// partial and collector ones tasks.withType(DokkaTask.class) { dokkaSourceSets.configureEach { documentedVisibilities.set([ @@ -394,9 +395,667 @@ tasks.withType(DokkaTaskPartial.class) { -### Full configuration +## Configuration options + +Dokka has many configuration options to tailor your and your reader's experience. + +Below you will find examples and descriptions for each configuration section. You can also find an example with +[all configuration options](#complete-configuration) applied at once at the very bottom. + +### General configuration + +General configuration of any Dokka task, regardless of source set and package: + + + + +```kotlin +import org.jetbrains.dokka.gradle.DokkaTask + +tasks.withType().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 + // .. +} +``` + + + + +```groovy +import org.jetbrains.dokka.gradle.DokkaTask + +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 + // .. +} +``` + + + + + + +

    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.

    +
    + +

    + 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.

    +
    + +

    Directory to which documentation will be generated, regardless of format. Can be set on per-task basis.

    +

    + Default is project/buildDir/format, where format is the task name with + removed "dokka" prefix. For task dokkaHtmlMultiModule it will be + project/buildDir/htmlMultiModule +

    +
    + +

    + 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.

    +
    + +

    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.

    +
    + +

    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.

    +
    + +

    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. +

    +

    + Note: you can cache fetched files locally and provide them to + Dokka as local paths. See externalDocumentationLinks section. +

    +

    Default is false.

    +
    +
    + +### Source set configuration + +Configuration of Kotlin [source sets](https://kotlinlang.org/docs/multiplatform-discover-project.html#source-sets). + + + + +```kotlin +import org.jetbrains.dokka.DokkaConfiguration.Visibility +import org.jetbrains.dokka.gradle.DokkaTask +import org.jetbrains.dokka.Platform +import java.net.URL + +tasks.withType().configureEach { + // .. + // general configuration section + // .. + + 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 + } + } +} +``` + + + + +```groovy +import org.jetbrains.dokka.DokkaConfiguration.Visibility +import org.jetbrains.dokka.gradle.DokkaTask +import org.jetbrains.dokka.Platform +import java.net.URL + +tasks.withType(DokkaTask.class) { + // .. + // general configuration section + // .. + + 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 + } + } +} +``` + + + + + + +

    Whether this source set should be skipped when generating documentation.

    +

    Default is false.

    +
    + +

    Display name used to refer to the source set.

    +

    + The name will be used both externally (for example, as 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.

    +
    + +

    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.

    +

    Default is DokkaConfiguration.Visibility.PUBLIC.

    +
    + +

    + 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.

    +

    Default is false.

    +
    + +

    + 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.

    +
    + +

    Whether to document declarations annotated with @Deprecated.

    +

    Can be overridden on package level.

    +

    Default is false.

    +
    + +

    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 option, so you can configure it manually. +

    +

    Default is true.

    +
    + +

    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 for it. +

    +

    Default is JDK 8.

    +
    + +

    + Kotlin language version + used for setting up analysis and @sample + environment. +

    +

    By default, the latest language version available to Dokka's embedded compiler will be used.

    +
    + +

    + Kotlin API version + used for setting up analysis and @sample + environment. +

    +

    By default, it will be deduced from languageVersion.

    +
    + +

    + 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.

    +
    + +

    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.

    +
    + +

    + 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.

    +
    + +

    + List of Markdown files that contain + module and package documentation. +

    +

    Contents of specified files will be parsed and embedded into documentation as module and package descriptions.

    +

    + See Dokka gradle example + for an example of how to use it and what it will look like. +

    +
    + +

    + Platform to be used for setting up code analysis and + @sample environment. +

    +

    The default value is deduced from information provided by the Kotlin Gradle plugin.

    +
    + +

    + Source code roots to be analyzed and documented. + Accepts directories and individual .kt / .java files. +

    +

    By default, source roots are deduced from information provided by the Kotlin Gradle plugin.

    +
    + +

    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.

    +
    + +

    + List of directories or files that contain sample functions which are referenced via + @sample KDoc tag. +

    +
    +
    + +### Source link configuration + +Configuration block 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. + +For an example, see documentation for +[count](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/count.html) +function from `kotlinx.coroutines`. + + + + +```kotlin +import org.jetbrains.dokka.gradle.DokkaTask +import java.net.URL + +tasks.withType().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/main/kotlin")) + remoteLineSuffix.set("#L") + } + } +} +``` + + + + +```groovy +import org.jetbrains.dokka.gradle.DokkaTask +import java.net.URL + +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/main/kotlin")) + remoteLineSuffix.set("#L") + } + } +} +``` + + + + + + +

    + Path to the local source directory. The path must be relative to the root of + current project. +

    +
    + +

    + 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. +

    +
    + +

    + 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.

    +
    +
    + +### Package options + +Configuration block that allows setting some options for specific packages matched by `matchingRegex`. + + + + +```kotlin +import org.jetbrains.dokka.DokkaConfiguration.Visibility +import org.jetbrains.dokka.gradle.DokkaTask + +tasks.withType().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)) + } + } +} +``` + + + + +```groovy +import org.jetbrains.dokka.DokkaConfiguration.Visibility +import org.jetbrains.dokka.gradle.DokkaTask + +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]) + } + } +} +``` + + + + + + +

    Regular expression that is used to match the package.

    +

    Default is any string: .*.

    +
    + +

    Whether this package should be skipped when generating documentation.

    +

    Default is false.

    +
    + +

    Whether to document declarations annotated with @Deprecated.

    +

    Can be configured on source set level.

    +

    Default is false.

    +
    + +

    + 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 failOnWarning.

    +

    Can be configured on source set level.

    +

    Default is false.

    +
    + +

    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 on source set level.

    +

    Default is DokkaConfiguration.Visibility.PUBLIC.

    +
    +
    + +### External documentation links configuration + +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 links for used types, making them clickable +and appear resolved. + + + + +```kotlin +import org.jetbrains.dokka.gradle.DokkaTask +import java.net.URL + +tasks.withType().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() + ) + } + } +} +``` + + + + +```groovy +import org.jetbrains.dokka.gradle.DokkaTask +import java.net.URL + +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() + ) + } + } +} +``` + + + -TODO add descriptions for each setting as a separate entry in a table + + +

    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. +

    +

    + If automatic resolution fails or if you want to use locally cached files instead, + consider providing packageListUrl. +

    +
    + +

    + 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. +

    +
    +
    + +### Complete configuration + +Below you can see all possible configuration options applied at once. diff --git a/docs/topics/runners/maven.md b/docs/topics/runners/maven.md index c578ebb310..a571090c19 100644 --- a/docs/topics/runners/maven.md +++ b/docs/topics/runners/maven.md @@ -7,6 +7,9 @@ To generate documentation for Maven-based projects, you can use [Dokka Maven plu > {type="note"} +You can play around with Dokka and see how it can be configured for a Maven project by visiting +[Maven example](https://github.com/Kotlin/dokka/tree/%dokkaVersion%/examples/maven) project. + ## Applying the plugin To apply the plugin, you need to add it to the plugins section of your POM: @@ -81,7 +84,7 @@ You can learn more about Dokka plugins in [a separate topic](plugins_introductio ## Building javadoc.jar -Unlike [Gradle plugin](gradle.md#building-javadoc-jar), Maven plugin comes with ready-to-use `dokka:javadocJar` goal. +Unlike the [Gradle plugin](gradle.md#building-javadoc-jar), Maven plugin comes with ready-to-use `dokka:javadocJar` goal. By default, it will generate documentation in [Javadoc](javadoc.md) format under `target` folder. If you are not satisfied with the built-in goal or want to customize the output (for instance, you want to generate @@ -115,7 +118,7 @@ Maven jar plugin with the following configuration: ``` -The documentation and the archive for it can then be generated by running `dokka:dokka` and `jar:jar@dokka-jar` goals: +The documentation and the `.jar` archive for it can then be generated by running `dokka:dokka` and `jar:jar@dokka-jar` goals: ```Bash mvn dokka:dokka jar:jar@dokka-jar @@ -125,8 +128,7 @@ mvn dokka:dokka jar:jar@dokka-jar Maven's plugin configuration block can be used to configure Dokka. -Below you will find basic configuration that only changes output location of documentation. See -[all configuration elements](#all-configuration-elements) section to find out what else is possible. +Example of basic configuration that only changes output location of documentation: ```xml @@ -139,15 +141,20 @@ Below you will find basic configuration that only changes output location of doc ``` -### All configuration elements +## Configuration options + +Dokka has many configuration options to tailor your experience. -TODO add descriptions for each setting as a separate entry in a table +Below you will find examples and descriptions for each configuration section. You can also find an example with +[all configuration options](#complete-configuration) applied at once at the very bottom. + +### General configuration ```xml org.jetbrains.dokka dokka-maven-plugin - ... + false ${project.artifactId} @@ -156,12 +163,400 @@ TODO add descriptions for each setting as a separate entry in a table true false false + + ${project.basedir}/src/main/kotlin + + + PUBLIC + PROTECTED + + false + false + true + + /path/to/dir + /path/to/file + + 8 + 1.7 + 1.7 + false + false + + packages.md + extra.md + + ${project.compileClasspathElements} + + ${project.basedir}/samples + + + + + + + + + + + + +``` + + + +

    Whether to skip documentation generation.

    +

    Default is false.

    +
    + +

    Display name used to refer to the project/module. Used for ToC, navigation, logging, etc.

    +

    Default is {project.artifactId}.

    +
    + +

    Directory to which documentation will be generated.

    +

    Default is {project.basedir}/target/dokka.

    +
    + +

    + 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.

    +
    + +

    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

    +
    + +

    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.

    +
    + +

    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, see externalDocumentationLinks section. +

    +

    Default is false.

    +
    + +

    + Source code roots to be analyzed and documented. + Accepts directories and individual .kt / .java files. +

    +

    Default is {project.compileSourceRoots}.

    +
    + +

    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.

    +

    Default is PUBLIC.

    +
    + +

    + 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 on package level.

    +

    Default is false.

    +
    + +

    Whether to document declarations annotated with @Deprecated.

    +

    Can be overridden on package level.

    +

    Default is false.

    +
    + +

    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.

    +
    + +

    + Directories or individual files that should be suppressed, meaning declarations from them + will be not documented. +

    +
    + +

    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 for it. +

    +

    Default is JDK 8.

    +
    + +

    + Kotlin language version + used for setting up analysis and @sample + environment. +

    +

    By default, the latest language version available to Dokka's embedded compiler will be used.

    +
    + +

    + Kotlin API version + used for setting up analysis and @sample + environment. +

    +

    By default, it will be deduced from languageVersion.

    +
    + +

    + 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.

    +
    + +

    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.

    +
    + +

    + List of Markdown files that contain + module and package documentation +

    +

    Contents of specified files will be parsed and embedded into documentation as module and package descriptions.

    +
    + +

    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}.

    +
    + +

    + List of directories or files that contain sample functions which are referenced via + @sample KDoc tag. +

    +
    +
    + +### Source link configuration + +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. + +For an example, see documentation for +[count](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/count.html) +function from `kotlinx.coroutines`. - JVM +```xml + + org.jetbrains.dokka + dokka-maven-plugin + + + + + ${project.basedir}/src/main/kotlin + https://github.com/kotlin/dokka/tree/master/src/main/kotlin + #L + + + + +``` + + + +

    + Path to the local source directory. The path must be relative to the root of + current module. +

    +
    + +

    + 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. +

    +
    + +

    + 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-
  • + +

    +
    +
    + +#### External documentation links configuration + +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 links for used types, making them clickable +and appear resolved. + +```xml + + org.jetbrains.dokka + dokka-maven-plugin + + + + + https://kotlinlang.org/api/kotlinx.serialization/ + file:/${project.basedir}/serialization.package.list + + + + +``` + + + +

    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. +

    +
    + +

    + 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. +

    +
    +
    + +### Package options + +Configuration block that allows setting some options for specific packages matched by `matchingRegex`. + +```xml + + org.jetbrains.dokka + dokka-maven-plugin + + + + + .*api.* + false + false + false + + PUBLIC + PRIVATE + PROTECTED + INTERNAL + PACKAGE + + + + + +``` + + + +

    Regular expression that is used to match the package.

    +

    Default is any string: .*.

    +
    + +

    Whether this package should be skipped when generating documentation.

    +

    Default is false.

    +
    + +

    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 PUBLIC.

    +
    + +

    Whether to document declarations annotated with @Deprecated.

    +

    Can be set on project/module level.

    +

    Default is false.

    +
    + +

    + 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 failOnWarning.

    +

    Default is false.

    +
    +
    + +### Complete configuration + +Below you can see all possible configuration options applied at once. + +```xml + + org.jetbrains.dokka + dokka-maven-plugin + + + false + ${project.artifactId} + ${project.basedir}/target/documentation + false + true + false + false ${project.basedir}/src/main/kotlin - JVM PUBLIC PRIVATE @@ -185,13 +580,6 @@ TODO add descriptions for each setting as a separate entry in a table packages.md extra.md - JVM - - - src/main/kotlin - JVM - - ${project.compileClasspathElements} ${project.basedir}/samples diff --git a/runners/cli/api/cli.api b/runners/cli/api/cli.api index cdd051ccbe..74769272a2 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 ([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 0000000000..f52f72fd0c --- /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(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(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(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(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(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: =[#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) : + ArgType(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) : ArgType(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 0000000000..2bda8d79eb --- /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) : 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 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 = emptyList() + + val logger: DokkaLogger by lazy { + DokkaConsoleLogger(loggingLevel) + } + + init { + parser.parse(args) + + sourceSets.forEach { + it.perPackageOptions.cast>() + .addAll(parsePerPackageOptions(globalPackageOptions)) + } + + sourceSets.forEach { + it.externalDocumentationLinks.cast>().addAll(parseLinks(globalLinks)) + } + + globalSrcLink.forEach { + if (it.isNotEmpty() && it.contains("=")) + sourceSets.all { sourceSet -> + sourceSet.sourceLinks.cast>() + .add(SourceLinkDefinitionImpl.parseSourceLinkDefinition(it)) + } + else { + logger.warn("Invalid -srcLink syntax. Expected: =[#lineSuffix]. No source links will be generated.") + } + } + + sourceSets.forEach { + it.externalDocumentationLinks.cast>().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 0000000000..191d5067f4 --- /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 = + buildList { + if (!config.noJdkLink) { + add(DokkaConfiguration.ExternalDocumentationLink.jdk(config.jdkVersion)) + } + + if (!config.noStdlibLink) { + add(DokkaConfiguration.ExternalDocumentationLink.kotlinStdlib()) + } + }.toMutableList() + + +fun parseLinks(links: List): List { + 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 0000000000..1b9a3c5698 --- /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): List = 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 0000000000..49e8f2ae05 --- /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): 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 = 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 aca57f7ede..99813f62de 100644 --- a/runners/cli/src/main/kotlin/org/jetbrains/dokka/main.kt +++ b/runners/cli/src/main/kotlin/org/jetbrains/dokka/main.kt @@ -1,413 +1,17 @@ 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) : 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 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 = emptyList() - - val logger: DokkaLogger by lazy { - DokkaConsoleLogger(loggingLevel) - } - - init { - parser.parse(args) - - sourceSets.forEach { - it.perPackageOptions.cast>() - .addAll(parsePerPackageOptions(globalPackageOptions)) - } - - sourceSets.forEach { - it.externalDocumentationLinks.cast>().addAll(parseLinks(globalLinks)) - } - - globalSrcLink.forEach { - if (it.isNotEmpty() && it.contains("=")) - sourceSets.all { sourceSet -> - sourceSet.sourceLinks.cast>() - .add(SourceLinkDefinitionImpl.parseSourceLinkDefinition(it)) - } - else { - logger.warn("Invalid -srcLink syntax. Expected: =[#lineSuffix]. No source links will be generated.") - } - } - - sourceSets.forEach { - it.externalDocumentationLinks.cast>().addAll(defaultLinks(it)) - } - } -} - -private fun parseSourceSet(moduleName: String, args: Array): 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 = documentedVisibilities.toSet() - .ifEmpty { DokkaDefaults.documentedVisibilities } - } -} - -object ArgTypeFile : ArgType(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(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(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(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(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: =[#lineSuffix]. No source links will be generated.") - } - - override val description: kotlin.String - get() = "{ String that represent source links }" -} - -data class ArgTypeArgument(val moduleName: CLIEntity) : - ArgType(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) : ArgType(false) { - override fun convert(value: kotlin.String, name: kotlin.String): Any = Any().also { - parseSourceSet(moduleName.value, arrayOf("-h")) - } - - override val description: kotlin.String - get() = "" -} - -@OptIn(ExperimentalStdlibApi::class) -fun defaultLinks(config: DokkaConfiguration.DokkaSourceSet): MutableList = - buildList { - if (!config.noJdkLink) { - add(ExternalDocumentationLink.jdk(config.jdkVersion)) - } - - if (!config.noStdlibLink) { - add(ExternalDocumentationLink.kotlinStdlib()) - } - }.toMutableList() - - -fun parseLinks(links: List): List { - 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) - } +fun main(args: Array) { + val globalArguments = GlobalArguments(args) + val configuration = initializeConfiguration(globalArguments) + DokkaGenerator(configuration, globalArguments.logger).generate() } -fun initializeConfiguration(globalArguments: GlobalArguments): DokkaConfiguration = if (globalArguments.json != null) { +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) @@ -420,10 +24,5 @@ fun initializeConfiguration(globalArguments: GlobalArguments): DokkaConfiguratio } else { globalArguments } - -fun main(args: Array) { - 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 a654f9d56e..7cf7fab621 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 = project.objects.safeProperty() .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 = project.objects.safeProperty() .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 = project.objects.safeProperty() .safeConvention(defaultDokkaOutputDirectory()) - @Optional - @InputDirectory - @PathSensitive(PathSensitivity.RELATIVE) - val cacheRoot: Property = 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 = 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 = project.objects.safeProperty() - .safeConvention(DokkaDefaults.failOnWarning) + val pluginsMapConfiguration: MapProperty = 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 = project.objects.safeProperty() .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 = project.objects.safeProperty() .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 = project.objects.safeProperty() .safeConvention(DokkaDefaults.offlineMode) - @Input - val pluginsConfiguration: ListProperty = 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 = project.objects.mapProperty() + val failOnWarning: Property = project.objects.safeProperty() + .safeConvention(DokkaDefaults.failOnWarning) + @Optional + @InputDirectory + @PathSensitive(PathSensitivity.RELATIVE) + val cacheRoot: Property = 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 { + * footerMessage = "Test" + * } + * } + * ``` + * + * @param P Plugin class that extends [DokkaPlugin] + * @param T Plugin configuration class that extends [ConfigurableBlock] + */ inline fun 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 76213f14eb..c930bc5048 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 similarity index 100% rename from runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/toDokkaSourceSetImpl.kt rename to 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 717527d205..6390336ac0 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 = project.objects.safeProperty() .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 = 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 = project.objects.setProperty() + .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 = project.objects.setProperty() .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 = project.objects.safeProperty() - .safeConvention(DokkaDefaults.includeNonPublic) - - @Input - val documentedVisibilities: SetProperty = project.objects.setProperty() - .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 = project.objects.safeProperty() .safeConvention(DokkaDefaults.reportUndocumented) - @Input - val skipEmptyPackages: Property = project.objects.safeProperty() - .safeConvention(DokkaDefaults.skipEmptyPackages) - - @Input - val skipDeprecated: Property = project.objects.safeProperty() - .safeConvention(DokkaDefaults.skipDeprecated) - - @Input - val suppressGeneratedFiles: Property = project.objects.safeProperty() - .safeConvention(true) - - @Input - val jdkVersion: Property = project.objects.safeProperty() - .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 = project.objects.setProperty() .convention(emptySet()) + /** + * Allows to customize documentation generation options on a per-package basis. + * + * @see GradlePackageOptionsBuilder for details + */ @Nested val perPackageOptions: ListProperty = project.objects.listProperty() .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 = project.objects.setProperty() .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 = project.objects.safeProperty() + val platform: Property = project.objects.safeProperty() + .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 = project.objects.safeProperty() + val skipEmptyPackages: Property = project.objects.safeProperty() + .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 = project.objects.safeProperty() + .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 = project.objects.safeProperty() + .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 = project.objects.safeProperty() .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 = project.objects.safeProperty() .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 = project.objects.safeProperty() - .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 = 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 = project.objects.safeProperty() - .safeConvention(Platform.DEFAULT) + val apiVersion: Property = 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 = project.objects.safeProperty() + .safeConvention(DokkaDefaults.jdkVersion) + + /** + * Deprecated. Use [documentedVisibilities] instead. + */ + @Input + val includeNonPublic: Property = project.objects.safeProperty() + .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) { 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) { 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) { 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) { 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) { 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) { 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 c5c7428f28..5c7c523b93 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 19d150c338..36e4f81d31 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 { + + /** + * 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 = 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 = 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 f15a6462ac..4e53cf8117 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 { + + /** + * Regular expression that is used to match the package. + * + * Default is any string: `.*`. + */ @Input val matchingRegex: Property = project.objects.safeProperty() .safeConvention(".*") + /** + * Whether this package should be skipped when generating documentation. + * + * Default is `false`. + */ @Input - val includeNonPublic: Property = project.objects.safeProperty() - .safeConvention(DokkaDefaults.includeNonPublic) + val suppress: Property = project.objects.safeProperty() + .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 = project.objects.setProperty() .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 = project.objects.safeProperty() + .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 = project.objects.safeProperty() .safeConvention(DokkaDefaults.reportUndocumented) + /** + * Deprecated. Use [documentedVisibilities] instead. + */ @Input - val skipDeprecated: Property = project.objects.safeProperty() - .safeConvention(DokkaDefaults.skipDeprecated) + val includeNonPublic: Property = project.objects.safeProperty() + .safeConvention(DokkaDefaults.includeNonPublic) - @Input - val suppress: Property = project.objects.safeProperty() - .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 2ddd8056d5..8e118767b2 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/main/kotlin")) + * remoteLineSuffix.set("#L") + * } + * ``` + */ class GradleSourceLinkBuilder( @Transient @get:Internal internal val project: Project ) : DokkaConfigurationBuilder { + /** + * 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 = 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/main/kotlin")) + * ``` + */ @Input val remoteUrl: Property = 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 = project.objects.safeProperty() diff --git a/runners/maven-plugin/api/maven-plugin.api b/runners/maven-plugin/api/maven-plugin.api index 3b4ace568f..28d96bd3b6 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 ()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 ()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 ()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 ()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 581d4c9e61..92ab97548f 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) : AbstractMojo() { @Parameter(defaultValue = "\${project}", readonly = true, required = true) @@ -64,118 +42,303 @@ abstract class AbstractDokkaMojo(private val defaultDokkaPlugins: List = 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 = 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 = 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 = 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 = 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 = 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 = emptyList() + /** + * Allows linking to Dokka/Javadoc documentation of the project's dependencies. + * + * @see ExternalDocumentationLinkBuilder for details + */ @Parameter var externalDocumentationLinks: List = 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 = 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 = 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 + * + * + * org.jetbrains.dokka + * gfm-plugin + * 1.7.20 + * + * + * ``` + */ @Parameter var dokkaPlugins: List = 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 + * + * https://kotlinlang.org/api/latest/jvm/stdlib/ + * file:/${project.basedir}/stdlib.package.list + * + * + * ``` + */ +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 + * https://kotlinlang.org/api/latest/jvm/stdlib/ + * ``` + */ + @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 + * file:/${project.basedir}/stdlib.package.list + * ``` + */ + @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 0000000000..af67876956 --- /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 + * + * + * + * .*api.* + * false + * false + * false + * + * PUBLIC + * PROTECTED + * + * + * + * + * ``` + */ +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 = 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 0000000000..bd6d3baee5 --- /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 + * + * + * ${project.basedir}/src/main/kotlin + * https://github.com/kotlin/dokka/tree/master/src/main/kotlin + * #L + * + * + * ``` + */ +class SourceLinkMapItem { + + /** + * Path to the local source directory. The path must be relative to the root of current project. + * + * Example: + * + * ```xml + * ${project.basedir}/src/main/kotlin + * ``` + */ + @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 + * https://github.com/username/projectname/tree/master/src/main/kotlin + * ``` + */ + @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 +}