diff options
Diffstat (limited to 'runners/cli')
-rw-r--r-- | runners/cli/build.gradle | 16 | ||||
-rw-r--r-- | runners/cli/build.gradle.kts | 34 | ||||
-rw-r--r-- | runners/cli/src/main/kotlin/cli/DokkaArgumentsParser.kt | 185 | ||||
-rw-r--r-- | runners/cli/src/main/kotlin/cli/main.kt | 532 |
4 files changed, 336 insertions, 431 deletions
diff --git a/runners/cli/build.gradle b/runners/cli/build.gradle deleted file mode 100644 index 24db0b1e..00000000 --- a/runners/cli/build.gradle +++ /dev/null @@ -1,16 +0,0 @@ -apply plugin: 'kotlin' - -sourceCompatibility = 1.8 - -tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { - kotlinOptions { - languageVersion = language_version - apiVersion = language_version - jvmTarget = "1.8" - } -} - -dependencies { - implementation "org.jetbrains.kotlinx:kotlinx-cli-jvm:0.1.0-dev-3" - implementation project(":core") -} diff --git a/runners/cli/build.gradle.kts b/runners/cli/build.gradle.kts new file mode 100644 index 00000000..4ad34192 --- /dev/null +++ b/runners/cli/build.gradle.kts @@ -0,0 +1,34 @@ +import org.jetbrains.DokkaPublicationBuilder.Component.Shadow +import org.jetbrains.registerDokkaArtifactPublication + +plugins { + id("com.github.johnrengelman.shadow") + id("com.jfrog.bintray") +} + +repositories { + maven(url = "https://dl.bintray.com/kotlin/kotlinx") +} + +dependencies { + implementation("org.jetbrains.kotlinx:kotlinx-cli-jvm:0.2.1") + implementation(project(":core")) + implementation(kotlin("stdlib")) +} + +tasks { + shadowJar { + val dokka_version: String by project + archiveFileName.set("dokka-cli-$dokka_version.jar") + archiveClassifier.set("") + manifest { + attributes("Main-Class" to "org.jetbrains.dokka.MainKt") + } + } +} + +registerDokkaArtifactPublication("dokkaCli"){ + artifactId = "dokka-cli" + component = Shadow +} + 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 55601b21..989a45a1 100644 --- a/runners/cli/src/main/kotlin/cli/main.kt +++ b/runners/cli/src/main/kotlin/cli/main.kt @@ -1,278 +1,350 @@ package org.jetbrains.dokka +import kotlinx.cli.* import org.jetbrains.dokka.DokkaConfiguration.ExternalDocumentationLink -import org.jetbrains.dokka.Utilities.defaultLinks -import java.io.File +import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet.* +import org.jetbrains.dokka.utilities.DokkaConsoleLogger +import org.jetbrains.dokka.utilities.cast +import java.io.* import java.net.MalformedURLException import java.net.URL -import java.net.URLClassLoader - -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, markdown, jekyll, kotlin-website)", - "") - - override val generateIndexPages: Boolean by parser.singleFlag( - listOf("-generateIndexPages"), - "Generate index page" - ) +import java.nio.file.Files +import java.nio.file.Paths - 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) +class GlobalArguments(args: Array<String>) : DokkaConfiguration { - override val impliedPlatforms: List<String> = emptyList() + val parser = ArgParser("globalArguments", prefixStyle = ArgParser.OptionPrefixStyle.JVM) - override val passesConfigurations: List<Arguments> by parser.repeatableFlag( - listOf("-pass"), - "Single dokka pass" - ) { - Arguments(parser) - } -} + val json: String? by parser.argument(ArgType.String, description = "Json file name").optional() -class Arguments(val parser: DokkaArgumentsParser) : DokkaConfiguration.PassConfiguration { - override val moduleName: String by parser.stringOption( - listOf("-module"), - "Name of the documentation module", - "") + override val outputDir by parser.option(ArgType.String, description = "Output directory path") + .default(DokkaDefaults.outputDir) - override val classpath: List<String> by parser.repeatableOption( - listOf("-classpath"), - "Classpath for symbol resolution" + 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 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 samples: List<String> by parser.repeatableOption( - listOf("-sample"), - "Source root for samples" + override val sourceSets by parser.option( + ArgTypeArgument, + 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..." + ).default(emptyMap()) + + override val pluginsClasspath by parser.option( + ArgTypeFile, + description = "List of jars with dokka plugins (allows many paths separated by the semicolon `;`)" + ).delimiter(";") + + + override val offlineMode by parser.option( + ArgType.Boolean, + "Offline mode (do not download package lists from the Internet)" + ).default(DokkaDefaults.offlineMode) + + override val failOnWarning by parser.option( + ArgType.Boolean, + "Throw an exception if the generation exited with warnings" + ).default(DokkaDefaults.failOnWarning) + + 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, + description = "Prints help for single -sourceSet" ) - override val includes: List<String> by parser.repeatableOption( - 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 modules: List<DokkaConfiguration.DokkaModuleDescription> = emptyList() - override val reportUndocumented: Boolean by parser.singleFlag( - listOf("-reportUndocumented"), - "Report undocumented members") + init { + parser.parse(args) - override val skipEmptyPackages: Boolean by parser.singleFlag( - listOf("-skipEmptyPackages"), - "Do not create index pages for empty packages") - - override val skipDeprecated: Boolean by parser.singleFlag( - listOf("-skipDeprecated"), - "Do not output deprecated members") - - override val jdkVersion: Int by parser.singleOption( - listOf("-jdkVersion"), - "Version of JDK to use for linking to JDK JavaDoc", - { it.toInt() }, - { 6 } - ) - - override val languageVersion: String? by parser.stringOption( - listOf("-languageVersion"), - "Language Version to pass to Kotlin Analysis", - null) - - override val apiVersion: String? by parser.stringOption( - listOf("-apiVersion"), - "Kotlin Api Version to pass to Kotlin Analysis", - null - ) + sourceSets.all { + it.perPackageOptions.cast<MutableList<DokkaConfiguration.PackageOptions>>() + .addAll(parsePerPackageOptions(globalPackageOptions)) + } - override val noStdlibLink: Boolean by parser.singleFlag( - listOf("-noStdlibLink"), - "Disable documentation link to stdlib") + sourceSets.all { + it.externalDocumentationLinks.cast<MutableList<ExternalDocumentationLink>>().addAll(parseLinks(globalLinks)) + } - override val noJdkLink: Boolean by parser.singleFlag( - listOf("-noJdkLink"), - "Disable documentation link to JDK") + globalSrcLink.forEach { + if (it.isNotEmpty() && it.contains("=")) + sourceSets.all { sourceSet -> + sourceSet.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 suppressedFiles: List<String> by parser.repeatableOption( - listOf("-suppressedFile"), - "" - ) + sourceSets.forEach { + it.externalDocumentationLinks.cast<MutableList<ExternalDocumentationLink>>().addAll(defaultLinks(it)) + it.externalDocumentationLinks.cast<MutableList<ExternalDocumentationLink>>().replaceAll { link -> + ExternalDocumentationLink.Builder(link.url, link.packageListUrl).build() + } + } + } +} - override val sinceKotlin: String? by parser.stringOption( - listOf("-sinceKotlin"), - "Kotlin Api version to use as base version, if none specified", - null - ) +private fun parseSourceSet(args: Array<String>): DokkaConfiguration.DokkaSourceSet { - override val collectInheritedExtensionsFromLibraries: Boolean by parser.singleFlag( - listOf("-collectInheritedExtensionsFromLibraries"), - "Search for applicable extensions in libraries") + val parser = ArgParser("sourceSet", prefixStyle = ArgParser.OptionPrefixStyle.JVM) - override val analysisPlatform: Platform by parser.singleOption( - listOf("-analysisPlatform"), - "Platform for analysis", - { Platform.fromString(it) }, - { Platform.DEFAULT } - ) + val moduleName by parser.option( + ArgType.String, + description = "Name of the documentation module", + fullName = "moduleName" + ).required() - override val targets: List<String> by parser.repeatableOption( - listOf("-target"), - "Generation targets" + val moduleDisplayName by parser.option( + ArgType.String, + description = "Name of the documentation module" ) - override val perPackageOptions: MutableList<DokkaConfiguration.PackageOptions> by parser.singleOption( - listOf("-packageOptions"), - "List of package passConfiguration in format \"prefix,-deprecated,-privateApi,+warnUndocumented,+suppress;...\" ", - { parsePerPackageOptions(it).toMutableList() }, - { mutableListOf() } + 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("JVM") + + 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 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( + 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(DokkaDefaults.includeNonPublic) + + val includeRootPackage by parser.option(ArgType.Boolean, description = "Include root package") + .default(DokkaDefaults.includeRootPackage) + + val reportUndocumented by parser.option(ArgType.Boolean, description = "Report undocumented members") + .default(DokkaDefaults.reportUndocumented) + + val skipEmptyPackages by parser.option( + ArgType.Boolean, + description = "Do not create index pages for empty packages" + ).default(DokkaDefaults.skipEmptyPackages) + + 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" ) - override val externalDocumentationLinks: MutableList<DokkaConfiguration.ExternalDocumentationLink> by parser.singleOption( - listOf("-links"), - "External documentation links in format url^packageListUrl^^url2...", - { MainKt.parseLinks(it).toMutableList() }, - { mutableListOf() } + val apiVersion by parser.option( + ArgType.String, + description = "Kotlin Api Version to pass to Kotlin analysis" ) - override val sourceLinks: MutableList<DokkaConfiguration.SourceLinkDefinition> by parser.repeatableOption( - listOf("-srcLink"), - "Mapping between a source directory and a Web site for browsing the code" - ) { - if (it.isNotEmpty() && it.contains("=")) - SourceLinkDefinitionImpl.parseSourceLinkDefinition(it) - else { - throw IllegalArgumentException("Warning: Invalid -srcLink syntax. Expected: <path>=<url>[#lineSuffix]. No source links will be generated.") - } + 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( + 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(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 moduleDisplayName = moduleDisplayName ?: moduleName + override val displayName = displayName + override val sourceSetID = DokkaSourceSetID(moduleName, sourceSetName) + override val classpath = classpath + override val sourceRoots = sourceRoots.map { SourceRootImpl(it.toAbsolutePath()) } + override val dependentSourceSets: Set<DokkaSourceSetID> = dependentSourceSets + .map { dependentSourceSetName -> dependentSourceSetName.split('/').let { DokkaSourceSetID(it[0], it[1]) } } + .toSet() + 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 } } -object MainKt { - 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 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 }" +} - @JvmStatic - fun entry(configuration: DokkaConfiguration) { - val generator = DokkaGenerator(configuration, DokkaConsoleLogger) - generator.generate() - DokkaConsoleLogger.report() - } +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 }" +} - fun findToolsJar(): File { - val javaHome = System.getProperty("java.home") - val default = File(javaHome, "../lib/tools.jar") - val mac = File(javaHome, "../Classes/classes.jar") - when { - default.exists() -> return default - mac.exists() -> return mac - else -> { - throw Exception("tools.jar not found, please check it, also you can provide it manually, using -cp") +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() - 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() = "{ String fqName=json, remember to escape `\"` inside json }" +} - 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) +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.") } - } - fun createConfiguration(args: Array<String>): GlobalArguments { - val parseContext = ParseContext() - val parser = DokkaArgumentsParser(args, parseContext) - val configuration = GlobalArguments(parser) + override val description: kotlin.String + get() = "{ String that represent source links }" +} - parseContext.cli.singleAction( - listOf("-globalPackageOptions"), - "List of package passConfiguration in format \"prefix,-deprecated,-privateApi,+warnUndocumented,+suppress;...\" " - ) { link -> - configuration.passesConfigurations.all { it.perPackageOptions.addAll(parsePerPackageOptions(link)) } - } +object ArgTypeArgument : ArgType<DokkaConfiguration.DokkaSourceSet>(true) { + override fun convert(value: kotlin.String, name: kotlin.String): DokkaConfiguration.DokkaSourceSet = + parseSourceSet(value.split(" ").filter { it.isNotBlank() }.toTypedArray()) - parseContext.cli.singleAction( - listOf("-globalLinks"), - "External documentation links in format url^packageListUrl^^url2..." - ) { link -> - configuration.passesConfigurations.all { it.externalDocumentationLinks.addAll(parseLinks(link)) } - } + override val description: kotlin.String + get() = "" +} - 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()) { - println("Warning: Invalid -srcLink syntax. Expected: <path>=<url>[#lineSuffix]. No source links will be generated.") - } - listOf() - } +// Workaround for printing nested parsers help +object ArgTypeHelpSourceSet : ArgType<Any>(false) { + override fun convert(value: kotlin.String, name: kotlin.String): Any = Any().also { parseSourceSet(arrayOf("-h")) } - configuration.passesConfigurations.all { it.sourceLinks.addAll(newSourceLinks) } - } + override val description: kotlin.String + get() = "" +} - parser.parseInto(configuration) - return configuration +fun defaultLinks(config: DokkaConfiguration.DokkaSourceSet): 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 GlobalArguments.addDefaultLinks() = passesConfigurations.forEach { it.externalDocumentationLinks += it.defaultLinks() } - - @JvmStatic - fun main(args: Array<String>) { - val configuration = createConfiguration(args).apply { addDefaultLinks() } - if (configuration.format.toLowerCase() == "javadoc") - startWithToolsJar(configuration) - else - entry(configuration) - } +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() + } } - - +fun main(args: Array<String>) { + val globalArguments = GlobalArguments(args) + val configuration = if (globalArguments.json != null) + DokkaConfigurationImpl( + Paths.get(checkNotNull(globalArguments.json)).toFile().readText() + ) + else + globalArguments + DokkaGenerator(configuration, DokkaConsoleLogger).generate() +} |