Programas de la línea de comandos, Subcomandos

¿Cómo crear subcomandos en programas de la línea de comandos?

Los programas para la línea de comandos soportan el uso de subcomandos. Por ejemplo, para la aplicación git podemos utilizar subcomandos como.

$ git clone
$ git merge
$ git checkcout

Para cada uno de estos subcomandos existe documentación que puede ser desplegada mediante el uso de –help.

El paquete flag permite crear subcomandos mediante el uso de flag.NewFlagSet.

subcomando := flag.NewFlagSet("copiar", flag.ExitOnError)
  • El primer parámetro de NewFlagSet es el nombre del subcomando.
  • El segundo parámetro de NewFlagSet define el comportamiento, que puede ser.
    • flag.ContinueOnError si existe un error en el parseo, continuar.
    • flag.ExitOnError si existe un error en el parseo, terminar con un status code 2.
    • flag.PanicOnError si existe un error en el parseo, invocar panic.

Al utilizar NewFlagSet, grupos de flags pueden ser creados.

En el siguiente ejemplo implementamos subcomandos.

package main

import (
    "flag"
    "fmt"
    "os"
    "strings"
)

func main() {

    // personalizar la ayuda
    flag.Usage = func() {
        documentacion := `Las opciones disponibles son
mayus Convierte el texto a mayúsculas
minus Convierte el texto a minúsculas`
        fmt.Fprintf(os.Stderr, "%s\n", documentacion)
    }

    // crear 2 subcomandos
    subCmdMayus := flag.NewFlagSet("mayus", flag.ExitOnError)
    subCmdMinus := flag.NewFlagSet("minus", flag.ExitOnError)

    // si la lista de argumentos no es la suficiente imprimir la ayuda
    if len(os.Args) == 1 {
        flag.Usage()
        return
    }

    // determinar que subcomando ejecutar
    switch os.Args[1] {
    case "mayus":
        // extraer el argumento -s y convertirlo en mayusculas
        s := subCmdMayus.String("s", "", "Introduzca el texto a convertir en mayúsculas")
        subCmdMayus.Parse(os.Args[2:])
        fmt.Println(strings.ToUpper(*s))
    case "minus":
        // extraer el argumento -s y convertirlo en minusculas
        s := subCmdMinus.String("s", "", "Introduzca el texto a convertir en minúsculas")
        subCmdMinus.Parse(os.Args[2:])
        fmt.Println(strings.ToLower(*s))
    default:
        // mostrar la documentacion
        flag.Usage()
    }
}

Podemos acceder la documentación del primer nivel mediante.

$ go run main.go

Y se desplegará la información.

Las opciones disponibles son
mayus Convierte el texto a mayúsculas
minus Convierte el texto a minúsculas

Para desplegar la documentación del segundo nivel, por ejemplo para el subcomando mayus.

$ go run main.go mayus -h

Y se desplegará la información.

Usage of mayus:
  -s string
        Introduzca el texto a convertir en mayúsculas
exit status 2

Finalmente podemos utilizar el subcomando mayus para realizar la conversión.

$ go run main.go mayus -s "Hola Mundo"

Y se desplegará en la salida.

HOLA MUNDO