Skip to content

Instantly share code, notes, and snippets.

@hnakamur
Last active October 28, 2015 02:32
Show Gist options
  • Save hnakamur/3c8fba54b792536a196c to your computer and use it in GitHub Desktop.
Save hnakamur/3c8fba54b792536a196c to your computer and use it in GitHub Desktop.
Tried to use subcommands with github.com/ogier/pflag but failed
package main
import (
"fmt"
"os"
flag "github.com/ogier/pflag"
)
var usage = `Usage argtest [Globals] <Command> [Options]
Commands:
put Put something
get Get something
Globals Options:
`
var subcommandOptionsUsageFormat = "\nOptions for subcommand \"%s\":\n"
func subcommandUsageFunc(subcommand string, fs *flag.FlagSet) func() {
return func() {
flag.Usage()
fmt.Printf(subcommandOptionsUsageFormat, subcommand)
fs.PrintDefaults()
}
}
func main() {
var (
opt1 = flag.StringP("opt1", "o", "default-value", "First string option")
opt2 = flag.StringP("opt2", "p", "default-value", "Second string option")
)
flag.Usage = func() {
fmt.Print(usage)
flag.PrintDefaults()
}
flag.Parse()
args := flag.Args()
if len(args) == 0 {
flag.Usage()
os.Exit(1)
}
fmt.Println("opt1:", *opt1)
fmt.Println("opt2:", *opt2)
switch args[0] {
case "put":
PutCommand(args[1:])
case "get":
GetCommand(args[1:])
default:
flag.Usage()
os.Exit(1)
}
}
func PutCommand(args []string) {
fs := flag.NewFlagSet("put", flag.ExitOnError)
putOpt := fs.StringP("put-opt", "p", "default-value", "Put option")
fs.Usage = subcommandUsageFunc("put", fs)
fs.Parse(args)
if len(args) == 0 {
fs.Usage()
os.Exit(1)
}
fmt.Println("args:", fs.Args())
fmt.Println("putopt:", *putOpt)
}
func GetCommand(args []string) {
fs := flag.NewFlagSet("get", flag.ExitOnError)
getOpt := fs.StringP("get-opt", "g", "default-value", "Get option")
fs.Usage = subcommandUsageFunc("get", fs)
fs.Parse(args)
if len(args) == 0 {
fs.Usage()
os.Exit(1)
}
fmt.Println("args:", fs.Args())
fmt.Println("getopt:", *getOpt)
}
@hnakamur
Copy link
Author

This code is based on https://gist.github.com/hnakamur/2512fd35b8e0b41d2c08, and I replaced flag.String with flag.StringP to use long and short options.

$ go build -o pflag-example
$ ./pflag-example -h
Usage argtest [Globals] <Command> [Options]
Commands:
  put Put something
  get Get something

Globals Options:
  -o, --opt1="default-value": First string option
  -p, --opt2="default-value": Second string option

However the command below does not work as I expected. I would like to see the options usage for the subcommand "put" here.

$ ./pflag-example put -h
Usage argtest [Globals] <Command> [Options]
Commands:
  put Put something
  get Get something

Globals Options:
  -o, --opt1="default-value": First string option
  -p, --opt2="default-value": Second string option

I expect that the command below are parsed successfully, but it is not.

$ ./pflag-example put --put-opt foo
unknown flag: --put-opt
Usage argtest [Globals] <Command> [Options]
Commands:
  put Put something
  get Get something

Globals Options:
  -o, --opt1="default-value": First string option
  -p, --opt2="default-value": Second string option

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment