diff options
author | Dan Duvall <dduvall@wikimedia.org> | 2018-03-06 20:31:58 -0800 |
---|---|---|
committer | Dan Duvall <dduvall@wikimedia.org> | 2018-03-19 15:55:16 -0700 |
commit | eb9b69dd3d710cb7afa1dfb6e23a5987842b21cc (patch) | |
tree | 049b11cc885e4e9f54aac8981c91a1bf3620e7af /vendor/github.com/pborman/getopt/v2/enum.go | |
parent | 6896e655eb5cc88b90e66979bc2d862eb92cbb9f (diff) | |
download | blubber-eb9b69dd3d710cb7afa1dfb6e23a5987842b21cc.tar.gz |
Allow for configuration policies
Summary:
Implements a rough interface for validating configuration against
arbitrary policy rules. Policies are provided as YAML and passed via the
command line as file paths or remote URIs.
The format of policies is:
enforcements:
- path: <path>
rule: <rule>
Where `<path>` is a YAML-ish path to a config field and `<rule>` is any
expression our config validator understands (expressions built in by the
validator library and custom tags defined in `config.validation.go`).
Example policy:
enforcements:
- path: variants.production.base
rule: oneof=debian:jessie debian:stretch
- path: variants.production.runs.as
rule: ne=foo
- path: variants.production.node.dependencies
rule: isfalse
Command flag parsing was implemented in `main.go` to support the new
`--policy=uri` flag and improve existing handling of `--version` and the
usage statement.
Test Plan: Run `go test ./...`.
Reviewers: thcipriani, demon, hashar, mmodell, #release-engineering-team
Reviewed By: thcipriani, #release-engineering-team
Tags: #release-engineering-team
Differential Revision: https://phabricator.wikimedia.org/D999
Diffstat (limited to 'vendor/github.com/pborman/getopt/v2/enum.go')
-rw-r--r-- | vendor/github.com/pborman/getopt/v2/enum.go | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/vendor/github.com/pborman/getopt/v2/enum.go b/vendor/github.com/pborman/getopt/v2/enum.go new file mode 100644 index 0000000..1ca6ff9 --- /dev/null +++ b/vendor/github.com/pborman/getopt/v2/enum.go @@ -0,0 +1,79 @@ +// Copyright 2017 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package getopt + +import ( + "errors" + "fmt" + "sync" +) + +type enumValue string + +var ( + enumValuesMu sync.Mutex + enumValues = make(map[*enumValue]map[string]struct{}) +) + +func (s *enumValue) Set(value string, opt Option) error { + enumValuesMu.Lock() + es, ok := enumValues[s] + enumValuesMu.Unlock() + if !ok || es == nil { + return errors.New("this option has no values") + } + if _, ok := es[value]; !ok { + return errors.New("invalid value: " + value) + } + *s = enumValue(value) + return nil +} + +func (s *enumValue) String() string { + return string(*s) +} + +// Enum creates an option that can only be set to one of the enumerated strings +// passed in values. Passing nil or an empty slice results in an option that +// will always fail. If not "", value is the default value of the enum. If +// value is not listed in values then Enum will produce an error on standard +// error and then exit the program with a status of 1. +func Enum(name rune, values []string, value string, helpvalue ...string) *string { + return CommandLine.Enum(name, values, value, helpvalue...) +} + +func (s *Set) Enum(name rune, values []string, value string, helpvalue ...string) *string { + var p enumValue + p.define(values, value, &option{short: name}) + s.FlagLong(&p, "", name, helpvalue...) + return (*string)(&p) +} + +func EnumLong(name string, short rune, values []string, value string, helpvalue ...string) *string { + return CommandLine.EnumLong(name, short, values, value, helpvalue...) +} + +func (s *Set) EnumLong(name string, short rune, values []string, value string, helpvalue ...string) *string { + var p enumValue + p.define(values, value, &option{short: short, long: name}) + s.FlagLong(&p, name, short, helpvalue...) + return (*string)(&p) +} + +func (e *enumValue) define(values []string, def string, opt Option) { + m := make(map[string]struct{}) + for _, v := range values { + m[v] = struct{}{} + } + enumValuesMu.Lock() + enumValues[e] = m + enumValuesMu.Unlock() + if def != "" { + if err := e.Set(def, nil); err != nil { + fmt.Fprintf(stderr, "setting default for %s: %v\n", opt.Name(), err) + exit(1) + } + } +} |