Open5
【Go】flagの使い方

FlagSetの活用
set := flag.NewFlagSet("get", flag.ExitOnError)
st := set.String("st", "default", "set string")
it := set.Int("it", 0, "set int")
fmt.Println(*st)
fmt.Println(*it)

fmt.Println(os.Args)
flag.Parse()
fmt.Println(flag.Args()) // os.Args[1:]が表示される

入力されたサブコマンドに対応した処理を行う。
func main() {
flag.Parse()
getCmd := flag.NewFlagSet("get", flag.ExitOnError)
setCmd := flag.NewFlagSet("set", flag.ExitOnError)
reqCmd := flag.NewFlagSet("request", flag.ExitOnError)
fmt.Println(getCmd.Name())
cmds := []*flag.FlagSet{getCmd, setCmd, reqCmd}
subCommands := os.Args[1:]
for _, c := range cmds {
if c.Name() == subCommands[0] {
fmt.Printf("command is %s", subCommands[0])
}
}
}

Commandインターフェースとコマンドごとの構造体を定義して、対応したサービス処理を実装する。
package main
import (
"flag"
"fmt"
"os"
)
func main() {
flag.Parse()
cmds := []Command{
NewGetCommand(),
NewSetCommand(),
}
subCommands := os.Args[1:]
for _, c := range cmds {
if c.Name() == subCommands[0] {
c.Service()
}
}
}
type Command interface {
Name() string
Service() error
}
type GetCommand struct {
FlagSet *flag.FlagSet
}
func NewGetCommand() *GetCommand {
cmd := flag.NewFlagSet("get", flag.ExitOnError)
return &GetCommand{
FlagSet: cmd,
}
}
func (g *GetCommand) Name() string {
return g.FlagSet.Name()
}
func (g *GetCommand) Service() error {
fmt.Println("run get")
return nil
}
type SetCommand struct {
FlagSet *flag.FlagSet
}
func NewSetCommand() *SetCommand {
cmd := flag.NewFlagSet("set", flag.ExitOnError)
return &SetCommand{
FlagSet: cmd,
}
}
func (s *SetCommand) Name() string {
return s.FlagSet.Name()
}
func (s *SetCommand) Service() error {
fmt.Println("run set")
return nil
}

構造体を通してサブコマンド以降を引き渡す。
package main
import (
"flag"
"fmt"
"log"
"os"
)
func main() {
getCmd := NewGetCommand()
setCmd := NewSetCommand()
cmds := []Command{getCmd, setCmd}
if err := ExecSubCommand(cmds); err != nil {
log.Fatal(err)
}
}
func ExecSubCommand(cmds []Command) error {
subCommands := os.Args[1:]
for _, c := range cmds {
if c.Name() == subCommands[0] {
if err := c.Parse(); err != nil {
return fmt.Errorf("failed flag parse: %v", err)
}
if err := c.RunCommand(); err != nil {
return fmt.Errorf("failed execute command: %v", err)
}
break
}
}
return nil
}
type Command interface {
Name() string
RunCommand() error
Parse() error
}
type GetCommand struct {
FlagSet *flag.FlagSet
Key *string
}
func NewGetCommand() *GetCommand {
cmd := flag.NewFlagSet("get", flag.ExitOnError)
key := cmd.String("key", "", "get key")
return &GetCommand{
FlagSet: cmd,
Key: key,
}
}
func (g *GetCommand) Name() string {
return g.FlagSet.Name()
}
func (g *GetCommand) RunCommand() error {
fmt.Println("run get")
fmt.Printf("set key: %s", *g.Key)
return nil
}
func (g *GetCommand) Parse() error {
return g.FlagSet.Parse(os.Args[2:])
}
type SetCommand struct {
FlagSet *flag.FlagSet
Key *string
Value *string
}
func NewSetCommand() *SetCommand {
cmd := flag.NewFlagSet("set", flag.ExitOnError)
key := cmd.String("key", "", "set key")
value := cmd.String("value", "", "set value")
return &SetCommand{
FlagSet: cmd,
Key: key,
Value: value,
}
}
func (s *SetCommand) Name() string {
return s.FlagSet.Name()
}
func (s *SetCommand) RunCommand() error {
fmt.Println("executed set")
fmt.Printf("set key: %s, value: %s", *s.Key, *s.Value)
return nil
}
func (s *SetCommand) Parse() error {
return s.FlagSet.Parse(os.Args[2:])
}