Exemplo n.º 1
0
func loadConfig(nm string, flagSet *flag.FlagSet, isOverride bool) error {
	f, e := os.Open(nm)
	if nil != e {
		return fmt.Errorf("load config '%s' failed, %v", nm, e)
	}

	var res map[string]interface{}
	e = json.NewDecoder(f).Decode(&res)
	if nil != e {
		return fmt.Errorf("load config '%s' failed, %v", nm, e)
	}

	actual := map[string]string{}
	fn := func(f *flag.Flag) {
		actual[f.Name] = f.Name
	}
	if nil == flagSet {
		flag.Visit(fn)
	} else {
		flagSet.Visit(fn)
	}

	e = assignFlagSet("", res, flagSet, actual, isOverride)
	if nil != e {
		return fmt.Errorf("load config '%s' failed, %v", nm, e)
	}
	return nil
}
Exemplo n.º 2
0
// 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
}
Exemplo n.º 3
0
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, " ")
			if !visited[name] {
				copyFlag(name, ff, set)
			}
		}
	}
	return nil
}
Exemplo n.º 4
0
// 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
}
Exemplo n.º 5
0
// ParseSet parses the given flagset. The specified prefix will be applied to
// the environment variable names.
func ParseSet(prefix string, set *flag.FlagSet) error {
	var explicit []*flag.Flag
	var all []*flag.Flag
	set.Visit(func(f *flag.Flag) {
		explicit = append(explicit, f)
	})

	var err error
	set.VisitAll(func(f *flag.Flag) {
		if err != nil {
			return
		}
		all = append(all, f)
		if !contains(explicit, f) {
			name := strings.Replace(f.Name, ".", "_", -1)
			name = strings.Replace(name, "-", "_", -1)
			if prefix != "" {
				name = prefix + name
			}
			name = strings.ToUpper(name)
			val := os.Getenv(name)
			if val != "" {
				if ferr := f.Value.Set(val); ferr != nil {
					err = fmt.Errorf("failed to set flag %q with value %q", f.Name, val)
				}
			}
		}
	})
	return err
}
Exemplo n.º 6
0
func IsSet(fs *flag.FlagSet, name string) bool {
	set := false
	fs.Visit(func(f *flag.Flag) {
		if f.Name == name {
			set = true
		}
	})
	return set
}
Exemplo n.º 7
0
// IsFlagSet returns true if the specified flag has been set on
// the command line.
func IsFlagSet(fs *flag.FlagSet, name string) bool {
	found := false
	fs.Visit(func(f *flag.Flag) {
		if f.Name == name {
			found = true
		}
	})
	return found
}
Exemplo n.º 8
0
Arquivo: utils.go Projeto: hawx/img
// FlagVisited determines whether the named flag has been visited in the FlagSet
// given. This is helpful if you want to have a flag that triggers an action
// when given, but is not a boolean flag.
func FlagVisited(name string, flags flag.FlagSet) (didFind bool) {
	toFind := flags.Lookup(name)

	flags.Visit(func(f *flag.Flag) {
		if f == toFind {
			didFind = true
		}
	})

	return
}
Exemplo n.º 9
0
func loadActualFlags(flagSet *flag.FlagSet) map[string]string {
	actual := map[string]string{}
	fn := func(f *flag.Flag) {
		actual[f.Name] = f.Name
	}
	if nil == flagSet {
		flag.Visit(fn)
	} else {
		flagSet.Visit(fn)
	}
	return actual
}
Exemplo n.º 10
0
Arquivo: flags.go Projeto: ainoya/fune
// EnabledActionsFromFlags returns value as an array of string
// that is assigned to a command line flag name `enabledActionsFlagName`.
func EnabledActionsFromFlags(fs *flag.FlagSet, enabledActionsFlagName string) ([]string, error) {
	visited := make(map[string]struct{})
	fs.Visit(func(f *flag.Flag) {
		visited[f.Name] = struct{}{}
	})

	_, enabledActionsFlagIsSet := visited[enabledActionsFlagName]

	if enabledActionsFlagIsSet {
		enabledActions := *fs.Lookup(enabledActionsFlagName).Value.(*ActionNames)
		return enabledActions, nil
	}

	return []string{}, nil
}
Exemplo n.º 11
0
// 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)
			}
		}
	})
}
Exemplo n.º 12
0
// 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 given prefix  and any dashes are replaced by
// underscores - for example: some-flag => ETCD_SOME_FLAG
func SetFlagsFromEnv(prefix string, fs *flag.FlagSet) error {
	var err error
	alreadySet := make(map[string]bool)
	fs.Visit(func(f *flag.Flag) {
		alreadySet[flagToEnv(prefix, f.Name)] = true
	})
	usedEnvKey := make(map[string]bool)
	fs.VisitAll(func(f *flag.Flag) {
		err = setFlagFromEnv(fs, prefix, f.Name, usedEnvKey, alreadySet, true)
	})

	verifyEnv(prefix, usedEnvKey, alreadySet)

	return err
}
Exemplo n.º 13
0
func mustNotHave(fset *flag.FlagSet, keys ...string) error {
	for _, key := range keys {
		found := false
		fset.Visit(
			func(f *flag.Flag) {
				if f.Name == key {
					found = true
				}
			})
		if found {
			return fmt.Errorf("Invalid flags. Flag '%s' cannot appear for this operation", key)
		}
	}
	return nil
}
Exemplo n.º 14
0
func mustHave(fset *flag.FlagSet, keys ...string) error {
	for _, key := range keys {
		found := false
		fset.Visit(
			func(f *flag.Flag) {
				if f.Name == key {
					found = true
				}
			})
		if !found {
			flag := fset.Lookup(key)
			if flag == nil || flag.DefValue == "" {
				return fmt.Errorf("Invalid flags. Flag '%s' is required for this operation", key)
			}
		}
	}
	return nil
}
Exemplo n.º 15
0
// 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
}
Exemplo n.º 16
0
// MustFlag sets flags that are skipped by dst.Parse when p contains
// the respective key for flag.Flag.Name.
//
// It's use is recommended with command line arguments as in:
// 	flag.Parse()
// 	p.MustFlag(flag.CommandLine)
func (p *Properties) MustFlag(dst *flag.FlagSet) {
	m := make(map[string]*flag.Flag)
	dst.VisitAll(func(f *flag.Flag) {
		m[f.Name] = f
	})
	dst.Visit(func(f *flag.Flag) {
		delete(m, f.Name) // overridden
	})

	for name, f := range m {
		v, ok := p.Get(name)
		if !ok {
			continue
		}

		if err := f.Value.Set(v); err != nil {
			ErrorHandler(err)
		}
	}
}
Exemplo n.º 17
0
// 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
}
Exemplo n.º 18
0
// 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
}
Exemplo n.º 19
0
// 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
}
Exemplo n.º 20
0
// ParseFile parses the specified configuration file and populates the flags
// in the flag.FlagSet based on the contents of the file.
func ParseFile(flags *flag.FlagSet, filename string) {
	if filename == "" {
		return
	}

	var (
		explicit []*flag.Flag
		all      []*flag.Flag
	)

	config := readConfig(filename)

	flags.Visit(func(f *flag.Flag) {
		explicit = append(explicit, f)
	})

	flags.VisitAll(func(f *flag.Flag) {
		all = append(all, f)
		if !contains(explicit, f) {
			val := config[f.Name]
			if val != "" {
				err := f.Value.Set(val)
				if err != nil {
					log.Fatalf("Failed to set flag %s with value %s", f.Name, val)
				}
			}
		}
	})
Outer:
	for name, val := range config {
		for _, f := range all {
			if f.Name == name {
				continue Outer
			}
		}
		log.Fatalf("Unknown flag %s=%s in config file.", name, val)
	}
}
Exemplo n.º 21
0
// URLsFromFlags decides what URLs should be using two different flags
// as datasources. The first flag's Value must be of type URLs, while
// the second must be of type IPAddressPort. If both of these flags
// are set, an error will be returned. If only the first flag is set,
// the underlying url.URL objects will be returned unmodified. If the
// second flag happens to be set, the underlying IPAddressPort will be
// converted to a url.URL and returned. The Scheme of the returned
// url.URL will be http unless the provided TLSInfo object is non-empty.
// If neither of the flags have been explicitly set, the default value
// of the first flag will be returned unmodified.
func URLsFromFlags(fs *flag.FlagSet, urlsFlagName string, addrFlagName string, tlsInfo transport.TLSInfo) ([]url.URL, error) {
	visited := make(map[string]struct{})
	fs.Visit(func(f *flag.Flag) {
		visited[f.Name] = struct{}{}
	})

	_, urlsFlagIsSet := visited[urlsFlagName]
	_, addrFlagIsSet := visited[addrFlagName]

	if addrFlagIsSet {
		if urlsFlagIsSet {
			return nil, fmt.Errorf("Set only one of flags -%s and -%s", urlsFlagName, addrFlagName)
		}

		addr := *fs.Lookup(addrFlagName).Value.(*IPAddressPort)
		addrURL := url.URL{Scheme: "http", Host: addr.String()}
		if !tlsInfo.Empty() {
			addrURL.Scheme = "https"
		}
		return []url.URL{addrURL}, nil
	}

	return []url.URL(*fs.Lookup(urlsFlagName).Value.(*URLsValue)), nil
}
Exemplo n.º 22
0
func (flags Flags) FromFlagSet(fs *flag.FlagSet) Flags {
	fs.Visit(func(f *flag.Flag) {
		flags[f.Name] = f.Value.String()
	})
	return flags
}
Exemplo n.º 23
0
// resolveConfig parses command line arguments and loads config file to
// return config.Config information.
func resolveConfig(fs *flag.FlagSet, argv []string) (*config.Config, error) {
	conf := &config.Config{}

	var (
		conffile      = fs.String("conf", config.DefaultConfig.Conffile, "Config file path (Configs in this file are over-written by command line options)")
		apibase       = fs.String("apibase", config.DefaultConfig.Apibase, "API base")
		pidfile       = fs.String("pidfile", config.DefaultConfig.Pidfile, "File containing PID")
		root          = fs.String("root", config.DefaultConfig.Root, "Directory containing variable state information")
		apikey        = fs.String("apikey", "", "(DEPRECATED) API key from mackerel.io web site")
		diagnostic    = fs.Bool("diagnostic", false, "Enables diagnostic features")
		verbose       bool
		roleFullnames roleFullnamesFlag
	)
	fs.BoolVar(&verbose, "verbose", config.DefaultConfig.Verbose, "Toggle verbosity")
	fs.BoolVar(&verbose, "v", config.DefaultConfig.Verbose, "Toggle verbosity (shorthand)")

	// The value of "role" option is internally "roll fullname",
	// but we call it "role" here for ease.
	fs.Var(&roleFullnames, "role", "Set this host's roles (format: <service>:<role>)")

	fs.Parse(argv)

	conf, confErr := config.LoadConfig(*conffile)
	conf.Conffile = *conffile
	if confErr != nil {
		return nil, fmt.Errorf("Failed to load the config file: %s", confErr)
	}

	// overwrite config from file by config from args
	fs.Visit(func(f *flag.Flag) {
		switch f.Name {
		case "apibase":
			conf.Apibase = *apibase
		case "apikey":
			conf.Apikey = *apikey
		case "pidfile":
			conf.Pidfile = *pidfile
		case "root":
			conf.Root = *root
		case "diagnostic":
			conf.Diagnostic = *diagnostic
		case "verbose", "v":
			conf.Verbose = verbose
		case "role":
			conf.Roles = roleFullnames
		}
	})

	r := []string{}
	for _, roleFullName := range conf.Roles {
		if !roleFullnamePattern.MatchString(roleFullName) {
			logger.Errorf("Bad format for role fullname (expecting <service>:<role>. Alphabet, numbers, hyphens and underscores are acceptable, but the first character must not be a hyphen or an underscore.): '%s'", roleFullName)
		} else {
			r = append(r, roleFullName)
		}
	}
	conf.Roles = r

	if conf.Verbose && conf.Silent {
		logger.Warningf("both of `verbose` and `silent` option are specified. In this case, `verbose` get preference over `silent`")
	}

	if conf.Apikey == "" {
		return nil, fmt.Errorf("Apikey must be specified in the config file (or by the DEPRECATED command-line flag)")
	}
	return conf, nil
}