Go Cookbook
上QQ阅读APP看书,第一时间看更新

How to do it...

These steps cover writing and running your application:

  1. From your terminal/console application, create a new directory called chapter2/cmdargs and navigate to that directory.
  1. Copy tests from https://github.com/agtorre/go-cookbook/tree/master/chapter2/cmdargs, or use this as an exercise to write some of your own code!
  2. Create a file called cmdargs.go with the following contents:
        package main
import (
"flag"
"fmt"
"os"
)
const version = "1.0.0"
const usage = `Usage:
%s [command]
Commands:
Greet
Version
`
const greetUsage = `Usage:
%s greet name [flag]
Positional Arguments:
name
the name to greet
Flags:
`
// MenuConf holds all the levels
// for a nested cmd line argument
type MenuConf struct {
Goodbye bool
}
// SetupMenu initializes the base flags
func (m *MenuConf) SetupMenu() *flag.FlagSet {
menu := flag.NewFlagSet("menu", flag.ExitOnError)
menu.Usage = func() {
fmt.Printf(usage, os.Args[0])
menu.PrintDefaults()
}
return menu
}
// GetSubMenu return a flag set for a submenu
func (m *MenuConf) GetSubMenu() *flag.FlagSet {
submenu := flag.NewFlagSet("submenu", flag.ExitOnError)
submenu.BoolVar(&m.Goodbye, "goodbye", false, "Say goodbye
instead of hello")
submenu.Usage = func() {
fmt.Printf(greetUsage, os.Args[0])
submenu.PrintDefaults()
}
return submenu
}
// Greet will be invoked by the greet command
func (m *MenuConf) Greet(name string) {
if m.Goodbye {
fmt.Println("Goodbye " + name + "!")
} else {
fmt.Println("Hello " + name + "!")
}
}
// Version prints the current version that is
// stored as a const
func (m *MenuConf) Version() {
fmt.Println("Version: " + version)
}
  1. Create a file called main.go with the following contents:
        package main

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

func main() {
c := MenuConf{}
menu := c.SetupMenu()
menu.Parse(os.Args[1:])

// we use arguments to switch between commands
// flags are also an argument
if len(os.Args) > 1 {
// we don't care about case
switch strings.ToLower(os.Args[1]) {
case "version":
c.Version()
case "greet":
f := c.GetSubMenu()
if len(os.Args) < 3 {
f.Usage()
return
}
if len(os.Args) > 3 {
if.Parse(os.Args[3:])
}
c.Greet(os.Args[2])
default:
fmt.Println("Invalid command")
menu.Usage()
return
}
} else {
menu.Usage()
return
}
}
  1. Run go build.
  2. Run the following commands and try a few other combinations of arguments:
      $./cmdargs -h 
Usage:

./cmdargs [command]

Commands:
Greet
Version

$./cmdargs version
Version: 1.0.0

$./cmdargs greet
Usage:

./cmdargs greet name [flag]

Positional Arguments:
name
the name to greet

Flags:
-goodbye
Say goodbye instead of hello

$./cmdargs greet reader
Hello reader!

$./cmdargs greet reader -goodbye
Goodbye reader!
  1. If you copied or wrote your own tests, go up one directory and run go test, and ensure all tests pass.