Subcomandos de línea de comandos

Beginner

This tutorial is from open-source community. Access the source code

Introducción

Este laboratorio tiene como objetivo probar tu capacidad para definir y usar subcomandos con su propio conjunto de flags en Golang.

Subcomandos de línea de comandos

Se te pide crear un programa que soporte dos subcomandos, foo y bar, cada uno con su propio conjunto de flags. El subcomando foo debe tener dos flags, enable y name, mientras que el subcomando bar debe tener un flag, level.

  • El programa debe usar el paquete flag para definir y analizar los flags.
  • El subcomando foo debe tener dos flags, enable y name, ambos de tipo string.
  • El subcomando bar debe tener un flag, level, de tipo int.
  • El programa debe imprimir un mensaje de error si se proporciona un subcomando no válido.
  • El programa debe imprimir los valores de los flags para el subcomando que se invoca.
$ go build command-line-subcommands.go

## Primero invoca el subcomando foo.
$./command-line-subcommands foo -enable -name=joe a1 a2
subcommand 'foo'
enable: true
name: joe
tail: [a1 a2]

## Ahora prueba bar.
$./command-line-subcommands bar -level 8 a1
subcommand 'bar'
level: 8
tail: [a1]

## Pero bar no aceptará los flags de foo.
$./command-line-subcommands bar -enable a1
flag provided but not defined: -enable
Usage of bar:
-level int
level

## A continuación veremos las variables de entorno, otra forma
## común de parametrizar los programas.

A continuación se muestra el código completo:

// Algunas herramientas de línea de comandos, como la herramienta `go` o `git`
// tienen muchos *subcomandos*, cada uno con su propio conjunto de
// flags. Por ejemplo, `go build` y `go get` son dos
// subcomandos diferentes de la herramienta `go`.
// El paquete `flag` nos permite definir fácilmente subcomandos simples
// que tienen sus propios flags.

package main

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

func main() {

    // Declaramos un subcomando usando la función `NewFlagSet`
    // y procedemos a definir nuevos flags específicos
    // para este subcomando.
    fooCmd := flag.NewFlagSet("foo", flag.ExitOnError)
    fooEnable := fooCmd.Bool("enable", false, "enable")
    fooName := fooCmd.String("name", "", "name")

    // Para un subcomando diferente podemos definir diferentes
    // flags admitidos.
    barCmd := flag.NewFlagSet("bar", flag.ExitOnError)
    barLevel := barCmd.Int("level", 0, "level")

    // El subcomando se espera como primer argumento
    // del programa.
    if len(os.Args) < 2 {
        fmt.Println("expected 'foo' or 'bar' subcommands")
        os.Exit(1)
    }

    // Comprobamos qué subcomando se invoca.
    switch os.Args[1] {

    // Para cada subcomando, analizamos sus propios flags y
    // tenemos acceso a los argumentos posicionales finales.
    case "foo":
        fooCmd.Parse(os.Args[2:])
        fmt.Println("subcommand 'foo'")
        fmt.Println("  enable:", *fooEnable)
        fmt.Println("  name:", *fooName)
        fmt.Println("  tail:", fooCmd.Args())
    case "bar":
        barCmd.Parse(os.Args[2:])
        fmt.Println("subcommand 'bar'")
        fmt.Println("  level:", *barLevel)
        fmt.Println("  tail:", barCmd.Args())
    default:
        fmt.Println("expected 'foo' or 'bar' subcommands")
        os.Exit(1)
    }
}

Resumen

En este laboratorio, aprendiste cómo definir y usar subcomandos con su propio conjunto de flags en Golang utilizando el paquete flag. También aprendiste cómo analizar los flags para cada subcomando y acceder a los argumentos posicionales finales.