Command Line Flags in Kotlin

Here’s the translation of the Go code to Kotlin, along with explanations in Markdown format suitable for Hugo:

Command-line flags are a common way to specify options for command-line programs. For example, in wc -l the -l is a command-line flag.

Kotlin provides several libraries for parsing command-line arguments. In this example, we’ll use the kotlinx.cli library, which offers a simple and expressive way to define and parse command-line options.

First, add the kotlinx.cli dependency to your project. If you’re using Gradle, add this to your build.gradle.kts file:

dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-cli:0.3.5")
}

Now, let’s implement our example command-line program:

import kotlinx.cli.*

fun main(args: Array<String>) {
    val parser = ArgParser("example")
    
    // Basic flag declarations are available for string, integer, and boolean options.
    // Here we declare a string option 'word' with a default value "foo" and a short description.
    val word by parser.option(ArgType.String, fullName = "word", shortName = "w", description = "a string")
        .default("foo")
    
    // This declares 'numb' and 'fork' options, using a similar approach to the 'word' option.
    val numb by parser.option(ArgType.Int, fullName = "numb", shortName = "n", description = "an int")
        .default(42)
    val fork by parser.option(ArgType.Boolean, fullName = "fork", shortName = "f", description = "a bool")
        .default(false)
    
    // It's also possible to declare an option that uses an existing var declared elsewhere in the program.
    var svar = "bar"
    parser.option(ArgType.String, fullName = "svar", shortName = "s", description = "a string var")
        .default(svar)
        .addValidator {
            svar = it
        }
    
    // Parse the command-line arguments
    parser.parse(args)
    
    // Here we'll just dump out the parsed options and any trailing positional arguments.
    println("word: $word")
    println("numb: $numb")
    println("fork: $fork")
    println("svar: $svar")
    println("tail: ${parser.unknownOption}")
}

To experiment with the command-line flags program, first compile it and then run the resulting JAR file directly.

$ kotlinc command-line-flags.kt -include-runtime -d command-line-flags.jar

Try out the built program by first giving it values for all flags:

$ java -jar command-line-flags.jar -word opt -numb 7 -fork -svar flag
word: opt
numb: 7
fork: true
svar: flag
tail: []

Note that if you omit flags, they automatically take their default values:

$ java -jar command-line-flags.jar -word opt
word: opt
numb: 42
fork: false
svar: bar
tail: []

Trailing positional arguments can be provided after any flags:

$ java -jar command-line-flags.jar -word opt a1 a2 a3
word: opt
...
tail: [a1, a2, a3]

Use -h or --help flags to get automatically generated help text for the command-line program:

$ java -jar command-line-flags.jar -h
Usage: example options_list
Options:
    --word, -w -> a string (default: foo)
    --numb, -n -> an int (default: 42)
    --fork, -f -> a bool (default: false)
    --svar, -s -> a string var (default: bar)
    --help, -h -> Usage info

If you provide a flag that wasn’t specified, the program will print an error message and show the help text again.

$ java -jar command-line-flags.jar -wat
Error: Unknown option: wat
Usage: example options_list
Options:
...

This Kotlin implementation uses the kotlinx.cli library, which provides a more idiomatic and type-safe approach to command-line argument parsing compared to the basic flag package in Go. The overall structure and functionality remain similar, allowing for easy definition and parsing of various types of command-line options.