Skip to content

Instantly share code, notes, and snippets.

@srid
Created October 24, 2012 22:52
Show Gist options
  • Save srid/3949446 to your computer and use it in GitHub Desktop.
Save srid/3949446 to your computer and use it in GitHub Desktop.
golang simple subcommand parser
// A simple sub command parser based on the flag package
package subcommand
import (
"flag"
"fmt"
"os"
)
type subCommand interface {
Name() string
DefineFlags(*flag.FlagSet)
Run()
}
type subCommandParser struct {
cmd subCommand
fs *flag.FlagSet
}
func Parse(commands ...subCommand) {
scp := make(map[string]*subCommandParser, len(commands))
for _, cmd := range commands {
name := cmd.Name()
scp[name] = &subCommandParser{cmd, flag.NewFlagSet(name, flag.ExitOnError)}
cmd.DefineFlags(scp[name].fs)
}
oldUsage := flag.Usage
flag.Usage = func() {
oldUsage()
for name, sc := range scp {
fmt.Fprintf(os.Stderr, "\n# %s %s\n", os.Args[0], name)
sc.fs.PrintDefaults()
fmt.Fprintf(os.Stderr, "\n")
}
}
flag.Parse()
if flag.NArg() < 1 {
flag.Usage()
os.Exit(1)
}
cmdname := flag.Arg(0)
if sc, ok := scp[cmdname]; ok {
sc.fs.Parse(flag.Args()[1:])
sc.cmd.Run()
} else {
fmt.Fprintf(os.Stderr, "error: %s is not a valid command", cmdname)
flag.Usage()
os.Exit(1)
}
}
@srid
Copy link
Author

srid commented Oct 24, 2012

package main

import (
    "flag"
    "subcommand"
)

type recv struct {
    hideprefix *bool
    filter     *string
}

func (cmd *recv) Name() string {
    return "recv"
}

func (cmd *recv) DefineFlags(fs *flag.FlagSet) {
    cmd.hideprefix = fs.Bool("hideprefix", false, "hide message prefix")
    cmd.filter = fs.String("filter", "", "filter by message key pattern")
}

func (cmd *recv) Run() {
    // real stuff
}

func main() {
    subcommand.Parse(new(recv))
}

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