Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAhmad Sherif <me@ahmadsherif.com>2016-12-22 17:54:55 +0300
committerAhmad Sherif <me@ahmadsherif.com>2016-12-23 22:14:07 +0300
commite32c0ad734100057234a2f9e2b255fc8ac3162d5 (patch)
tree61fe09e2664c7667c3f0d5a27e147c2834ecc3f0
parentfce0a9c1edcd950a815e3f0fd764ce7efb16b395 (diff)
Use envconfig package for configurations setting
-rw-r--r--cmd/gitaly/main.go20
-rw-r--r--vendor/github.com/kelseyhightower/envconfig/LICENSE19
-rw-r--r--vendor/github.com/kelseyhightower/envconfig/MAINTAINERS2
-rw-r--r--vendor/github.com/kelseyhightower/envconfig/README.md175
-rw-r--r--vendor/github.com/kelseyhightower/envconfig/doc.go8
-rw-r--r--vendor/github.com/kelseyhightower/envconfig/env_os.go7
-rw-r--r--vendor/github.com/kelseyhightower/envconfig/env_syscall.go7
-rw-r--r--vendor/github.com/kelseyhightower/envconfig/envconfig.go273
-rw-r--r--vendor/vendor.json6
9 files changed, 510 insertions, 7 deletions
diff --git a/cmd/gitaly/main.go b/cmd/gitaly/main.go
index 675f4492e..3c6df166d 100644
--- a/cmd/gitaly/main.go
+++ b/cmd/gitaly/main.go
@@ -1,35 +1,41 @@
package main
import (
- "flag"
+ "log"
"net/http"
"os"
"os/signal"
"syscall"
+ "github.com/kelseyhightower/envconfig"
"github.com/prometheus/client_golang/prometheus/promhttp"
serv "gitlab.com/gitlab-org/gitaly/server"
)
-var (
- prometheusListenAddr = flag.String("prometheusListenAddr", "", "Prometheus listening address, e.g. ':9100'")
-)
+type Config struct {
+ PrometheusListenAddr string `split_words:"true"`
+}
func main() {
ch := make(chan os.Signal)
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
- server := serv.NewServer()
+ config := Config{}
+ err := envconfig.Process("gitaly", &config)
+ if err != nil {
+ log.Fatal(err)
+ }
+
go func() {
server.Serve("0.0.0.0:6666", serv.CommandExecutor)
}()
- if *prometheusListenAddr != "" {
+ if config.PrometheusListenAddr != "" {
promMux := http.NewServeMux()
promMux.Handle("/metrics", promhttp.Handler())
go func() {
- http.ListenAndServe(*prometheusListenAddr, promMux)
+ http.ListenAndServe(config.PrometheusListenAddr, promMux)
}()
}
diff --git a/vendor/github.com/kelseyhightower/envconfig/LICENSE b/vendor/github.com/kelseyhightower/envconfig/LICENSE
new file mode 100644
index 000000000..4bfa7a84d
--- /dev/null
+++ b/vendor/github.com/kelseyhightower/envconfig/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2013 Kelsey Hightower
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/kelseyhightower/envconfig/MAINTAINERS b/vendor/github.com/kelseyhightower/envconfig/MAINTAINERS
new file mode 100644
index 000000000..6527a9f2c
--- /dev/null
+++ b/vendor/github.com/kelseyhightower/envconfig/MAINTAINERS
@@ -0,0 +1,2 @@
+Kelsey Hightower kelsey.hightower@gmail.com github.com/kelseyhightower
+Travis Parker travis.parker@gmail.com github.com/teepark
diff --git a/vendor/github.com/kelseyhightower/envconfig/README.md b/vendor/github.com/kelseyhightower/envconfig/README.md
new file mode 100644
index 000000000..09de74b42
--- /dev/null
+++ b/vendor/github.com/kelseyhightower/envconfig/README.md
@@ -0,0 +1,175 @@
+# envconfig
+
+[![Build Status](https://travis-ci.org/kelseyhightower/envconfig.png)](https://travis-ci.org/kelseyhightower/envconfig)
+
+```Go
+import "github.com/kelseyhightower/envconfig"
+```
+
+## Documentation
+
+See [godoc](http://godoc.org/github.com/kelseyhightower/envconfig)
+
+## Usage
+
+Set some environment variables:
+
+```Bash
+export MYAPP_DEBUG=false
+export MYAPP_PORT=8080
+export MYAPP_USER=Kelsey
+export MYAPP_RATE="0.5"
+export MYAPP_TIMEOUT="3m"
+export MYAPP_USERS="rob,ken,robert"
+```
+
+Write some code:
+
+```Go
+package main
+
+import (
+ "fmt"
+ "log"
+ "time"
+
+ "github.com/kelseyhightower/envconfig"
+)
+
+type Specification struct {
+ Debug bool
+ Port int
+ User string
+ Users []string
+ Rate float32
+ Timeout time.Duration
+}
+
+func main() {
+ var s Specification
+ err := envconfig.Process("myapp", &s)
+ if err != nil {
+ log.Fatal(err.Error())
+ }
+ format := "Debug: %v\nPort: %d\nUser: %s\nRate: %f\nTimeout: %s\n"
+ _, err = fmt.Printf(format, s.Debug, s.Port, s.User, s.Rate)
+ if err != nil {
+ log.Fatal(err.Error())
+ }
+
+ fmt.Println("Users:")
+ for _, u := range s.Users {
+ fmt.Printf(" %s\n", u)
+ }
+}
+```
+
+Results:
+
+```Bash
+Debug: false
+Port: 8080
+User: Kelsey
+Rate: 0.500000
+Timeout: 3m0s
+Users:
+ rob
+ ken
+ robert
+```
+
+## Struct Tag Support
+
+Envconfig supports the use of struct tags to specify alternate, default, and required
+environment variables.
+
+For example, consider the following struct:
+
+```Go
+type Specification struct {
+ ManualOverride1 string `envconfig:"manual_override_1"`
+ DefaultVar string `default:"foobar"`
+ RequiredVar string `required:"true"`
+ IgnoredVar string `ignored:"true"`
+ AutoSplitVar string `split_words:"true"`
+}
+```
+
+Envconfig has automatic support for CamelCased struct elements when the
+`split_words:"true"` tag is supplied. Without this tag, `AutoSplitVar` above
+would look for an environment variable called `MYAPP_AUTOSPLITVAR`. With the
+setting applied it will look for `MYAPP_AUTO_SPLIT_VAR`. Note that numbers
+will get globbed into the previous word. If the setting does not do the
+right thing, you may use a manual override.
+
+Envconfig will process value for `ManualOverride1` by populating it with the
+value for `MYAPP_MANUAL_OVERRIDE_1`. Without this struct tag, it would have
+instead looked up `MYAPP_MANUALOVERRIDE1`. With the `split_words:"true"` tag
+it would have looked up `MYAPP_MANUAL_OVERRIDE1`.
+
+```Bash
+export MYAPP_MANUAL_OVERRIDE_1="this will be the value"
+
+# export MYAPP_MANUALOVERRIDE1="and this will not"
+```
+
+If envconfig can't find an environment variable value for `MYAPP_DEFAULTVAR`,
+it will populate it with "foobar" as a default value.
+
+If envconfig can't find an environment variable value for `MYAPP_REQUIREDVAR`,
+it will return an error when asked to process the struct.
+
+If envconfig can't find an environment variable in the form `PREFIX_MYVAR`, and there
+is a struct tag defined, it will try to populate your variable with an environment
+variable that directly matches the envconfig tag in your struct definition:
+
+```shell
+export SERVICE_HOST=127.0.0.1
+export MYAPP_DEBUG=true
+```
+```Go
+type Specification struct {
+ ServiceHost string `envconfig:"SERVICE_HOST"`
+ Debug bool
+}
+```
+
+Envconfig won't process a field with the "ignored" tag set to "true", even if a corresponding
+environment variable is set.
+
+## Supported Struct Field Types
+
+envconfig supports supports these struct field types:
+
+ * string
+ * int8, int16, int32, int64
+ * bool
+ * float32, float64
+ * [encoding.TextUnmarshaler](https://golang.org/pkg/encoding/#TextUnmarshaler)
+
+Embedded structs using these fields are also supported.
+
+## Custom Decoders
+
+Any field whose type (or pointer-to-type) implements `envconfig.Decoder` can
+control its own deserialization:
+
+```Bash
+export DNS_SERVER=8.8.8.8
+```
+
+```Go
+type IPDecoder net.IP
+
+func (ipd *IPDecoder) Decode(value string) error {
+ *ipd = IPDecoder(net.ParseIP(value))
+ return nil
+}
+
+type DNSConfig struct {
+ Address IPDecoder `envconfig:"DNS_SERVER"`
+}
+```
+
+Also, envconfig will use a `Set(string) error` method like from the
+[flag.Value](https://godoc.org/flag#Value) interface if implemented.
diff --git a/vendor/github.com/kelseyhightower/envconfig/doc.go b/vendor/github.com/kelseyhightower/envconfig/doc.go
new file mode 100644
index 000000000..f28561cd1
--- /dev/null
+++ b/vendor/github.com/kelseyhightower/envconfig/doc.go
@@ -0,0 +1,8 @@
+// Copyright (c) 2013 Kelsey Hightower. All rights reserved.
+// Use of this source code is governed by the MIT License that can be found in
+// the LICENSE file.
+
+// Package envconfig implements decoding of environment variables based on a user
+// defined specification. A typical use is using environment variables for
+// configuration settings.
+package envconfig
diff --git a/vendor/github.com/kelseyhightower/envconfig/env_os.go b/vendor/github.com/kelseyhightower/envconfig/env_os.go
new file mode 100644
index 000000000..a6a014a2b
--- /dev/null
+++ b/vendor/github.com/kelseyhightower/envconfig/env_os.go
@@ -0,0 +1,7 @@
+// +build appengine
+
+package envconfig
+
+import "os"
+
+var lookupEnv = os.LookupEnv
diff --git a/vendor/github.com/kelseyhightower/envconfig/env_syscall.go b/vendor/github.com/kelseyhightower/envconfig/env_syscall.go
new file mode 100644
index 000000000..9d98085b9
--- /dev/null
+++ b/vendor/github.com/kelseyhightower/envconfig/env_syscall.go
@@ -0,0 +1,7 @@
+// +build !appengine
+
+package envconfig
+
+import "syscall"
+
+var lookupEnv = syscall.Getenv
diff --git a/vendor/github.com/kelseyhightower/envconfig/envconfig.go b/vendor/github.com/kelseyhightower/envconfig/envconfig.go
new file mode 100644
index 000000000..38e449ebb
--- /dev/null
+++ b/vendor/github.com/kelseyhightower/envconfig/envconfig.go
@@ -0,0 +1,273 @@
+// Copyright (c) 2013 Kelsey Hightower. All rights reserved.
+// Use of this source code is governed by the MIT License that can be found in
+// the LICENSE file.
+
+package envconfig
+
+import (
+ "encoding"
+ "errors"
+ "fmt"
+ "reflect"
+ "regexp"
+ "strconv"
+ "strings"
+ "time"
+)
+
+// ErrInvalidSpecification indicates that a specification is of the wrong type.
+var ErrInvalidSpecification = errors.New("specification must be a struct pointer")
+
+// A ParseError occurs when an environment variable cannot be converted to
+// the type required by a struct field during assignment.
+type ParseError struct {
+ KeyName string
+ FieldName string
+ TypeName string
+ Value string
+ Err error
+}
+
+// Decoder has the same semantics as Setter, but takes higher precedence.
+// It is provided for historical compatibility.
+type Decoder interface {
+ Decode(value string) error
+}
+
+// Setter is implemented by types can self-deserialize values.
+// Any type that implements flag.Value also implements Setter.
+type Setter interface {
+ Set(value string) error
+}
+
+func (e *ParseError) Error() string {
+ return fmt.Sprintf("envconfig.Process: assigning %[1]s to %[2]s: converting '%[3]s' to type %[4]s. details: %[5]s", e.KeyName, e.FieldName, e.Value, e.TypeName, e.Err)
+}
+
+// Process populates the specified struct based on environment variables
+func Process(prefix string, spec interface{}) error {
+ // For splitting camelCased words
+ expr := regexp.MustCompile("([^A-Z]+|[A-Z][^A-Z]+|[A-Z]+)")
+
+ s := reflect.ValueOf(spec)
+
+ if s.Kind() != reflect.Ptr {
+ return ErrInvalidSpecification
+ }
+ s = s.Elem()
+ if s.Kind() != reflect.Struct {
+ return ErrInvalidSpecification
+ }
+ typeOfSpec := s.Type()
+ for i := 0; i < s.NumField(); i++ {
+ f := s.Field(i)
+ ftype := typeOfSpec.Field(i)
+ if !f.CanSet() || ftype.Tag.Get("ignored") == "true" {
+ continue
+ }
+
+ for f.Kind() == reflect.Ptr {
+ if f.IsNil() {
+ if f.Type().Elem().Kind() != reflect.Struct {
+ // nil pointer to a non-struct: leave it alone
+ break
+ }
+ // nil pointer to struct: create a zero instance
+ f.Set(reflect.New(f.Type().Elem()))
+ }
+ f = f.Elem()
+ }
+
+ // Default to the field name as the env var name (will be upcased)
+ key := ftype.Name
+
+ // Best effort to un-pick camel casing as separate words
+ if ftype.Tag.Get("split_words") == "true" {
+ words := expr.FindAllStringSubmatch(ftype.Name, -1)
+ if len(words) > 0 {
+ var name []string
+ for _, words := range words {
+ name = append(name, words[0])
+ }
+
+ key = strings.Join(name, "_")
+ }
+ }
+
+ alt := ftype.Tag.Get("envconfig")
+ if alt != "" {
+ key = alt
+ }
+
+ if prefix != "" {
+ key = fmt.Sprintf("%s_%s", prefix, key)
+ }
+
+ key = strings.ToUpper(key)
+
+ if f.Kind() == reflect.Struct {
+ // honor Decode if present
+ if decoderFrom(f) == nil && setterFrom(f) == nil && textUnmarshaler(f) == nil {
+ innerPrefix := prefix
+ if !ftype.Anonymous {
+ innerPrefix = key
+ }
+
+ embeddedPtr := f.Addr().Interface()
+ if err := Process(innerPrefix, embeddedPtr); err != nil {
+ return err
+ }
+ f.Set(reflect.ValueOf(embeddedPtr).Elem())
+
+ continue
+ }
+ }
+
+ // `os.Getenv` cannot differentiate between an explicitly set empty value
+ // and an unset value. `os.LookupEnv` is preferred to `syscall.Getenv`,
+ // but it is only available in go1.5 or newer. We're using Go build tags
+ // here to use os.LookupEnv for >=go1.5
+ value, ok := lookupEnv(key)
+ if !ok && alt != "" {
+ key := strings.ToUpper(alt)
+ value, ok = lookupEnv(key)
+ }
+
+ def := ftype.Tag.Get("default")
+ if def != "" && !ok {
+ value = def
+ }
+
+ req := ftype.Tag.Get("required")
+ if !ok && def == "" {
+ if req == "true" {
+ return fmt.Errorf("required key %s missing value", key)
+ }
+ continue
+ }
+
+ err := processField(value, f)
+ if err != nil {
+ return &ParseError{
+ KeyName: key,
+ FieldName: ftype.Name,
+ TypeName: f.Type().String(),
+ Value: value,
+ Err: err,
+ }
+ }
+ }
+ return nil
+}
+
+// MustProcess is the same as Process but panics if an error occurs
+func MustProcess(prefix string, spec interface{}) {
+ if err := Process(prefix, spec); err != nil {
+ panic(err)
+ }
+}
+
+func processField(value string, field reflect.Value) error {
+ typ := field.Type()
+
+ decoder := decoderFrom(field)
+ if decoder != nil {
+ return decoder.Decode(value)
+ }
+ // look for Set method if Decode not defined
+ setter := setterFrom(field)
+ if setter != nil {
+ return setter.Set(value)
+ }
+
+ if t := textUnmarshaler(field); t != nil {
+ return t.UnmarshalText([]byte(value))
+ }
+
+ if typ.Kind() == reflect.Ptr {
+ typ = typ.Elem()
+ if field.IsNil() {
+ field.Set(reflect.New(typ))
+ }
+ field = field.Elem()
+ }
+
+ switch typ.Kind() {
+ case reflect.String:
+ field.SetString(value)
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ var (
+ val int64
+ err error
+ )
+ if field.Kind() == reflect.Int64 && typ.PkgPath() == "time" && typ.Name() == "Duration" {
+ var d time.Duration
+ d, err = time.ParseDuration(value)
+ val = int64(d)
+ } else {
+ val, err = strconv.ParseInt(value, 0, typ.Bits())
+ }
+ if err != nil {
+ return err
+ }
+
+ field.SetInt(val)
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ val, err := strconv.ParseUint(value, 0, typ.Bits())
+ if err != nil {
+ return err
+ }
+ field.SetUint(val)
+ case reflect.Bool:
+ val, err := strconv.ParseBool(value)
+ if err != nil {
+ return err
+ }
+ field.SetBool(val)
+ case reflect.Float32, reflect.Float64:
+ val, err := strconv.ParseFloat(value, typ.Bits())
+ if err != nil {
+ return err
+ }
+ field.SetFloat(val)
+ case reflect.Slice:
+ vals := strings.Split(value, ",")
+ sl := reflect.MakeSlice(typ, len(vals), len(vals))
+ for i, val := range vals {
+ err := processField(val, sl.Index(i))
+ if err != nil {
+ return err
+ }
+ }
+ field.Set(sl)
+ }
+
+ return nil
+}
+
+func interfaceFrom(field reflect.Value, fn func(interface{}, *bool)) {
+ // it may be impossible for a struct field to fail this check
+ if !field.CanInterface() {
+ return
+ }
+ var ok bool
+ fn(field.Interface(), &ok)
+ if !ok && field.CanAddr() {
+ fn(field.Addr().Interface(), &ok)
+ }
+}
+
+func decoderFrom(field reflect.Value) (d Decoder) {
+ interfaceFrom(field, func(v interface{}, ok *bool) { d, *ok = v.(Decoder) })
+ return d
+}
+
+func setterFrom(field reflect.Value) (s Setter) {
+ interfaceFrom(field, func(v interface{}, ok *bool) { s, *ok = v.(Setter) })
+ return s
+}
+
+func textUnmarshaler(field reflect.Value) (t encoding.TextUnmarshaler) {
+ interfaceFrom(field, func(v interface{}, ok *bool) { t, *ok = v.(encoding.TextUnmarshaler) })
+ return t
+}
diff --git a/vendor/vendor.json b/vendor/vendor.json
index 8e256632a..33fdb527a 100644
--- a/vendor/vendor.json
+++ b/vendor/vendor.json
@@ -15,6 +15,12 @@
"revisionTime": "2016-11-17T03:31:26Z"
},
{
+ "checksumSHA1": "ngWgR7cRhH340bOHEpLTJCY1jTs=",
+ "path": "github.com/kelseyhightower/envconfig",
+ "revision": "5c008110b20b657eb7e005b83d0a5f6aa6bb5f4b",
+ "revisionTime": "2016-12-05T22:33:43Z"
+ },
+ {
"checksumSHA1": "bKMZjd2wPw13VwoE7mBeSv5djFA=",
"path": "github.com/matttproud/golang_protobuf_extensions/pbutil",
"revision": "c12348ce28de40eed0136aa2b644d0ee0650e56c",