aboutsummaryrefslogtreecommitdiff
path: root/runners/cli/src
diff options
context:
space:
mode:
authoraleksZubakov <aleks.zubakov@gmail.com>2018-08-10 16:12:50 +0300
committeraleksZubakov <aleks.zubakov@gmail.com>2018-08-10 16:12:50 +0300
commit8d051eb3b32d7caf44b972fe03f2e0a5fcdd4490 (patch)
treefbf29a07a60d56b80e0f213bff34f7e04ea72997 /runners/cli/src
parente00bfb699deb2a7781d9a15b225c68f098089107 (diff)
downloaddokka-8d051eb3b32d7caf44b972fe03f2e0a5fcdd4490.tar.gz
dokka-8d051eb3b32d7caf44b972fe03f2e0a5fcdd4490.tar.bz2
dokka-8d051eb3b32d7caf44b972fe03f2e0a5fcdd4490.zip
Boilerplate eliminating
Diffstat (limited to 'runners/cli/src')
-rw-r--r--runners/cli/src/main/kotlin/cli/DokkaArgumentsParser.kt226
-rw-r--r--runners/cli/src/main/kotlin/cli/main.kt376
2 files changed, 363 insertions, 239 deletions
diff --git a/runners/cli/src/main/kotlin/cli/DokkaArgumentsParser.kt b/runners/cli/src/main/kotlin/cli/DokkaArgumentsParser.kt
new file mode 100644
index 00000000..dd4d6377
--- /dev/null
+++ b/runners/cli/src/main/kotlin/cli/DokkaArgumentsParser.kt
@@ -0,0 +1,226 @@
+package org.jetbrains.dokka
+
+import kotlinx.cli.*
+import kotlin.reflect.KProperty
+class ParseContext(val cli: CommandLineInterface = CommandLineInterface("dokka")) {
+ private val map = mutableMapOf<KProperty<*>, (String) -> Unit>()
+ private val flagActions = mutableMapOf<KProperty<*>, () -> Unit>()
+
+ fun registerFlagAction(
+ keys: List<String>,
+ help: String,
+ invoke: () -> Unit,
+ property: KProperty<*>
+ ) {
+ if (property !in flagActions.keys) {
+ cli.flagAction(keys, help) {
+ flagActions[property]!!()
+ }
+ }
+ flagActions[property] = invoke
+
+ }
+
+ fun registerSingleAction(
+ keys: List<String>,
+ help: String,
+ invoke: (String) -> Unit,
+ property: KProperty<*>
+ ) {
+ if (property !in map.keys) {
+ cli.singleAction(keys, help) {
+ map[property]!!(it)
+ }
+ }
+ map[property] = invoke
+ }
+
+ fun registerRepeatableAction(
+ keys: List<String>,
+ help: String,
+ invoke: (String) -> Unit,
+ property: KProperty<*>
+ ) {
+ if (property !in map.keys) {
+ cli.repeatingAction(keys, help) {
+ map[property]!!(it)
+ }
+ }
+ map[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) {
+ fun <T> parseInto(constructor: (parseContext: DokkaArgumentsParser) -> T): T {
+ val res = constructor(this)
+ parseContext.parse(args)
+ return res
+ }
+
+ fun <T> repeatableOption(
+ keys: List<String>,
+ help: String,
+ transform: (String) -> T
+ ): OptionDelegate<MutableList<T>> {
+ val list = mutableListOf<T>()
+ return object : OptionDelegate<MutableList<T>>(list) {
+ override fun provideDelegate(thisRef: Any, property: KProperty<*>): OptionDelegate<MutableList<T>> {
+ parseContext.registerRepeatableAction(
+ keys,
+ help,
+ {
+ list.add(transform(it))
+ },
+ property
+
+ )
+ return this
+ }
+ }
+ }
+
+ fun <T> repeatableFlag(
+ keys: List<String>,
+ help: String,
+ initElement: (ParseContext) -> T
+ ): OptionDelegate<MutableList<T>> {
+ val list = mutableListOf<T>()
+ return object : OptionDelegate<MutableList<T>>(list) {
+ override fun provideDelegate(thisRef: Any, property: KProperty<*>): OptionDelegate<MutableList<T>> {
+ parseContext.registerFlagAction(
+ keys,
+ help,
+ {
+ list.add(initElement(parseContext))
+ },
+ property
+
+ )
+ return this
+ }
+ }
+ }
+
+ fun <T> singleFlag(
+ keys: List<String>,
+ help: String,
+ initElement: (ParseContext) -> T,
+ transform: () -> T
+ ): OptionDelegate<T> {
+ val element = initElement(parseContext)
+ return object : OptionDelegate<T>(element) {
+ override fun provideDelegate(thisRef: Any, property: KProperty<*>): OptionDelegate<T> {
+ parseContext.registerFlagAction(
+ keys,
+ help,
+ {
+ value = transform()
+ },
+ property
+ )
+
+ return this
+ }
+ }
+
+ }
+
+ fun <T> singleOption(
+ keys: List<String>,
+ help: String,
+ transform: ((String) -> T)? = null,
+ initElement: (ParseContext) -> T
+ ): OptionDelegate<T> {
+ val element: T = initElement(parseContext)
+ return object : OptionDelegate<T>(element) {
+
+ override fun provideDelegate(thisRef: Any, property: KProperty<*>): OptionDelegate<T> {
+ parseContext.registerSingleAction(
+ keys,
+ help,
+ {
+ val toAdd = if (transform != null) {
+ transform(it)
+ } else {
+ it as T
+ }
+ value = toAdd
+ },
+ property
+ )
+
+ return this
+ }
+ }
+ }
+
+ fun singleBooleanFlag(
+ keys: List<String>,
+ help: String
+ ) = singleFlag(keys, help, { false }, { true })
+
+ fun <T> defaultSingleOption(
+ keys: List<String>,
+ help: String,
+ defaultValue: T
+ ) = singleOption(
+ keys,
+ help,
+ { it as T },
+ { defaultValue }
+ )
+}
+
+abstract class OptionDelegate<T>(var value: T) {
+ operator fun getValue(thisRef: Any?, property: KProperty<*>): T = value
+ abstract operator fun provideDelegate(thisRef: Any, property: KProperty<*>): OptionDelegate<T>
+}
diff --git a/runners/cli/src/main/kotlin/cli/main.kt b/runners/cli/src/main/kotlin/cli/main.kt
index 85826fe0..34d86257 100644
--- a/runners/cli/src/main/kotlin/cli/main.kt
+++ b/runners/cli/src/main/kotlin/cli/main.kt
@@ -1,6 +1,5 @@
package org.jetbrains.dokka
-import kotlinx.cli.*
import org.jetbrains.dokka.DokkaConfiguration.ExternalDocumentationLink
import java.io.File
@@ -8,247 +7,144 @@ import java.net.MalformedURLException
import java.net.URL
import java.net.URLClassLoader
-data class Arguments(
- override var moduleName: String = "",
- override var classpath: MutableList<String> = mutableListOf(),
- override var sourceRoots: MutableList<DokkaConfiguration.SourceRoot> = mutableListOf(),
- override var samples: MutableList<String> = mutableListOf(),
- override var includes: MutableList<String> = mutableListOf(),
- override var includeNonPublic: Boolean = false,
- override var includeRootPackage: Boolean = false,
- override var reportUndocumented: Boolean = false,
- override var skipEmptyPackages: Boolean = false,
- override var skipDeprecated: Boolean = false,
- override var jdkVersion: Int = 6,
- override var sourceLinks: List<DokkaConfiguration.SourceLinkDefinition> = listOf(),
- override var perPackageOptions: List<DokkaConfiguration.PackageOptions> = listOf(),
- override var externalDocumentationLinks: List<DokkaConfiguration.ExternalDocumentationLink> = listOf(),
- override var languageVersion: String? = "",
- override var apiVersion: String? = "",
- override var noStdlibLink: Boolean = false,
- override var noJdkLink: Boolean = false,
- override var suppressedFiles: MutableList<String> = mutableListOf(),
- override var collectInheritedExtensionsFromLibraries: Boolean = false,
- override var analysisPlatform: Platform = Platform.DEFAULT,
- override var targets: MutableList<String> = mutableListOf(),
- var rawPerPackageOptions: MutableList<String> = mutableListOf()
-) : DokkaConfiguration.PassConfiguration
-
-
-data class GlobalArguments(
- override var outputDir: String = "",
- override var format: String = "",
- override var generateIndexPages: Boolean = false,
- override var cacheRoot: String? = null,
- override var passesConfigurations: List<Arguments> = listOf(),
- override var impliedPlatforms: MutableList<String> = mutableListOf()
-) : DokkaConfiguration
-
-class DokkaArgumentsParser {
- companion object {
- fun CommandLineInterface.registerSingleAction(
- 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.registerRepeatingAction(
- 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@registerRepeatingAction.getFlagAction(message) != null) {
- arguments.previous()
- break
- }
- invoke(message)
- }
-
- }
-
- override fun invoke() {
- error("should be never called")
- }
- }
-
- )
-
- }
-
- val cli = CommandLineInterface("dokka")
- val globalArguments = GlobalArguments()
-
- init {
- cli.flagAction(
- listOf("-pass"),
- "Single dokka pass"
- ) {
- globalArguments.passesConfigurations += Arguments()
- }
-
- cli.registerRepeatingAction(
- listOf("-src"),
- "Source file or directory (allows many paths separated by the system path separator)"
- ) {
- globalArguments.passesConfigurations.last().sourceRoots.add(SourceRootImpl.parseSourceRoot(it))
- }
-
- cli.registerRepeatingAction(
- listOf("-srcLink"),
- "Mapping between a source directory and a Web site for browsing the code"
- ) {
- println(it)
- }
-
- cli.registerRepeatingAction(
- listOf("-include"),
- "Markdown files to load (allows many paths separated by the system path separator)"
- ) {
- globalArguments.passesConfigurations.last().includes.add(it)
- }
-
- cli.registerRepeatingAction(
- listOf("-samples"),
- "Source root for samples"
- ) {
- globalArguments.passesConfigurations.last().samples.add(it)
- }
-
- cli.registerSingleAction(
- listOf("-output"),
- "Output directory path"
- ) {
- globalArguments.outputDir = it
- }
-
- cli.registerSingleAction(
- listOf("-format"),
- "Output format (text, html, markdown, jekyll, kotlin-website)"
- ) {
- globalArguments.format = it
- }
-
- cli.registerSingleAction(
- listOf("-module"),
- "Name of the documentation module"
- ) {
- globalArguments.passesConfigurations.last().moduleName = it
- }
-
- cli.registerRepeatingAction(
- listOf("-classpath"),
- "Classpath for symbol resolution"
- ) {
- globalArguments.passesConfigurations.last().classpath.add(it)
- }
-
- cli.flagAction(
- listOf("-nodeprecacted"),
- "Exclude deprecated members from documentation"
- ) {
- globalArguments.passesConfigurations.last().skipDeprecated = true
- }
-
- cli.registerSingleAction(
- listOf("jdkVersion"),
- "Version of JDK to use for linking to JDK JavaDoc"
- ) {
- globalArguments.passesConfigurations.last().jdkVersion = Integer.parseInt(it)
- }
-
- cli.registerRepeatingAction(
- listOf("-impliedPlatforms"),
- "List of implied platforms (comma-separated)"
- ) {
- globalArguments.impliedPlatforms.add(it)
- }
-
- cli.registerSingleAction(
- listOf("-pckageOptions"),
- "List of package passConfiguration in format \"prefix,-deprecated,-privateApi,+warnUndocumented,+suppress;...\" "
- ) {
- globalArguments.passesConfigurations.last().perPackageOptions = parsePerPackageOptions(it)
- }
-
- cli.registerSingleAction(
- listOf("links"),
- "External documentation links in format url^packageListUrl^^url2..."
- ) {
- globalArguments.passesConfigurations.last().externalDocumentationLinks = MainKt.parseLinks(it)
- }
-
- cli.flagAction(
- listOf("-noStdlibLink"),
- "Disable documentation link to stdlib"
- ) {
- globalArguments.passesConfigurations.last().noStdlibLink = true
- }
-
- cli.flagAction(
- listOf("-noJdkLink"),
- "Disable documentation link to jdk"
- ) {
- globalArguments.passesConfigurations.last().noJdkLink = true
- }
-
- cli.registerSingleAction(
- listOf("-cacheRoot"),
- "Path to cache folder, or 'default' to use ~/.cache/dokka, if not provided caching is disabled"
- ) {
- globalArguments.cacheRoot = it
- }
-
- cli.registerSingleAction(
- listOf("-languageVersion"),
- "Language Version to pass to Kotlin Analysis"
- ) {
- globalArguments.passesConfigurations.last().languageVersion = it
- }
-
- cli.registerSingleAction(
- listOf("-apiVesion"),
- "Kotlin Api Version to pass to Kotlin Analysis"
- ) {
- globalArguments.passesConfigurations.last().apiVersion = it
- }
-
- cli.flagAction(
- listOf("-collectInheritedExtensionsFromLibraries"),
- "Search for applicable extensions in libraries"
- ) {
- globalArguments.passesConfigurations.last().collectInheritedExtensionsFromLibraries = true
- }
-
+open class GlobalArguments(parser: DokkaArgumentsParser) : DokkaConfiguration {
+ override val outputDir: String by parser.defaultSingleOption(
+ listOf("-output"),
+ "Output directory path",
+ "")
+
+ override val format: String by parser.defaultSingleOption(
+ listOf("-format"),
+ "Output format (text, html, markdown, jekyll, kotlin-website)",
+ "")
+
+ override val generateIndexPages: Boolean by parser.singleBooleanFlag(
+ listOf("-generateIndexPages"),
+ "Generate index page"
+ )
+
+ override val cacheRoot: String? by parser.defaultSingleOption(
+ listOf("-cacheRoot"),
+ "Path to cache folder, or 'default' to use ~/.cache/dokka, if not provided caching is disabled",
+ null)
+
+ override val impliedPlatforms: List<String> by parser.repeatableOption(
+ listOf("-impliedPlatforms"),
+ "List of implied platforms (comma-separated)"
+ ) { it }
+
+ override val passesConfigurations: List<Arguments> by parser.repeatableFlag(
+ listOf("-pass"),
+ "Single dokka pass"
+ ) {
+ Arguments(parser)
}
+}
- fun parse(args: Array<String>): DokkaConfiguration {
- cli.parseArgs(*args)
-
- return globalArguments
- }
+class Arguments(val parser: DokkaArgumentsParser) : DokkaConfiguration.PassConfiguration {
+ override val moduleName: String by parser.defaultSingleOption(
+ listOf("-module"),
+ "Name of the documentation module",
+ "")
+
+ override val classpath: List<String> by parser.repeatableOption(
+ listOf("-classpath"),
+ "Classpath for symbol resolution"
+ ) { it }
+
+ 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.parseSourceRoot(it) }
+
+ override val samples: List<String> by parser.repeatableOption(
+ listOf("-samples"),
+ "Source root for samples"
+ ) { it }
+
+ override val includes: List<String> by parser.repeatableOption(
+ listOf("-include"),
+ "Markdown files to load (allows many paths separated by the system path separator)"
+ ) { it }
+
+ override val includeNonPublic: Boolean by parser.singleBooleanFlag(
+ listOf("-includeNonPublic"),
+ "Include non public")
+
+ override val includeRootPackage: Boolean by parser.singleBooleanFlag(
+ listOf("-includeRootPackage"),
+ "Include non public")
+
+ override val reportUndocumented: Boolean by parser.singleBooleanFlag(
+ listOf("-reportUndocumented"),
+ "Include non public")
+
+ override val skipEmptyPackages: Boolean by parser.singleBooleanFlag(
+ listOf("-skipEmptyPackages"),
+ "Include non public")
+
+ override val skipDeprecated: Boolean by parser.singleBooleanFlag(
+ listOf("-skipDeprecated"),
+ "Include non public")
+
+ 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.defaultSingleOption(
+ listOf("-languageVersion"),
+ "Language Version to pass to Kotlin Analysis",
+ null)
+
+ override val apiVersion: String? by parser.defaultSingleOption(
+ listOf("-apiVesion"),
+ "Kotlin Api Version to pass to Kotlin Analysis",
+ null
+ )
+
+ override val noStdlibLink: Boolean by parser.singleBooleanFlag(
+ listOf("-noStdlibLink"),
+ "Disable documentation link to stdlib")
+
+ override val noJdkLink: Boolean by parser.singleBooleanFlag(
+ listOf("-noJdkLink"),
+ "Disable documentation link to stdlib")
+
+ override val suppressedFiles: List<String> by parser.repeatableOption(
+ listOf("-suppresedFiles"),
+ "",
+ { it }
+ )
+
+ override val collectInheritedExtensionsFromLibraries: Boolean by parser.singleBooleanFlag(
+ listOf("-collectInheritedExtensionsFromLibraries"),
+ "Search for applicable extensions in libraries")
+
+ override val analysisPlatform: Platform by parser.singleOption(
+ listOf("-analysisPlatform"),
+ "Platform for analysis",
+ { Platform.fromString(it) },
+ { Platform.DEFAULT }
+ )
+
+ override val targets: List<String> by parser.repeatableOption(
+ listOf("-targets"),
+ "Generation targets",
+ { it }
+ )
+
+ override val sourceLinks: List<DokkaConfiguration.SourceLinkDefinition>
+ get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
+ override val perPackageOptions: List<DokkaConfiguration.PackageOptions>
+ get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
+ override val externalDocumentationLinks: List<DokkaConfiguration.ExternalDocumentationLink>
+ get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
}
object MainKt {
-
fun parseLinks(links: String): List<ExternalDocumentationLink> {
val (parsedLinks, parsedOfflineLinks) = links.split("^^")
.map { it.split("^").map { it.trim() }.filter { it.isNotBlank() } }
@@ -312,8 +208,10 @@ object MainKt {
fun main(args: Array<String>) {
- val dokkaArgumentsParser = DokkaArgumentsParser()
- val configuration = dokkaArgumentsParser.parse(args)
+ val parser = DokkaArgumentsParser(args, ParseContext())
+ val parseContext = parser.parseInto(::GlobalArguments)
+
+ val configuration = parseContext
if (configuration.format == "javadoc")
startWithToolsJar(configuration)