aboutsummaryrefslogtreecommitdiff
path: root/runners/cli/src/main
diff options
context:
space:
mode:
authorAndrzej Ratajczak <andrzej.ratajczak98@gmail.com>2020-05-12 15:19:53 +0200
committerKamil Doległo <9080183+kamildoleglo@users.noreply.github.com>2020-06-16 11:42:11 +0200
commit9637ec0747815181d56fa53419d4f6c56705752b (patch)
tree8d5c151b13322224c1053c9710273be2cf9760bd /runners/cli/src/main
parentd20cad929c4c095fbc8a94e4d41938fa3fc39a0c (diff)
downloaddokka-9637ec0747815181d56fa53419d4f6c56705752b.tar.gz
dokka-9637ec0747815181d56fa53419d4f6c56705752b.tar.bz2
dokka-9637ec0747815181d56fa53419d4f6c56705752b.zip
Refactor CLI
Diffstat (limited to 'runners/cli/src/main')
-rw-r--r--runners/cli/src/main/kotlin/cli/DokkaArgumentsParser.kt185
-rw-r--r--runners/cli/src/main/kotlin/cli/main.kt584
2 files changed, 300 insertions, 469 deletions
diff --git a/runners/cli/src/main/kotlin/cli/DokkaArgumentsParser.kt b/runners/cli/src/main/kotlin/cli/DokkaArgumentsParser.kt
deleted file mode 100644
index 5d795da7..00000000
--- a/runners/cli/src/main/kotlin/cli/DokkaArgumentsParser.kt
+++ /dev/null
@@ -1,185 +0,0 @@
-package org.jetbrains.dokka
-
-import kotlinx.cli.*
-import kotlin.reflect.KProperty
-
-class ParseContext(val cli: CommandLineInterface = CommandLineInterface("dokka")) {
- private val transformActions = mutableMapOf<KProperty<*>, (String) -> Unit>()
- private val flagActions = mutableMapOf<KProperty<*>, () -> Unit>()
-
- fun registerFlagAction(
- keys: List<String>,
- help: String,
- property: KProperty<*>,
- invoke: () -> Unit
- ) {
- if (property !in flagActions.keys) {
- cli.flagAction(keys, help) {
- flagActions[property]!!()
- }
- }
- flagActions[property] = invoke
-
- }
-
- fun registerSingleOption(
- keys: List<String>,
- help: String,
- property: KProperty<*>,
- invoke: (String) -> Unit
- ) {
- if (property !in transformActions.keys) {
- cli.singleAction(keys, help) {
- transformActions[property]!!(it)
- }
- }
- transformActions[property] = invoke
- }
-
- fun registerRepeatableOption(
- keys: List<String>,
- help: String,
- property: KProperty<*>,
- invoke: (String) -> Unit
- ) {
- if (property !in transformActions.keys) {
- cli.repeatingAction(keys, help) {
- transformActions[property]!!(it)
- }
- }
- transformActions[property] = invoke
- }
-
- fun parse(args: Array<String>) {
- cli.parseArgs(*args)
- }
-
-}
-
-fun CommandLineInterface.singleAction(
- keys: List<String>,
- help: String,
- invoke: (String) -> Unit
-) = registerAction(
- object : FlagActionBase(keys, help) {
- override fun invoke(arguments: ListIterator<String>) {
- if (arguments.hasNext()) {
- val msg = arguments.next()
- invoke(msg)
- }
- }
-
- override fun invoke() {
- error("should be never called")
- }
- }
-)
-
-fun CommandLineInterface.repeatingAction(
- keys: List<String>,
- help: String,
- invoke: (String) -> Unit
-) = registerAction(
- object : FlagActionBase(keys, help) {
- override fun invoke(arguments: ListIterator<String>) {
- while (arguments.hasNext()) {
- val message = arguments.next()
-
- if (this@repeatingAction.getFlagAction(message) != null) {
- arguments.previous()
- break
- }
- invoke(message)
- }
- }
-
- override fun invoke() {
- error("should be never called")
- }
- }
-
-)
-
-
-class DokkaArgumentsParser(val args: Array<String>, val parseContext: ParseContext) {
- class OptionDelegate<T>(
- var value: T,
- private val action: (delegate: OptionDelegate<T>, property: KProperty<*>) -> Unit
- ) {
- operator fun getValue(thisRef: Any?, property: KProperty<*>): T = value
- operator fun provideDelegate(thisRef: Any, property: KProperty<*>): OptionDelegate<T> {
- action(this, property)
- return this
- }
- }
-
- fun <T> parseInto(dest: T): T {
- // TODO: constructor: (DokkaArgumentsParser) -> T
- parseContext.parse(args)
- return dest
- }
-
- fun <T> repeatableOption(
- keys: List<String>,
- help: String,
- transform: (String) -> T
- ) = OptionDelegate(mutableListOf<T>()) { delegate, property ->
- parseContext.registerRepeatableOption(keys, help, property) {
- delegate.value.add(transform(it))
- }
- }
-
- fun <T : String?> repeatableOption(
- keys: List<String>,
- help: String
- ) = repeatableOption(keys, help) { it as T }
-
- fun <T> repeatableFlag(
- keys: List<String>,
- help: String,
- initElement: (ParseContext) -> T
- ) = OptionDelegate(mutableListOf<T>()) { delegate, property ->
- parseContext.registerFlagAction(keys, help, property) {
- delegate.value.add(initElement(parseContext))
- }
- }
-
- fun <T> singleFlag(
- keys: List<String>,
- help: String,
- initElement: (ParseContext) -> T,
- transform: () -> T
- ) = OptionDelegate(initElement(parseContext)) { delegate, property ->
- parseContext.registerFlagAction(keys, help, property) {
- delegate.value = transform()
- }
- }
-
- fun singleFlag(
- keys: List<String>,
- help: String
- ) = singleFlag(keys, help, { false }, { true })
-
- fun <T : String?> stringOption(
- keys: List<String>,
- help: String,
- defaultValue: T
- ) = singleOption(keys, help, { it as T }, { defaultValue })
-
- fun <T> singleOption(
- keys: List<String>,
- help: String,
- transform: (String) -> T,
- initElement: (ParseContext) -> T
- ) = OptionDelegate(initElement(parseContext)) { delegate, property ->
- parseContext.registerSingleOption(keys, help, property) {
- val toAdd = transform(it)
- delegate.value = toAdd
- }
- }
-}
-
-
-//`(-perPackage fqName [-include-non-public] [...other flags])*` (edited)
-//`(-sourceLink dir url [-urlSuffix value])*`
-//`(-extLink url [packageListUrl])*` \ No newline at end of file
diff --git a/runners/cli/src/main/kotlin/cli/main.kt b/runners/cli/src/main/kotlin/cli/main.kt
index 2ef08c2e..515f9bb0 100644
--- a/runners/cli/src/main/kotlin/cli/main.kt
+++ b/runners/cli/src/main/kotlin/cli/main.kt
@@ -1,335 +1,351 @@
package org.jetbrains.dokka
+import com.google.gson.Gson
+import kotlinx.cli.*
import org.jetbrains.dokka.DokkaConfiguration.ExternalDocumentationLink
import org.jetbrains.dokka.utilities.DokkaConsoleLogger
-import java.io.File
-import java.io.FileNotFoundException
+import org.jetbrains.kotlin.utils.addToStdlib.cast
+import java.io.*
import java.net.MalformedURLException
import java.net.URL
-import java.net.URLClassLoader
import java.nio.file.Files
import java.nio.file.Paths
-open class GlobalArguments(parser: DokkaArgumentsParser) : DokkaConfiguration {
- override val outputDir: String by parser.stringOption(
- listOf("-output"),
- "Output directory path",
- ""
- )
-
- override val format: String by parser.stringOption(
- listOf("-format"),
- "Output format (text, html, gfm, jekyll, kotlin-website)",
- ""
- )
-
- override val pluginsClasspath: List<File> by parser.repeatableOption(
- listOf("-dokkaPlugins"),
- "List of jars with dokka plugins"
- ) {
- File(it)
- }.also {
- Paths.get("./dokka-base.jar").toAbsolutePath().normalize().run {
- if (Files.exists(this)) it.value.add(this.toFile())
- else throw FileNotFoundException("Dokka base plugin is not found! Make sure you placed 'dokka-base.jar' containing base plugin along the cli jar file")
- }
- }
-
- override val cacheRoot: String? by parser.stringOption(
- listOf("-cacheRoot"),
- "Path to cache folder, or 'default' to use ~/.cache/dokka, if not provided caching is disabled",
- null
- )
-
- override val offlineMode: Boolean by parser.singleFlag(
- listOf("-offlineMode"),
- "Offline mode (do not download package lists from the Internet)"
- )
+class GlobalArguments(args: Array<String>) : DokkaConfiguration {
- override val failOnWarning: Boolean by parser.singleFlag(
- listOf("-failOnWarning"), "Fail dokka task if at least one warning was reported"
- )
+ val parser = ArgParser("globalArguments", prefixStyle = ArgParser.OptionPrefixStyle.JVM)
- override val passesConfigurations: List<Arguments> by parser.repeatableFlag(
- listOf("-pass"),
- "Single dokka pass"
- ) {
- Arguments(parser).also { if (it.moduleName.isEmpty()) DokkaConsoleLogger.warn("Not specified module name. It can result in unexpected behaviour while including documentation for module") }
- }
+ val json: String? by parser.argument(ArgType.String, description = "Json file name").optional()
- override val modules: List<DokkaConfiguration.DokkaModuleDescription> = emptyList()
+ override val outputDir by parser.option(ArgType.String, description = "Output directory path")
+ .default("./dokka")
- override val pluginsConfiguration: Map<String, String> = mutableMapOf()
-}
+ override val format by parser.option(
+ ArgType.String,
+ description = "Output format (html, gfm, jekyll)"
+ ).default("html")
-class Arguments(val parser: DokkaArgumentsParser) : DokkaConfiguration.PassConfiguration {
- override val moduleName: String by parser.stringOption(
- listOf("-module"),
- "Name of the documentation module",
- ""
+ override val cacheRoot by parser.option(
+ ArgType.String,
+ description = "Path to cache folder, or 'default' to use ~/.cache/dokka, if not provided caching is disabled"
)
- override val displayName: String by parser.stringOption(
- listOf("-displayName"),
- "Name displayed in the generated documentation",
- ""
- )
+ override val passesConfigurations by parser.option(
+ ArgTypeArgument,
+ description = "Single dokka pass",
+ fullName = "pass"
+ ).multiple()
- override val sourceSetID: String by parser.stringOption(
- listOf("-sourceSetID"),
- "Source set ID used for declaring dependent source sets",
- "main"
- )
+ override val pluginsConfiguration by parser.option(
+ ArgTypePlugin,
+ description = "Configuration for plugins in format fqPluginName=json^^fqPluginName=json..."
+ ).default(emptyMap())
- override val classpath: List<String> by parser.repeatableOption<String>(
- listOf("-classpath"),
- "Classpath for symbol resolution"
- )
-
- override val sourceRoots: List<DokkaConfiguration.SourceRoot> by parser.repeatableOption(
- listOf("-src"),
- "Source file or directory (allows many paths separated by the system path separator)"
- ) { SourceRootImpl(it) }
+ override val pluginsClasspath by parser.option(
+ ArgTypeFile,
+ description = "List of jars with dokka plugins (allows many paths separated by the semicolon `;`)"
+ ).delimiter(";")
- override val dependentSourceSets: List<String> by parser.repeatableOption<String>(
- listOf("-dependentSets"),
- "Names of dependent source sets"
- )
-
- override val samples: List<String> by parser.repeatableOption<String>(
- listOf("-sample"),
- "Source root for samples"
- )
- override val includes: List<String> by parser.repeatableOption<String>(
- listOf("-include"),
- "Markdown files to load (allows many paths separated by the system path separator)"
- )
-
- override val includeNonPublic: Boolean by parser.singleFlag(
- listOf("-includeNonPublic"),
- "Include non public"
- )
-
- override val includeRootPackage: Boolean by parser.singleFlag(
- listOf("-includeRootPackage"),
- "Include root package"
- )
-
- override val reportUndocumented: Boolean by parser.singleFlag(
- listOf("-reportUndocumented"),
- "Report undocumented members"
+ override val offlineMode by parser.option(
+ ArgType.Boolean,
+ "Offline mode (do not download package lists from the Internet)"
+ ).default(false)
+
+ override val failOnWarning by parser.option(
+ ArgType.Boolean,
+ "Throw an exception if the generation exited with warnings"
+ ).default(false)
+
+ val globalPackageOptions by parser.option(
+ ArgType.String,
+ description = "List of package passConfiguration 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 helpPass by parser.option(
+ ArgTypeHelpPass,
+ description = "Prints help for single -pass"
)
- override val skipEmptyPackages: Boolean by parser.singleFlag(
- listOf("-skipEmptyPackages"),
- "Do not create index pages for empty packages"
- )
+ override val modules: List<DokkaConfiguration.DokkaModuleDescription> = emptyList()
- override val skipDeprecated: Boolean by parser.singleFlag(
- listOf("-skipDeprecated"),
- "Do not output deprecated members"
- )
+ init {
+ parser.parse(args)
- override val jdkVersion: Int by parser.singleOption(
- listOf("-jdkVersion"),
- "Version of JDK to use for linking to JDK JavaDoc",
- { it.toInt() },
- { 8 }
- )
+ passesConfigurations.all {
+ it.perPackageOptions.cast<MutableList<DokkaConfiguration.PackageOptions>>()
+ .addAll(parsePerPackageOptions(globalPackageOptions))
+ }
- override val languageVersion: String? by parser.stringOption(
- listOf("-languageVersion"),
- "Language Version to pass to Kotlin analysis",
- null
- )
+ passesConfigurations.all {
+ it.externalDocumentationLinks.cast<MutableList<ExternalDocumentationLink>>().addAll(parseLinks(globalLinks))
+ }
- override val apiVersion: String? by parser.stringOption(
- listOf("-apiVersion"),
- "Kotlin Api Version to pass to Kotlin analysis",
- null
- )
+ globalSrcLink.forEach {
+ if (it.isNotEmpty() && it.contains("="))
+ passesConfigurations.all { pass ->
+ pass.sourceLinks.cast<MutableList<SourceLinkDefinitionImpl>>()
+ .add(SourceLinkDefinitionImpl.parseSourceLinkDefinition(it))
+ }
+ else {
+ DokkaConsoleLogger.warn("Invalid -srcLink syntax. Expected: <path>=<url>[#lineSuffix]. No source links will be generated.")
+ }
+ }
- override val noStdlibLink: Boolean by parser.singleFlag(
- listOf("-noStdlibLink"),
- "Disable documentation link to stdlib"
- )
+ passesConfigurations.forEach {
+ it.externalDocumentationLinks.cast<MutableList<ExternalDocumentationLink>>().addAll(defaultLinks(it))
+ }
+ }
+}
- override val noJdkLink: Boolean by parser.singleFlag(
- listOf("-noJdkLink"),
- "Disable documentation link to JDK"
+fun passArguments(args: Array<String>): DokkaConfiguration.PassConfiguration {
+
+ val parser = ArgParser("passConfiguration", prefixStyle = ArgParser.OptionPrefixStyle.JVM)
+
+ val moduleName by parser.option(
+ ArgType.String,
+ description = "Name of the documentation module",
+ fullName = "module"
+ ).required()
+
+ val displayName by parser.option(
+ ArgType.String,
+ description = "Name of the source set"
+ ).default("JVM")
+
+ val sourceSetID by parser.option(
+ ArgType.String,
+ description = "ID of the source set"
+ ).default("main")
+
+ val classpath by parser.option(
+ ArgType.String,
+ description = "Classpath for symbol resolution (allows many paths separated by the semicolon `;`)"
+ ).delimiter(";")
+
+ val sourceRoots by parser.option(
+ ArgType.String,
+ description = "Source file or directory (allows many paths separated by the semicolon `;`)",
+ fullName = "src"
+ ).delimiter(";")
+
+ val dependentSourceRoots by parser.option(
+ ArgType.String,
+ description = "Source file or directory (allows many paths separated by the semicolon `;`)"
+ ).delimiter(";")
+
+ val dependentSourceSets by parser.option(
+ ArgType.String,
+ description = "Names of dependent source sets (allows many paths separated by the semicolon `;`)"
+ ).delimiter(";")
+
+ val samples by parser.option(
+ ArgType.String,
+ description = "Source root for samples (allows many paths separated by the semicolon `;`)"
+ ).delimiter(";")
+
+ val includes by parser.option(
+ ArgType.String,
+ 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(false)
+
+ val includeRootPackage by parser.option(ArgType.Boolean, description = "Include non public")
+ .default(false)
+
+ val reportUndocumented by parser.option(ArgType.Boolean, description = "Report undocumented members")
+ .default(false)
+
+ val skipEmptyPackages by parser.option(
+ ArgType.Boolean,
+ description = "Do not create index pages for empty packages"
+ ).default(false)
+
+ val skipDeprecated by parser.option(ArgType.Boolean, description = "Do not output deprecated members")
+ .default(false)
+
+ val jdkVersion by parser.option(
+ ArgType.Int,
+ description = "Version of JDK to use for linking to JDK JavaDoc"
+ ).default(8)
+
+ val languageVersion by parser.option(
+ ArgType.String,
+ description = "Language Version to pass to Kotlin analysis"
)
- override val suppressedFiles: List<String> by parser.repeatableOption<String>(
- listOf("-suppressedFile"),
- ""
+ 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(false)
+
+ val noJdkLink by parser.option(ArgType.Boolean, description = "Disable documentation link to JDK")
+ .default(false)
+
+ val suppressedFiles by parser.option(
+ ArgType.String,
+ 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(Platform.DEFAULT)
+
+ val perPackageOptions by parser.option(
+ ArgType.String,
+ description = "List of package passConfiguration 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.PassConfiguration {
+ override val moduleName = moduleName
+ override val displayName = displayName
+ override val sourceSetID = sourceSetID
+ override val classpath = classpath
+ override val sourceRoots = sourceRoots.map { SourceRootImpl(it.toAbsolutePath()) }
+ override val dependentSourceSets: List<String> = dependentSourceSets
+ override val samples = samples.map { it.toAbsolutePath() }
+ override val includes = includes.map { it.toAbsolutePath() }
+ override val includeNonPublic = includeNonPublic
+ override val includeRootPackage = includeRootPackage
+ override val reportUndocumented = reportUndocumented
+ override val skipEmptyPackages = skipEmptyPackages
+ override val skipDeprecated = skipDeprecated
+ override val jdkVersion = jdkVersion
+ override val sourceLinks = sourceLinks
+ override val analysisPlatform = analysisPlatform
+ override val perPackageOptions = parsePerPackageOptions(perPackageOptions)
+ override val externalDocumentationLinks = parseLinks(externalDocumentationLinks)
+ override val languageVersion = languageVersion
+ override val apiVersion = apiVersion
+ override val noStdlibLink = noStdlibLink
+ override val noJdkLink = noJdkLink
+ override val suppressedFiles = suppressedFiles
+ }
+}
- override val analysisPlatform: Platform by parser.singleOption(
- listOf("-analysisPlatform"),
- "Platform for analysis",
- { Platform.fromString(it) },
- { Platform.DEFAULT }
- )
+object ArgTypeFile : ArgType<File>(true) {
+ override fun convert(value: kotlin.String, name: kotlin.String): File = File(value)
+ override val description: kotlin.String
+ get() = "{ String that points to file path }"
+}
+object ArgTypePlatform : ArgType<Platform>(true) {
+ override fun convert(value: kotlin.String, name: kotlin.String): Platform = Platform.fromString(value)
+ override val description: kotlin.String
+ get() = "{ String thar represents paltform }"
+}
- override val perPackageOptions: MutableList<DokkaConfiguration.PackageOptions> by parser.singleOption(
- listOf("-packageOptions"),
- "List of package passConfiguration in format \"prefix,-deprecated,-privateApi,+reportUndocumented,+suppress;...\" ",
- { parsePerPackageOptions(it).toMutableList() },
- { mutableListOf() }
- )
+object ArgTypePlugin : ArgType<Map<String, String>>(true) {
+ override fun convert(value: kotlin.String, name: kotlin.String): Map<kotlin.String, kotlin.String> =
+ value.split("^^").map {
+ it.split("=").let {
+ it[0] to it[1]
+ }
+ }.toMap()
- override val externalDocumentationLinks: MutableList<DokkaConfiguration.ExternalDocumentationLink> by parser.singleOption(
- listOf("-links"),
- "External documentation links in format url^packageListUrl^^url2...",
- { MainKt.parseLinks(it).toMutableList() },
- { mutableListOf() }
- )
+ override val description: kotlin.String
+ get() = "{ String fqName=json, remember to escape `\"` inside json }"
+}
- override val sourceLinks: MutableList<DokkaConfiguration.SourceLinkDefinition> by parser.repeatableOption<DokkaConfiguration.SourceLinkDefinition>(
- listOf("-srcLink"),
- "Mapping between a source directory and a Web site for browsing the code"
- ) {
- if (it.isNotEmpty() && it.contains("="))
- SourceLinkDefinitionImpl.parseSourceLinkDefinition(it)
+object ArgTypeSourceLinkDefinition : ArgType<DokkaConfiguration.SourceLinkDefinition>(true) {
+ override fun convert(value: kotlin.String, name: kotlin.String): DokkaConfiguration.SourceLinkDefinition =
+ if (value.isNotEmpty() && value.contains("="))
+ SourceLinkDefinitionImpl.parseSourceLinkDefinition(value)
else {
throw IllegalArgumentException("Warning: Invalid -srcLink syntax. Expected: <path>=<url>[#lineSuffix]. No source links will be generated.")
}
- }
-}
-object MainKt {
- fun defaultLinks(config: DokkaConfiguration.PassConfiguration): MutableList<ExternalDocumentationLink> =
- mutableListOf<ExternalDocumentationLink>().apply {
- if (!config.noJdkLink)
- this += DokkaConfiguration.ExternalDocumentationLink
- .Builder("https://docs.oracle.com/javase/${config.jdkVersion}/docs/api/")
- .build()
-
- if (!config.noStdlibLink)
- this += DokkaConfiguration.ExternalDocumentationLink
- .Builder("https://kotlinlang.org/api/latest/jvm/stdlib/")
- .build()
- }
+ override val description: kotlin.String
+ get() = "{ String that represent source links }"
+}
- fun parseLinks(links: String): List<ExternalDocumentationLink> {
- val (parsedLinks, parsedOfflineLinks) = links.split("^^")
- .map { it.split("^").map { it.trim() }.filter { it.isNotBlank() } }
- .filter { it.isNotEmpty() }
- .partition { it.size == 1 }
-
- return parsedLinks.map { (root) -> ExternalDocumentationLink.Builder(root).build() } +
- parsedOfflineLinks.map { (root, packageList) ->
- val rootUrl = URL(root)
- val packageListUrl =
- try {
- URL(packageList)
- } catch (ex: MalformedURLException) {
- File(packageList).toURI().toURL()
- }
- ExternalDocumentationLink.Builder(rootUrl, packageListUrl).build()
- }
- }
+object ArgTypeArgument : ArgType<DokkaConfiguration.PassConfiguration>(true) {
+ override fun convert(value: kotlin.String, name: kotlin.String): DokkaConfiguration.PassConfiguration =
+ passArguments(value.split(" ").filter { it.isNotBlank() }.toTypedArray())
- @JvmStatic
- fun entry(configuration: DokkaConfiguration) {
- val generator = DokkaGenerator(configuration, DokkaConsoleLogger)
- generator.generate()
- DokkaConsoleLogger.report()
- }
+ override val description: kotlin.String
+ get() = ""
+}
- fun findToolsJar(): File {
- val javaHome = System.getProperty("java.home")
- val default = File(javaHome, "../lib/tools.jar")
- val mac = File(javaHome, "../Classes/classes.jar")
- return when {
- default.exists() -> default
- mac.exists() -> mac
- else -> {
- throw Exception("tools.jar not found, please check it, also you can provide it manually, using -cp")
- }
- }
- }
+// Workaround for printing nested parsers help
+object ArgTypeHelpPass : ArgType<Any>(false) {
+ override fun convert(value: kotlin.String, name: kotlin.String): Any = Any().also { passArguments(arrayOf("-h")) }
- fun createClassLoaderWithTools(): ClassLoader {
- val toolsJar = findToolsJar().canonicalFile.toURI().toURL()
- val originalUrls = (javaClass.classLoader as? URLClassLoader)?.urLs
- val dokkaJar = javaClass.protectionDomain.codeSource.location
- val urls = if (originalUrls != null) arrayOf(toolsJar, *originalUrls) else arrayOf(toolsJar, dokkaJar)
- return URLClassLoader(urls, ClassLoader.getSystemClassLoader().parent)
- }
+ override val description: kotlin.String
+ get() = ""
+}
- fun startWithToolsJar(configuration: DokkaConfiguration) {
- try {
- javaClass.classLoader.loadClass("com.sun.tools.doclets.formats.html.HtmlDoclet")
- entry(configuration)
- } catch (e: ClassNotFoundException) {
- val classLoader = createClassLoaderWithTools()
- classLoader.loadClass("org.jetbrains.dokka.MainKt")
- .methods.find { it.name == "entry" }!!
- .invoke(null, configuration)
- }
+fun defaultLinks(config: DokkaConfiguration.PassConfiguration): MutableList<ExternalDocumentationLink> =
+ mutableListOf<ExternalDocumentationLink>().apply {
+ if (!config.noJdkLink)
+ this += DokkaConfiguration.ExternalDocumentationLink
+ .Builder("https://docs.oracle.com/javase/${config.jdkVersion}/docs/api/")
+ .build()
+
+ if (!config.noStdlibLink)
+ this += ExternalDocumentationLink
+ .Builder("https://kotlinlang.org/api/latest/jvm/stdlib/")
+ .build()
}
- fun createConfiguration(args: Array<String>): GlobalArguments {
- val parseContext = ParseContext()
- val parser = DokkaArgumentsParser(args, parseContext)
- val configuration = GlobalArguments(parser)
-
- parseContext.cli.singleAction(
- listOf("-globalPackageOptions"),
- "List of package passConfiguration in format \"prefix,-deprecated,-privateApi,+reportUndocumented,+suppress;...\" "
- ) { link ->
- configuration.passesConfigurations.all {
- it.perPackageOptions.toMutableList().addAll(parsePerPackageOptions(link))
- }
- }
-
- parseContext.cli.singleAction(
- listOf("-globalLinks"),
- "External documentation links in format url^packageListUrl^^url2..."
- ) { link ->
- configuration.passesConfigurations.all {
- it.externalDocumentationLinks.toMutableList().addAll(parseLinks(link))
- }
- }
-
- parseContext.cli.repeatingAction(
- listOf("-globalSrcLink"),
- "Mapping between a source directory and a Web site for browsing the code"
- ) {
- val newSourceLinks = if (it.isNotEmpty() && it.contains("="))
- listOf(SourceLinkDefinitionImpl.parseSourceLinkDefinition(it))
- else {
- if (it.isNotEmpty()) {
- DokkaConsoleLogger.warn("Invalid -srcLink syntax. Expected: <path>=<url>[#lineSuffix]. No source links will be generated.")
- }
- listOf()
+private fun String.toAbsolutePath() = Paths.get(this).toAbsolutePath().toString()
+
+fun parseLinks(links: List<String>): List<ExternalDocumentationLink> {
+ val (parsedLinks, parsedOfflineLinks) = links
+ .map { it.split("^").map { it.trim() }.filter { it.isNotBlank() } }
+ .filter { it.isNotEmpty() }
+ .partition { it.size == 1 }
+
+ return parsedLinks.map { (root) -> ExternalDocumentationLink.Builder(root).build() } +
+ parsedOfflineLinks.map { (root, packageList) ->
+ val rootUrl = URL(root)
+ val packageListUrl =
+ try {
+ URL(packageList)
+ } catch (ex: MalformedURLException) {
+ File(packageList).toURI().toURL()
+ }
+ ExternalDocumentationLink.Builder(rootUrl, packageListUrl).build()
}
-
- configuration.passesConfigurations.all {
- it.sourceLinks.toMutableList().addAll(newSourceLinks)
- }
- }
- parser.parseInto(configuration)
- configuration.passesConfigurations.forEach {
- it.externalDocumentationLinks.addAll(defaultLinks(it))
- }
- return configuration
- }
-
- @JvmStatic
- fun main(args: Array<String>) {
- val configuration = createConfiguration(args)
-
- if (configuration.format.toLowerCase() == "javadoc")
- startWithToolsJar(configuration)
- else
- entry(configuration)
- }
}
-
-
+fun main(args: Array<String>) {
+ val globalArguments = GlobalArguments(args)
+ val configuration = if (globalArguments.json != null)
+ Gson().fromJson(
+ Paths.get(globalArguments.json).toFile().readText(),
+ DokkaConfigurationImpl::class.java
+ )
+ else
+ globalArguments
+ DokkaGenerator(configuration, DokkaConsoleLogger).generate()
+} \ No newline at end of file