Working with Clikt
Couple of quick notes on working with Clikt, the Kotlin CLI library:
Using Clikt as a pure parser
If all you want is to turn command line arguments into a data class, without using the Clikt Command abstraction, you can do it as follows:
import com.github.ajalt.clikt.core.NoOpCliktCommand
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.options.required
fun main(vararg args: String) {
  val config: Config = CliParser.parseConfig(*args)
}
data class Config(val username: String)
class CliParser private constructor() : NoOpCliktCommand(
  name = "",
  help = "help text",
) {
  private val username: String by option(help = "the username").required()
  private fun toConfig() = Config(username = username)
  companion object {
    fun parseConfig(vararg args: String): Config =
      CliParser()
        .apply { parse(args.toList()) }
        .toConfig()
  }
}
Injecting the environment as a map
If you want to decouple Clikt from System.getenv you can do so as so:
class CliParser(
  env: Map<String, String> = System.getenv()
) : CliktCommand {
  init {
    context {
      envarReader = env::get
      autoEnvvarPrefix = "MY_APP"
    }
  }
}
Putting them together
import com.github.ajalt.clikt.core.NoOpCliktCommand
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.options.required
fun main(vararg args: String) {
    val config: Config = CliParser.parseConfig(*args)
}
data class Config(val username: String)
class CliParser private constructor(
  env: Map<String, String>
) : NoOpCliktCommand(
  name = "",
  help = "help text",
) {
  init {
    context {
      envarReader = env::get
      autoEnvvarPrefix = "MY_APP"
    }
  }
  private val username: String by option(help = "the username").required()
  private fun toConfig() = Config(username = username)
  companion object {
      fun parseConfig(
          args: List<String>,
          env: Map<String, String> = System.getenv(),
      ): Config =
          CliParser(env)
              .apply { parse(args) }
              .toConfig()
    fun parseConfig(
        vararg args: String,
        env: Map<String, String> = System.getenv(), 
    ): Config = parseConfig(
        args.toList(), 
        env,
    )
  }
}