• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

Kotlin/kotlinx-cli: Pure Kotlin implementation of a generic CLI parser.

原作者: [db:作者] 来自: 网络 收藏 邀请

开源软件名称(OpenSource Name):

Kotlin/kotlinx-cli

开源软件地址(OpenSource Url):

https://github.com/Kotlin/kotlinx-cli

开源编程语言(OpenSource Language):

Kotlin 100.0%

开源软件介绍(OpenSource Introduction):

kotlinx-cli

Kotlin Experimental JetBrains incubator project GitHub license Maven Central

Pure Kotlin implementation of a generic command-line parser.

  • Declarative: describe what your commands and parameters are
  • Platform-agnostic: core library has no platform-specific dependencies and can be used in any Kotlin project
  • Hackable: build extensions on top of it however you like

kotlinx-cli can be used to create user-friendly and flexible command-line interfaces for Kotlin/JVM, Kotlin/Native, and any other Kotlin console applications. Program defines what arguments are expected. kotlinx-cli will figure out how to parse those, reporting errors if the program arguments are invalid, and also generate help and usage messages as well.

Using in your projects

Note that the library is experimental and the API is subject to change.

The library is published to Maven Central repository.

Gradle

  • Add the Maven Central repository if it is not already there:
repositories {
    mavenCentral()
}

In Kotlin multiplatform projects, add the following dependency to a source set (it may be a common or platform specific source set):

kotlin {
    sourceSets {
        commonMain {
             dependencies {
                 implementation("org.jetbrains.kotlinx:kotlinx-cli:0.3.4")
             }
        }
    }
}

kotlinx-cli is also included in Kotlin/Native distribution as an endorsed library, so it's possible to use kotlinx.cli in Kotlin/Native projects without an explicit dependency on it.

If Gradle is used to build a project, turning on endorsed libraries in Kotlin/Native is possible with

kotlin {
    linuxX64("linux") {
        compilations["main"].enableEndorsedLibs = true
    }
}

Important

If kotlinx-cli is added to a gradle project as an explicit dependency, endorsed libraries in Kotlin/Native must be turned off!

Maven

In Kotlin projects, add the following dependency to the dependencies element of pom.xml:

<dependency>
    <groupId>org.jetbrains.kotlinx</groupId>
    <artifactId>kotlinx-cli-jvm</artifactId>
    <version>0.3.4</version>
</dependency>

Command line entities

There are 2 base entity: option and argument.

Option - command line entity started with some prefix (-/--) and can have value as next entity in command line string.

Argument - command line entity which role is connected only with its position.

Command line entities can be several types:

  • ArgType.Boolean
  • ArgType.Int
  • ArgType.String
  • ArgType.Double
  • ArgType.Choice (value can be only from predefined list)

Custom types can be created.

Example

import kotlinx.cli.*

fun produce(result: List<Double>, format: String, outputFileName: String?) {
    outputFileName.let {
        // Print to file.
        ...
    } ?: run {
        // Print to stdout.
        ...
    }
}

fun readFrom(inputFileName: String): String {
    ...
}

fun calculate(inputData: String, eps: Double, debug: Boolean = false): List<Double> {
    ...
}

enum class Format {
    HTML,
    CSV,
    PDF
}

fun main(args: Array<String>) {
    val parser = ArgParser("example")
    val input by parser.option(ArgType.String, shortName = "i", description = "Input file").required()
    val output by parser.option(ArgType.String, shortName = "o", description = "Output file name")
    val format by parser.option(ArgType.Choice<Format>(), shortName = "f", 
    	description = "Format for output file").default(Format.CSV).multiple()
    val stringFormat by parser.option(ArgType.Choice(listOf("html", "csv", "pdf"), { it }), shortName = "sf", 
        description = "Format as string for output file").default("csv").multiple()
    val debug by parser.option(ArgType.Boolean, shortName = "d", description = "Turn on debug mode").default(false)
    val eps by parser.option(ArgType.Double, description = "Observational error").default(0.01)

    parser.parse(args)
    val inputData = readFrom(input)
    val result = calculate(inputData, eps, debug)
    format.forEach {
        produce(result, it, output)
    }
}

It's also possible to use arguments in current example.

...
    val input by parser.argument(ArgType.String, description = "Input file")
    val output by parser.argument(ArgType.String, description = "Output file name").optional()

Auto-generated help message for this example is

Usage: example options_list
Arguments: 
    input -> Input file { String }
    output -> Output file name (optional) { String }
Options: 
    --format, -f [csv] -> Format for output file { Value should be one of [html, csv, pdf] }
    --debug, -d [false] -> Turn on debug mode 
    --eps [0.01] -> Observational error { Double }
    --help, -h -> Usage info

Subcommands

If application has rich command line interface and executes different actions with different arguments, subcommands can be useful.

@file:OptIn(ExperimentalCli::class)

import kotlinx.cli.*

fun main(args: Array<String>) {
	val parser = ArgParser("example")
    val output by parser.option(ArgType.String, "output", "o", "Output file")
    class Summary: Subcommand("summary", "Calculate summary") {
        val invert by option(ArgType.Boolean, "invert", "i", "Invert results").default(false)
        val addendums by argument(ArgType.Int, "addendums", description = "Addendums").vararg()
        var result: Int = 0

        override fun execute() {
            result = addendums.sum()
            result = if (invert!!) -1 * result else result
        }
    }
    class Multiply: Subcommand("mul", "Multiply") {
        val numbers by argument(ArgType.Int, description = "Addendums").vararg()
        var result: Int = 0

        override fun execute() {
            result = numbers.reduce{ acc, it -> acc * it }
        }
    }
    val summary = Summary()
    val multiple = Multiply()
    parser.subcommands(summary, multiple)

    parser.parse(args)
}

Then help information will be available for each subcommand separately.

In case of example summary -h help info will be

Usage: example summary options_list
Arguments: 
    addendums -> Addendums { Int }
Options: 
    --invert, -i -> Invert results 
    --help, -h -> Usage info 

In case of example mul -h help info will be

Usage: example mul options_list
Arguments: 
    numbers -> Addendums { Int }
Options: 
    --help, -h -> Usage info

The boolean property strictSubcommandOptionsOrder defines the allowed order of options and arguments for subcommands. When it is false (default), then the main program's options can be specified everywhere, even after the subcommand. Otherwise, parameters can only be specified after the subcommands where they are defined. For example,

@file:OptIn(ExperimentalCli::class)

import kotlinx.cli.*

fun main(args: Array<String>) {
    val parser = ArgParser("example", strictSubcommandOptionsOrder = true)
    val output by parser.option(ArgType.String, "output", "o", "Output file")

    class Multiply: Subcommand("mul", "Multiply") {
        val numbers by argument(ArgType.Int, description = "Addendums").vararg()
        var result: Int = 0

        override fun execute() {
            result = numbers.reduce{ acc, it -> acc * it }
        }
    }
    val multiple = Multiply()
    parser.subcommands(summary, multiple)

    parser.parse(args)
}

example -o out.txt mul 1 2 3 -o out.txt # OK

example mul 1 2 3 -o out.txt # fail in this case, but OK if strictSubcommandOptionsOrder is false




鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap