Clikt: Potente framework CLI para Kotlin
Clikt es un framework moderno y ligero para crear aplicaciones de consola (CLI) en el lenguaje Kotlin. A diferencia de muchas otras bibliotecas, Clikt utiliza un enfoque declarativo, permitiendo describir la estructura de los comandos y sus parámetros mediante anotaciones simples y expresiones lambda. Esto hace que el código sea limpio, legible y fácil de mantener. La biblioteca es ideal tanto para pequeñas utilidades como para interfaces de línea de comandos complejas de múltiples niveles.
Características clave de Clikt
- Sintaxis declarativa: Definición de comandos, opciones y argumentos a través de DSL (Lenguaje Específico del Dominio) o anotaciones.
- Generación automática de ayuda: Clikt crea automáticamente un mensaje
--helphermoso y estructurado basado en sus definiciones. - Soporte para comandos anidados: Cree jerarquías de comandos (por ejemplo,
git commit,git push) con un mecanismo simple de subcomandos. - Validación de valores: Mecanismos integrados para verificar tipos, rangos, formatos y condiciones personalizadas.
- Autocompletado: Soporte nativo para generar scripts de autocompletado para Bash, Zsh y Fish.
- Capacidad de prueba: Herramientas convenientes para probar aplicaciones CLI sin ejecutarlas realmente en la terminal.
Instalación y configuración
Para comenzar, agregue la dependencia a su build.gradle.kts:
repositories { mavenCentral()}
dependencies { implementation("com.github.ajalt.clikt:clikt:4.4.0")}Para Maven use:
<dependency> <groupId>com.github.ajalt.clikt</groupId> <artifactId>clikt</artifactId> <version>4.4.0</version></dependency>Ejemplo básico: saludo
Creemos un comando simple que recibe el nombre de un usuario y una bandera opcional para saludar en diferentes idiomas.
import com.github.ajalt.clikt.core.CliktCommandimport com.github.ajalt.clikt.parameters.arguments.argumentimport com.github.ajalt.clikt.parameters.options.flagimport com.github.ajalt.clikt.parameters.options.option
class Greet : CliktCommand() { val name: String by argument(help = "Nombre del usuario") val formal: Boolean by option("--formal", "-f", help = "Saludo formal").flag()
override fun run() { val greeting = if (formal) "Hola" else "¡Hola" echo("$greeting, $name!") }}
fun main(args: Array<String>) = Greet().main(args)Ejecución desde la línea de comandos:
$ kotlin greet.kts Juan¡Hola, Juan!
$ kotlin greet.kts --formal JuanHola, Juan!
$ kotlin greet.kts --helpUsage: greet [<options>] <name>
Nombre del usuario
Options: -f, --formal Saludo formal -h, --help Show this message and exitEjemplo avanzado: trabajo con archivos y subcomandos
Consideremos un escenario más complejo: una utilidad para trabajar con archivos de texto con soporte para los subcomandos count y search.
import com.github.ajalt.clikt.core.CliktCommandimport com.github.ajalt.clikt.core.subcommandsimport com.github.ajalt.clikt.parameters.arguments.argumentimport com.github.ajalt.clikt.parameters.options.defaultimport com.github.ajalt.clikt.parameters.options.optionimport java.io.File
class FileTool : CliktCommand() { override fun run() = Unit // El comando raíz no hace nada}
class Count : CliktCommand(help = "Contar líneas en un archivo") { val file: File by argument(help = "Ruta al archivo") .validate { require(it.exists()) { "Archivo no encontrado: $it" } }
override f