func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) { switch ff.Value.(type) { case *StringSlice: default: set.Set(name, ff.Value.String()) } }
// SetFlagsFromYaml goes through all registered flags in the given flagset, // and if they are not already set it attempts to set their values from // the YAML config. It will use the key REPLACE(UPPERCASE(flagname), '-', '_') func SetFlagsFromYaml(fs *flag.FlagSet, rawYaml []byte) (err error) { conf := make(map[string]string) if err = yaml.Unmarshal(rawYaml, conf); err != nil { return } alreadySet := map[string]struct{}{} fs.Visit(func(f *flag.Flag) { alreadySet[f.Name] = struct{}{} }) errs := make([]error, 0) fs.VisitAll(func(f *flag.Flag) { if f.Name == "" { return } if _, ok := alreadySet[f.Name]; ok { return } tag := strings.Replace(strings.ToUpper(f.Name), "-", "_", -1) val, ok := conf[tag] if !ok { return } if serr := fs.Set(f.Name, val); serr != nil { errs = append(errs, fmt.Errorf("invalid value %q for %s: %v", val, tag, serr)) } }) if len(errs) != 0 { err = ErrorSlice(errs) } return }
// SetFlagsFromEnv parses all registered flags in the given flagset, // and if they are not already set it attempts to set their values from // environment variables. Environment variables take the name of the flag but // are UPPERCASE, have the prefix "PREFIX_", and any dashes are replaced by // underscores - for example: some-flag => PREFIX_SOME_FLAG func SetFlagsFromEnv(fs *flag.FlagSet, prefix string) error { var err error alreadySet := make(map[string]bool) fs.Visit(func(f *flag.Flag) { alreadySet[f.Name] = true }) if prefix == "" { prefix = "_" } else { prefix = strings.ToUpper(strings.Replace(prefix, "-", "_", -1)) } fs.VisitAll(func(f *flag.Flag) { if !alreadySet[f.Name] { key := prefix + strings.ToUpper(strings.Replace(f.Name, "-", "_", -1)) val := os.Getenv(key) if val != "" { if serr := fs.Set(f.Name, val); serr != nil { err = fmt.Errorf("invalid value %q for %s: %v", val, key, serr) } } } }) return err }
func normalizeFlags(flags []Flag, set *flag.FlagSet) error { visited := make(map[string]bool) set.Visit(func(f *flag.Flag) { visited[f.Name] = true }) for _, f := range flags { parts := strings.Split(f.GetName(), ",") if len(parts) == 1 { continue } var ff *flag.Flag for _, name := range parts { name = strings.Trim(name, " ") if visited[name] { if ff != nil { return errors.New("Cannot use two forms of the same flag: " + name + " " + ff.Name) } ff = set.Lookup(name) } } if ff == nil { continue } for _, name := range parts { name = strings.Trim(name, " ") set.Set(name, ff.Value.String()) } } return nil }
// ParseConfig parses a config file, using the provided FlagSet to // look up, parse, and store values. func ParseConfig(flags *flag.FlagSet, f io.Reader) error { scanner := bufio.NewScanner(f) for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) if line == "" || strings.HasPrefix(line, "#") { continue } bits := strings.SplitN(line, "=", 2) if len(bits) != 2 { return fmt.Errorf("illegal config line: `%s'", line) } key := strings.TrimSpace(bits[0]) value := strings.TrimSpace(bits[1]) if flag := flags.Lookup(key); flag == nil { return fmt.Errorf("unknown option `%s'", key) } if err := flags.Set(key, value); err != nil { return err } } return nil }
func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) { switch ff.Value.(type) { case Serializeder: set.Set(name, ff.Value.(Serializeder).Serialized()) default: set.Set(name, ff.Value.String()) } }
// SetBindAddrFromAddr sets the value of bindAddr flag from the value // of addr flag. Both flags' Value must be of type IPAddressPort. If the // bindAddr flag is set and the addr flag is unset, it will set bindAddr to // [::]:port of addr. Otherwise, it keeps the original values. func SetBindAddrFromAddr(fs *flag.FlagSet, bindAddrFlagName, addrFlagName string) { if IsSet(fs, bindAddrFlagName) || !IsSet(fs, addrFlagName) { return } addr := *fs.Lookup(addrFlagName).Value.(*IPAddressPort) addr.IP = "::" if err := fs.Set(bindAddrFlagName, addr.String()); err != nil { plog.Panicf("unexpected flags set error: %v", err) } }
// ParseSet parses the config file for the provided flag set. // If the flags are already set, values are overwritten // by the values in the config file. Defaults are not set // if the flag is not in the file. func (g *GlobalConf) ParseSet(flagSetName string, set *flag.FlagSet) { set.VisitAll(func(f *flag.Flag) { if val, ok := getEnv(g.EnvPrefix, flagSetName, f.Name); ok { set.Set(f.Name, val) return } val, found := g.dict.GetString(flagSetName, f.Name) if found { set.Set(f.Name, val) } }) }
// Parses the config file for the provided flag set. // If the flags are already set, values are overwritten // by the values in the config file. Defaults are not set // if the flag is not in the file. func (g *GlobalConf) ParseSet(flagSetName string, set *flag.FlagSet) { set.VisitAll(func(f *flag.Flag) { val := getEnv(flagSetName, f.Name) if val != "" { set.Set(f.Name, val) return } val, found := g.dict.GetString(flagSetName, f.Name) if found { set.Set(f.Name, val) } }) }
// flagsFromEnv parses all registered flags in the given flagset, // and if they are not already set it attempts to set their values from // environment variables. Environment variables take the name of the flag but // are UPPERCASE, have the given prefix, and any dashes are replaced by // underscores - for example: some-flag => PREFIX_SOME_FLAG func flagsFromEnv(prefix string, fs *flag.FlagSet) { alreadySet := make(map[string]bool) fs.Visit(func(f *flag.Flag) { alreadySet[f.Name] = true }) fs.VisitAll(func(f *flag.Flag) { if !alreadySet[f.Name] { key := strings.ToUpper(prefix + "_" + strings.Replace(f.Name, "-", "_", -1)) val := os.Getenv(key) if val != "" { fs.Set(f.Name, val) } } }) }
// ParseFlags parses a map of parameter assignments that are defined by a FlagSet. func ParseFlags(f *flag.FlagSet, values Values) error { for name := range values { if f.Lookup(name) == nil { return fmt.Errorf("%s: no such parameter", name) } } var err error for name, value := range values { err = f.Set(name, value) if err != nil { err = fmt.Errorf("%s: %s", name, err) } } return err }
// from github.com/coreos/etcd // // SetFlagsFromEnv parses all registered flags in the given flagset, // and if they are not already set it attempts to set their values from // environment variables. Environment variables take the name of the flag but // are UPPERCASE, have the prefix `s`, and any dashes are replaced by // underscores - for example: some-flag => ETCD_SOME_FLAG func AddEnvironmentToFlags(s string, fs *flag.FlagSet) error { var err error alreadySet := make(map[string]bool) fs.Visit(func(f *flag.Flag) { alreadySet[f.Name] = true }) fs.VisitAll(func(f *flag.Flag) { if !alreadySet[f.Name] { key := s + "_" + ToEnvironmentKey(f.Name) val := os.Getenv(key) if val != "" { if serr := fs.Set(f.Name, val); serr != nil { err = fmt.Errorf("invalid value %q for %s: %v", val, key, serr) } } } }) return err }
// SetFlagsFromEnv parses all registered flags in the given flagset, // and if they are not already set it attempts to set their values from // environment variables. Environment variables take the name of the flag but // are UPPERCASE, have the prefix "ETCD_", and any dashes are replaced by // underscores - for example: some-flag => ETCD_SOME_FLAG func SetFlagsFromEnv(fs *flag.FlagSet) error { var err error alreadySet := make(map[string]bool) fs.Visit(func(f *flag.Flag) { alreadySet[flagToEnv(f.Name)] = true }) usedEnvKey := make(map[string]bool) fs.VisitAll(func(f *flag.Flag) { key := flagToEnv(f.Name) if !alreadySet[key] { val := os.Getenv(key) if val != "" { usedEnvKey[key] = true if serr := fs.Set(f.Name, val); serr != nil { err = fmt.Errorf("invalid value %q for %s: %v", val, key, serr) } plog.Infof("recognized and used environment variable %s=%s", key, val) } } }) for _, env := range os.Environ() { kv := strings.SplitN(env, "=", 2) if len(kv) != 2 { plog.Warningf("found invalid env %s", env) } if usedEnvKey[kv[0]] { continue } if alreadySet[kv[0]] { plog.Infof("recognized environment variable %s, but unused: shadowed by corresponding flag ", kv[0]) continue } if strings.HasPrefix(env, "ETCD_") { plog.Warningf("unrecognized environment variable %s", env) } } return err }
// Populate sets the flags in set from the environment. The // environment value used will be the name of the flag in upper case, // with '-' changed to '_', and (if prefixis not the empty string) // prepended with prefix and an underscore. So, if prefix is // "DOORMAN", and the flag's name "foo-bar", the environment variable // DOORMAN_FOO_BAR will be used. func Populate(set *flag.FlagSet, prefix string) error { var ( setThroughFlags = make(map[string]bool) knownEnv = make(map[string]bool) err error ) set.Visit(func(f *flag.Flag) { setThroughFlags[f.Name] = true }) set.VisitAll(func(f *flag.Flag) { key := flagToEnv(prefix, f.Name) knownEnv[key] = true val := os.Getenv(key) if val == "" { return } if setThroughFlags[f.Name] { log.Warningf("Recognized environment variable %v, but shadowed by flag %v: won't be used.", key, f.Name) return } if e := set.Set(f.Name, val); e != nil { err = fmt.Errorf("Invalid value %q for %v.", val, key) return } }) for _, env := range os.Environ() { kv := strings.SplitN(env, "=", 2) if len(kv) < 1 { continue } if name := kv[0]; strings.HasPrefix(name, prefix) && !knownEnv[name] { log.Warningf("Unrecognized environment variable %s", name) } } return err }
// SetFlagsFromEnvFile iterates the given flagset and if any flags are not // already set it attempts to set their values from the given env file. Env // files may have KEY=VALUE lines where the environment variable names are // in UPPERCASE, prefixed by the given PREFIX, and dashes are replaced by // underscores. For example, if prefix=PREFIX, some-flag is named // PREFIX_SOME_FLAG. // Comment lines are skipped, but more complex env file parsing is not // performed. func SetFlagsFromEnvFile(fs *flag.FlagSet, prefix string, path string) (err error) { alreadySet := make(map[string]bool) fs.Visit(func(f *flag.Flag) { alreadySet[f.Name] = true }) envs, err := parseEnvFile(path) if err != nil { return err } fs.VisitAll(func(f *flag.Flag) { if !alreadySet[f.Name] { key := prefix + "_" + strings.ToUpper(strings.Replace(f.Name, "-", "_", -1)) val := envs[key] if val != "" { if serr := fs.Set(f.Name, val); serr != nil { err = fmt.Errorf("invalid value %q for %s: %v", val, key, serr) } } } }) return err }
func updateFlagsByConfig(configFile string, flagSet *flag.FlagSet) error { config := struct { Fluentd_Forwarder struct { Retry_interval string `retry-interval` Conn_timeout string `conn-timeout` Write_timeout string `write-timeout` Flush_interval string `flush-interval` Listen_on string `listen-on` To string `to` Buffer_path string `buffer-path` Buffer_chunk_limit string `buffer-chunk-limit` Log_level string `log-level` Ca_certs string `ca-certs` Cpuprofile string `cpuprofile` Log_file string `log-file` } }{} err := gcfg.ReadFileInto(&config, configFile) if err != nil { return err } r := reflect.ValueOf(config.Fluentd_Forwarder) rt := r.Type() for i, l := 0, rt.NumField(); i < l; i += 1 { f := rt.Field(i) fv := r.Field(i) v := fv.String() if v != "" { err := flagSet.Set(string(f.Tag), v) if err != nil { return err } } } return nil }
func TestLoadConfigWithOverride(t *testing.T) { var flagSet flag.FlagSet a := flagSet.Int("a", -1, "for test") b := flagSet.Bool("b", true, "for test") c := flagSet.String("c", "-1", "for test") da := flagSet.Int("d.a", -1, "for test") dc := flagSet.String("d.c", "-1", "for test") flagSet.Set("a", "2") flagSet.Set("b", "false") flagSet.Set("c", "set") flagSet.Set("d.a", "2") flagSet.Set("d.c", "set2") e := loadConfig("config_test.txt", &flagSet, true) if nil != e { t.Error(e) return } if *a != 1 { t.Error("a != 1") } if !*b { t.Error("b != true") } if "abc" != *c { t.Error("c != \"abc\"") } if *da != 1323 { t.Error("d.a != 1323") } if "67" != *dc { t.Errorf("dc != \"67\", actual is %s", *dc) } }
var _ = Describe("Activate", func() { var ( context *cli.Context set *flag.FlagSet ) BeforeEach(func() { os.Clearenv() set = flag.NewFlagSet("test", 0) set.String("profile", "profile-name", "doc") command := cli.Command{Name: "ap"} context = cli.NewContext(nil, set, nil) context.Command = command set.Set("profile", "some-profile") }) Context("When the shell is not supported", func() { It("should error", func() { os.Setenv("SHELL", "not_supported_shell") Expect(BeforeActivateProfile(context)).Should(Equal(errors.New("Sorry, not_supported_shell is not a supported shell"))) }) }) Context("When the resource file doesn't exist", func() { It("should error", func() { os.Setenv("SHELL", "/bin/bash") os.Setenv("HOME", "/tmp") Expect(BeforeActivateProfile(context)).Should(Equal(errors.New("File ~/.bash_profile not found"))) })
var _ = Describe("Deactivate", func() { var ( context *cli.Context set *flag.FlagSet ) BeforeEach(func() { os.Clearenv() set = flag.NewFlagSet("test", 0) set.String("profile", "profile-name", "doc") command := cli.Command{Name: "ap"} context = cli.NewContext(nil, set, nil) context.Command = command set.Set("profile", "some-profile") }) Context("When the shell is not supported", func() { It("should error", func() { os.Setenv("SHELL", "not_supported_shell") Expect(BeforeDeactivateProfile(context)).Should(Equal(errors.New("Sorry, not_supported_shell is not a supported shell"))) }) }) Context("When the resource file doesn't exist", func() { It("should error", func() { os.Setenv("SHELL", "/bin/bash") os.Setenv("HOME", "/tmp") Expect(BeforeDeactivateProfile(context)).Should(Equal(errors.New("File ~/.bash_profile not found"))) })