func RunModule(key string, module Module, args []string, w io.Writer) { flagSet := flag.NewFlagSet(key, flag.ContinueOnError) flagSet.Usage = func() { module.Help(os.Stderr) flagSet.SetOutput(os.Stderr) flagSet.PrintDefaults() } if adapter, is := module.(*module_adapter); is { gflag.RegisterFlags(key, adapter.obj, flagSet) } else { gflag.RegisterFlags(key, module, flagSet) } err := flagSet.Parse(args) if err != nil { handle(err, flag.ExitOnError) } else { // We make it possible for the module to ask to reparse the flags again. // This gives us the ablility to layer flags on top of config data after // config template has been applied to an object. // We conveniently use function and closures to store copies of the flagSet and args. reparseLock.Lock() reparseFlags[reflect.TypeOf(module)] = func() { // this should be fine here since the first time we parsed ok. flagSet.Parse(args) } reparseLock.Unlock() policy, has := policies[key] if !has { policy = flag.PanicOnError } handle(module.Run(flagSet.Args(), w), policy) handle(module.Close(), policy) } }
func showHelp(out io.Writer) { command.VisitModules(func(v string, module command.Module) { fmt.Fprintf(out, "%s\n", v) buff := new(bytes.Buffer) module.Help(buff) for _, line := range strings.Split(buff.String(), "\n") { fmt.Fprintf(out, " %s\n", line) } // show flags fs := flag.NewFlagSet(v, flag.PanicOnError) cf.RegisterFlags(v, module, fs) fs.PrintDefaults() }) }