mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 21:04:37 +03:00
Upgrade to go 1.19 and update dependencies (#3069)
* Update to go 1.19 * Update dependencies * Update cross-compile script * Add missing targets to cross-compile-all * Update cache action to remove warning
This commit is contained in:
26
vendor/github.com/spf13/afero/.travis.yml
generated
vendored
26
vendor/github.com/spf13/afero/.travis.yml
generated
vendored
@@ -1,26 +0,0 @@
|
||||
sudo: false
|
||||
language: go
|
||||
arch:
|
||||
- amd64
|
||||
- ppc64e
|
||||
|
||||
go:
|
||||
- "1.14"
|
||||
- "1.15"
|
||||
- "1.16"
|
||||
- tip
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- go: tip
|
||||
fast_finish: true
|
||||
|
||||
script:
|
||||
- go build -v ./...
|
||||
- go test -count=1 -cover -race -v ./...
|
||||
- go vet ./...
|
||||
- FILES=$(gofmt -s -l . zipfs sftpfs mem tarfs); if [[ -n "${FILES}" ]]; then echo "You have go format errors; gofmt your changes"; exit 1; fi
|
||||
2
vendor/github.com/spf13/afero/README.md
generated
vendored
2
vendor/github.com/spf13/afero/README.md
generated
vendored
@@ -2,7 +2,7 @@
|
||||
|
||||
A FileSystem Abstraction System for Go
|
||||
|
||||
[](https://travis-ci.org/spf13/afero) [](https://ci.appveyor.com/project/spf13/afero) [](https://godoc.org/github.com/spf13/afero) [](https://gitter.im/spf13/afero?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://github.com/spf13/afero/actions/workflows/test.yml) [](https://godoc.org/github.com/spf13/afero) [](https://gitter.im/spf13/afero?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
# Overview
|
||||
|
||||
|
||||
4
vendor/github.com/spf13/afero/afero.go
generated
vendored
4
vendor/github.com/spf13/afero/afero.go
generated
vendored
@@ -103,8 +103,8 @@ type Fs interface {
|
||||
|
||||
var (
|
||||
ErrFileClosed = errors.New("File is closed")
|
||||
ErrOutOfRange = errors.New("Out of range")
|
||||
ErrTooLarge = errors.New("Too large")
|
||||
ErrOutOfRange = errors.New("out of range")
|
||||
ErrTooLarge = errors.New("too large")
|
||||
ErrFileNotFound = os.ErrNotExist
|
||||
ErrFileExists = os.ErrExist
|
||||
ErrDestinationExists = os.ErrExist
|
||||
|
||||
9
vendor/github.com/spf13/afero/appveyor.yml
generated
vendored
9
vendor/github.com/spf13/afero/appveyor.yml
generated
vendored
@@ -1,3 +1,5 @@
|
||||
# This currently does nothing. We have moved to GitHub action, but this is kept
|
||||
# until spf13 has disabled this project in AppVeyor.
|
||||
version: '{build}'
|
||||
clone_folder: C:\gopath\src\github.com\spf13\afero
|
||||
environment:
|
||||
@@ -6,10 +8,3 @@ build_script:
|
||||
- cmd: >-
|
||||
go version
|
||||
|
||||
go env
|
||||
|
||||
go get -v github.com/spf13/afero/...
|
||||
|
||||
go build -v github.com/spf13/afero/...
|
||||
test_script:
|
||||
- cmd: go test -count=1 -cover -race -v github.com/spf13/afero/...
|
||||
|
||||
14
vendor/github.com/spf13/afero/basepath.go
generated
vendored
14
vendor/github.com/spf13/afero/basepath.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package afero
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
@@ -8,7 +9,10 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
var _ Lstater = (*BasePathFs)(nil)
|
||||
var (
|
||||
_ Lstater = (*BasePathFs)(nil)
|
||||
_ fs.ReadDirFile = (*BasePathFile)(nil)
|
||||
)
|
||||
|
||||
// The BasePathFs restricts all operations to a given path within an Fs.
|
||||
// The given file name to the operations on this Fs will be prepended with
|
||||
@@ -33,6 +37,14 @@ func (f *BasePathFile) Name() string {
|
||||
return strings.TrimPrefix(sourcename, filepath.Clean(f.path))
|
||||
}
|
||||
|
||||
func (f *BasePathFile) ReadDir(n int) ([]fs.DirEntry, error) {
|
||||
if rdf, ok := f.File.(fs.ReadDirFile); ok {
|
||||
return rdf.ReadDir(n)
|
||||
|
||||
}
|
||||
return readDirFile{f.File}.ReadDir(n)
|
||||
}
|
||||
|
||||
func NewBasePathFs(source Fs, path string) Fs {
|
||||
return &BasePathFs{source: source, path: path}
|
||||
}
|
||||
|
||||
1
vendor/github.com/spf13/afero/const_bsds.go
generated
vendored
1
vendor/github.com/spf13/afero/const_bsds.go
generated
vendored
@@ -11,6 +11,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build aix || darwin || openbsd || freebsd || netbsd || dragonfly
|
||||
// +build aix darwin openbsd freebsd netbsd dragonfly
|
||||
|
||||
package afero
|
||||
|
||||
8
vendor/github.com/spf13/afero/const_win_unix.go
generated
vendored
8
vendor/github.com/spf13/afero/const_win_unix.go
generated
vendored
@@ -10,12 +10,8 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// +build !darwin
|
||||
// +build !openbsd
|
||||
// +build !freebsd
|
||||
// +build !dragonfly
|
||||
// +build !netbsd
|
||||
// +build !aix
|
||||
//go:build !darwin && !openbsd && !freebsd && !dragonfly && !netbsd && !aix
|
||||
// +build !darwin,!openbsd,!freebsd,!dragonfly,!netbsd,!aix
|
||||
|
||||
package afero
|
||||
|
||||
|
||||
2
vendor/github.com/spf13/afero/httpFs.go
generated
vendored
2
vendor/github.com/spf13/afero/httpFs.go
generated
vendored
@@ -29,7 +29,7 @@ type httpDir struct {
|
||||
}
|
||||
|
||||
func (d httpDir) Open(name string) (http.File, error) {
|
||||
if filepath.Separator != '/' && strings.IndexRune(name, filepath.Separator) >= 0 ||
|
||||
if filepath.Separator != '/' && strings.ContainsRune(name, filepath.Separator) ||
|
||||
strings.Contains(name, "\x00") {
|
||||
return nil, errors.New("http: invalid character in file path")
|
||||
}
|
||||
|
||||
27
vendor/github.com/spf13/afero/internal/common/adapters.go
generated
vendored
Normal file
27
vendor/github.com/spf13/afero/internal/common/adapters.go
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright © 2022 Steve Francia <spf@spf13.com>.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package common
|
||||
|
||||
import "io/fs"
|
||||
|
||||
// FileInfoDirEntry provides an adapter from os.FileInfo to fs.DirEntry
|
||||
type FileInfoDirEntry struct {
|
||||
fs.FileInfo
|
||||
}
|
||||
|
||||
var _ fs.DirEntry = FileInfoDirEntry{}
|
||||
|
||||
func (d FileInfoDirEntry) Type() fs.FileMode { return d.FileInfo.Mode().Type() }
|
||||
|
||||
func (d FileInfoDirEntry) Info() (fs.FileInfo, error) { return d.FileInfo, nil }
|
||||
38
vendor/github.com/spf13/afero/iofs.go
generated
vendored
38
vendor/github.com/spf13/afero/iofs.go
generated
vendored
@@ -1,3 +1,4 @@
|
||||
//go:build go1.16
|
||||
// +build go1.16
|
||||
|
||||
package afero
|
||||
@@ -7,7 +8,10 @@ import (
|
||||
"io/fs"
|
||||
"os"
|
||||
"path"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/afero/internal/common"
|
||||
)
|
||||
|
||||
// IOFS adopts afero.Fs to stdlib io/fs.FS
|
||||
@@ -66,14 +70,31 @@ func (iofs IOFS) Glob(pattern string) ([]string, error) {
|
||||
}
|
||||
|
||||
func (iofs IOFS) ReadDir(name string) ([]fs.DirEntry, error) {
|
||||
items, err := ReadDir(iofs.Fs, name)
|
||||
f, err := iofs.Fs.Open(name)
|
||||
if err != nil {
|
||||
return nil, iofs.wrapError("readdir", name, err)
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
|
||||
if rdf, ok := f.(fs.ReadDirFile); ok {
|
||||
items, err := rdf.ReadDir(-1)
|
||||
if err != nil {
|
||||
return nil, iofs.wrapError("readdir", name, err)
|
||||
}
|
||||
sort.Slice(items, func(i, j int) bool { return items[i].Name() < items[j].Name() })
|
||||
return items, nil
|
||||
}
|
||||
|
||||
items, err := f.Readdir(-1)
|
||||
if err != nil {
|
||||
return nil, iofs.wrapError("readdir", name, err)
|
||||
}
|
||||
sort.Sort(byName(items))
|
||||
|
||||
ret := make([]fs.DirEntry, len(items))
|
||||
for i := range items {
|
||||
ret[i] = dirEntry{items[i]}
|
||||
ret[i] = common.FileInfoDirEntry{FileInfo: items[i]}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
@@ -108,17 +129,6 @@ func (IOFS) wrapError(op, path string, err error) error {
|
||||
}
|
||||
}
|
||||
|
||||
// dirEntry provides adapter from os.FileInfo to fs.DirEntry
|
||||
type dirEntry struct {
|
||||
fs.FileInfo
|
||||
}
|
||||
|
||||
var _ fs.DirEntry = dirEntry{}
|
||||
|
||||
func (d dirEntry) Type() fs.FileMode { return d.FileInfo.Mode().Type() }
|
||||
|
||||
func (d dirEntry) Info() (fs.FileInfo, error) { return d.FileInfo, nil }
|
||||
|
||||
// readDirFile provides adapter from afero.File to fs.ReadDirFile needed for correct Open
|
||||
type readDirFile struct {
|
||||
File
|
||||
@@ -134,7 +144,7 @@ func (r readDirFile) ReadDir(n int) ([]fs.DirEntry, error) {
|
||||
|
||||
ret := make([]fs.DirEntry, len(items))
|
||||
for i := range items {
|
||||
ret[i] = dirEntry{items[i]}
|
||||
ret[i] = common.FileInfoDirEntry{FileInfo: items[i]}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
|
||||
10
vendor/github.com/spf13/afero/ioutil.go
generated
vendored
10
vendor/github.com/spf13/afero/ioutil.go
generated
vendored
@@ -141,7 +141,7 @@ func WriteFile(fs Fs, filename string, data []byte, perm os.FileMode) error {
|
||||
// We generate random temporary file names so that there's a good
|
||||
// chance the file doesn't exist yet - keeps the number of tries in
|
||||
// TempFile to a minimum.
|
||||
var rand uint32
|
||||
var randNum uint32
|
||||
var randmu sync.Mutex
|
||||
|
||||
func reseed() uint32 {
|
||||
@@ -150,12 +150,12 @@ func reseed() uint32 {
|
||||
|
||||
func nextRandom() string {
|
||||
randmu.Lock()
|
||||
r := rand
|
||||
r := randNum
|
||||
if r == 0 {
|
||||
r = reseed()
|
||||
}
|
||||
r = r*1664525 + 1013904223 // constants from Numerical Recipes
|
||||
rand = r
|
||||
randNum = r
|
||||
randmu.Unlock()
|
||||
return strconv.Itoa(int(1e9 + r%1e9))[1:]
|
||||
}
|
||||
@@ -194,7 +194,7 @@ func TempFile(fs Fs, dir, pattern string) (f File, err error) {
|
||||
if os.IsExist(err) {
|
||||
if nconflict++; nconflict > 10 {
|
||||
randmu.Lock()
|
||||
rand = reseed()
|
||||
randNum = reseed()
|
||||
randmu.Unlock()
|
||||
}
|
||||
continue
|
||||
@@ -226,7 +226,7 @@ func TempDir(fs Fs, dir, prefix string) (name string, err error) {
|
||||
if os.IsExist(err) {
|
||||
if nconflict++; nconflict > 10 {
|
||||
randmu.Lock()
|
||||
rand = reseed()
|
||||
randNum = reseed()
|
||||
randmu.Unlock()
|
||||
}
|
||||
continue
|
||||
|
||||
30
vendor/github.com/spf13/afero/mem/file.go
generated
vendored
30
vendor/github.com/spf13/afero/mem/file.go
generated
vendored
@@ -18,15 +18,20 @@ import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/afero/internal/common"
|
||||
)
|
||||
|
||||
const FilePathSeparator = string(filepath.Separator)
|
||||
|
||||
var _ fs.ReadDirFile = &File{}
|
||||
|
||||
type File struct {
|
||||
// atomic requires 64-bit alignment for struct field access
|
||||
at int64
|
||||
@@ -183,10 +188,23 @@ func (f *File) Readdirnames(n int) (names []string, err error) {
|
||||
return names, err
|
||||
}
|
||||
|
||||
// Implements fs.ReadDirFile
|
||||
func (f *File) ReadDir(n int) ([]fs.DirEntry, error) {
|
||||
fi, err := f.Readdir(n)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
di := make([]fs.DirEntry, len(fi))
|
||||
for i, f := range fi {
|
||||
di[i] = common.FileInfoDirEntry{FileInfo: f}
|
||||
}
|
||||
return di, nil
|
||||
}
|
||||
|
||||
func (f *File) Read(b []byte) (n int, err error) {
|
||||
f.fileData.Lock()
|
||||
defer f.fileData.Unlock()
|
||||
if f.closed == true {
|
||||
if f.closed {
|
||||
return 0, ErrFileClosed
|
||||
}
|
||||
if len(b) > 0 && int(f.at) == len(f.fileData.data) {
|
||||
@@ -214,7 +232,7 @@ func (f *File) ReadAt(b []byte, off int64) (n int, err error) {
|
||||
}
|
||||
|
||||
func (f *File) Truncate(size int64) error {
|
||||
if f.closed == true {
|
||||
if f.closed {
|
||||
return ErrFileClosed
|
||||
}
|
||||
if f.readOnly {
|
||||
@@ -236,7 +254,7 @@ func (f *File) Truncate(size int64) error {
|
||||
}
|
||||
|
||||
func (f *File) Seek(offset int64, whence int) (int64, error) {
|
||||
if f.closed == true {
|
||||
if f.closed {
|
||||
return 0, ErrFileClosed
|
||||
}
|
||||
switch whence {
|
||||
@@ -251,7 +269,7 @@ func (f *File) Seek(offset int64, whence int) (int64, error) {
|
||||
}
|
||||
|
||||
func (f *File) Write(b []byte) (n int, err error) {
|
||||
if f.closed == true {
|
||||
if f.closed {
|
||||
return 0, ErrFileClosed
|
||||
}
|
||||
if f.readOnly {
|
||||
@@ -330,8 +348,8 @@ func (s *FileInfo) Size() int64 {
|
||||
|
||||
var (
|
||||
ErrFileClosed = errors.New("File is closed")
|
||||
ErrOutOfRange = errors.New("Out of range")
|
||||
ErrTooLarge = errors.New("Too large")
|
||||
ErrOutOfRange = errors.New("out of range")
|
||||
ErrTooLarge = errors.New("too large")
|
||||
ErrFileNotFound = os.ErrNotExist
|
||||
ErrFileExists = os.ErrExist
|
||||
ErrDestinationExists = os.ErrExist
|
||||
|
||||
2
vendor/github.com/spf13/afero/unionFile.go
generated
vendored
2
vendor/github.com/spf13/afero/unionFile.go
generated
vendored
@@ -65,7 +65,7 @@ func (f *UnionFile) ReadAt(s []byte, o int64) (int, error) {
|
||||
if f.Layer != nil {
|
||||
n, err := f.Layer.ReadAt(s, o)
|
||||
if (err == nil || err == io.EOF) && f.Base != nil {
|
||||
_, err = f.Base.Seek(o+int64(n), os.SEEK_SET)
|
||||
_, err = f.Base.Seek(o+int64(n), io.SeekStart)
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
10
vendor/github.com/spf13/afero/util.go
generated
vendored
10
vendor/github.com/spf13/afero/util.go
generated
vendored
@@ -25,6 +25,7 @@ import (
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"golang.org/x/text/runes"
|
||||
"golang.org/x/text/transform"
|
||||
"golang.org/x/text/unicode/norm"
|
||||
)
|
||||
@@ -158,16 +159,12 @@ func UnicodeSanitize(s string) string {
|
||||
|
||||
// Transform characters with accents into plain forms.
|
||||
func NeuterAccents(s string) string {
|
||||
t := transform.Chain(norm.NFD, transform.RemoveFunc(isMn), norm.NFC)
|
||||
t := transform.Chain(norm.NFD, runes.Remove(runes.In(unicode.Mn)), norm.NFC)
|
||||
result, _, _ := transform.String(t, string(s))
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func isMn(r rune) bool {
|
||||
return unicode.Is(unicode.Mn, r) // Mn: nonspacing marks
|
||||
}
|
||||
|
||||
func (a Afero) FileContainsBytes(filename string, subslice []byte) (bool, error) {
|
||||
return FileContainsBytes(a.Fs, filename, subslice)
|
||||
}
|
||||
@@ -299,6 +296,9 @@ func IsEmpty(fs Fs, path string) (bool, error) {
|
||||
}
|
||||
defer f.Close()
|
||||
list, err := f.Readdir(-1)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return len(list) == 0, nil
|
||||
}
|
||||
return fi.Size() == 0, nil
|
||||
|
||||
327
vendor/github.com/spf13/cast/caste.go
generated
vendored
327
vendor/github.com/spf13/cast/caste.go
generated
vendored
@@ -34,6 +34,12 @@ func ToTimeInDefaultLocationE(i interface{}, location *time.Location) (tim time.
|
||||
return v, nil
|
||||
case string:
|
||||
return StringToDateInDefaultLocation(v, location)
|
||||
case json.Number:
|
||||
s, err1 := ToInt64E(v)
|
||||
if err1 != nil {
|
||||
return time.Time{}, fmt.Errorf("unable to cast %#v of type %T to Time", i, i)
|
||||
}
|
||||
return time.Unix(s, 0), nil
|
||||
case int:
|
||||
return time.Unix(int64(v), 0), nil
|
||||
case int64:
|
||||
@@ -71,6 +77,11 @@ func ToDurationE(i interface{}) (d time.Duration, err error) {
|
||||
d, err = time.ParseDuration(s + "ns")
|
||||
}
|
||||
return
|
||||
case json.Number:
|
||||
var v float64
|
||||
v, err = s.Float64()
|
||||
d = time.Duration(v)
|
||||
return
|
||||
default:
|
||||
err = fmt.Errorf("unable to cast %#v of type %T to Duration", i, i)
|
||||
return
|
||||
@@ -93,6 +104,12 @@ func ToBoolE(i interface{}) (bool, error) {
|
||||
return false, nil
|
||||
case string:
|
||||
return strconv.ParseBool(i.(string))
|
||||
case json.Number:
|
||||
v, err := ToInt64E(b)
|
||||
if err == nil {
|
||||
return v != 0, nil
|
||||
}
|
||||
return false, fmt.Errorf("unable to cast %#v of type %T to bool", i, i)
|
||||
default:
|
||||
return false, fmt.Errorf("unable to cast %#v of type %T to bool", i, i)
|
||||
}
|
||||
@@ -102,13 +119,16 @@ func ToBoolE(i interface{}) (bool, error) {
|
||||
func ToFloat64E(i interface{}) (float64, error) {
|
||||
i = indirect(i)
|
||||
|
||||
intv, ok := toInt(i)
|
||||
if ok {
|
||||
return float64(intv), nil
|
||||
}
|
||||
|
||||
switch s := i.(type) {
|
||||
case float64:
|
||||
return s, nil
|
||||
case float32:
|
||||
return float64(s), nil
|
||||
case int:
|
||||
return float64(s), nil
|
||||
case int64:
|
||||
return float64(s), nil
|
||||
case int32:
|
||||
@@ -133,11 +153,19 @@ func ToFloat64E(i interface{}) (float64, error) {
|
||||
return v, nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
|
||||
case json.Number:
|
||||
v, err := s.Float64()
|
||||
if err == nil {
|
||||
return v, nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
|
||||
case bool:
|
||||
if s {
|
||||
return 1, nil
|
||||
}
|
||||
return 0, nil
|
||||
case nil:
|
||||
return 0, nil
|
||||
default:
|
||||
return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
|
||||
}
|
||||
@@ -147,13 +175,16 @@ func ToFloat64E(i interface{}) (float64, error) {
|
||||
func ToFloat32E(i interface{}) (float32, error) {
|
||||
i = indirect(i)
|
||||
|
||||
intv, ok := toInt(i)
|
||||
if ok {
|
||||
return float32(intv), nil
|
||||
}
|
||||
|
||||
switch s := i.(type) {
|
||||
case float64:
|
||||
return float32(s), nil
|
||||
case float32:
|
||||
return s, nil
|
||||
case int:
|
||||
return float32(s), nil
|
||||
case int64:
|
||||
return float32(s), nil
|
||||
case int32:
|
||||
@@ -178,11 +209,19 @@ func ToFloat32E(i interface{}) (float32, error) {
|
||||
return float32(v), nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
|
||||
case json.Number:
|
||||
v, err := s.Float64()
|
||||
if err == nil {
|
||||
return float32(v), nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
|
||||
case bool:
|
||||
if s {
|
||||
return 1, nil
|
||||
}
|
||||
return 0, nil
|
||||
case nil:
|
||||
return 0, nil
|
||||
default:
|
||||
return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
|
||||
}
|
||||
@@ -192,9 +231,12 @@ func ToFloat32E(i interface{}) (float32, error) {
|
||||
func ToInt64E(i interface{}) (int64, error) {
|
||||
i = indirect(i)
|
||||
|
||||
intv, ok := toInt(i)
|
||||
if ok {
|
||||
return int64(intv), nil
|
||||
}
|
||||
|
||||
switch s := i.(type) {
|
||||
case int:
|
||||
return int64(s), nil
|
||||
case int64:
|
||||
return s, nil
|
||||
case int32:
|
||||
@@ -218,11 +260,13 @@ func ToInt64E(i interface{}) (int64, error) {
|
||||
case float32:
|
||||
return int64(s), nil
|
||||
case string:
|
||||
v, err := strconv.ParseInt(s, 0, 0)
|
||||
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||
if err == nil {
|
||||
return v, nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
|
||||
case json.Number:
|
||||
return ToInt64E(string(s))
|
||||
case bool:
|
||||
if s {
|
||||
return 1, nil
|
||||
@@ -239,9 +283,12 @@ func ToInt64E(i interface{}) (int64, error) {
|
||||
func ToInt32E(i interface{}) (int32, error) {
|
||||
i = indirect(i)
|
||||
|
||||
intv, ok := toInt(i)
|
||||
if ok {
|
||||
return int32(intv), nil
|
||||
}
|
||||
|
||||
switch s := i.(type) {
|
||||
case int:
|
||||
return int32(s), nil
|
||||
case int64:
|
||||
return int32(s), nil
|
||||
case int32:
|
||||
@@ -265,11 +312,13 @@ func ToInt32E(i interface{}) (int32, error) {
|
||||
case float32:
|
||||
return int32(s), nil
|
||||
case string:
|
||||
v, err := strconv.ParseInt(s, 0, 0)
|
||||
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||
if err == nil {
|
||||
return int32(v), nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i)
|
||||
case json.Number:
|
||||
return ToInt32E(string(s))
|
||||
case bool:
|
||||
if s {
|
||||
return 1, nil
|
||||
@@ -286,9 +335,12 @@ func ToInt32E(i interface{}) (int32, error) {
|
||||
func ToInt16E(i interface{}) (int16, error) {
|
||||
i = indirect(i)
|
||||
|
||||
intv, ok := toInt(i)
|
||||
if ok {
|
||||
return int16(intv), nil
|
||||
}
|
||||
|
||||
switch s := i.(type) {
|
||||
case int:
|
||||
return int16(s), nil
|
||||
case int64:
|
||||
return int16(s), nil
|
||||
case int32:
|
||||
@@ -312,11 +364,13 @@ func ToInt16E(i interface{}) (int16, error) {
|
||||
case float32:
|
||||
return int16(s), nil
|
||||
case string:
|
||||
v, err := strconv.ParseInt(s, 0, 0)
|
||||
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||
if err == nil {
|
||||
return int16(v), nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i)
|
||||
case json.Number:
|
||||
return ToInt16E(string(s))
|
||||
case bool:
|
||||
if s {
|
||||
return 1, nil
|
||||
@@ -333,9 +387,12 @@ func ToInt16E(i interface{}) (int16, error) {
|
||||
func ToInt8E(i interface{}) (int8, error) {
|
||||
i = indirect(i)
|
||||
|
||||
intv, ok := toInt(i)
|
||||
if ok {
|
||||
return int8(intv), nil
|
||||
}
|
||||
|
||||
switch s := i.(type) {
|
||||
case int:
|
||||
return int8(s), nil
|
||||
case int64:
|
||||
return int8(s), nil
|
||||
case int32:
|
||||
@@ -359,11 +416,13 @@ func ToInt8E(i interface{}) (int8, error) {
|
||||
case float32:
|
||||
return int8(s), nil
|
||||
case string:
|
||||
v, err := strconv.ParseInt(s, 0, 0)
|
||||
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||
if err == nil {
|
||||
return int8(v), nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i)
|
||||
case json.Number:
|
||||
return ToInt8E(string(s))
|
||||
case bool:
|
||||
if s {
|
||||
return 1, nil
|
||||
@@ -380,9 +439,12 @@ func ToInt8E(i interface{}) (int8, error) {
|
||||
func ToIntE(i interface{}) (int, error) {
|
||||
i = indirect(i)
|
||||
|
||||
intv, ok := toInt(i)
|
||||
if ok {
|
||||
return intv, nil
|
||||
}
|
||||
|
||||
switch s := i.(type) {
|
||||
case int:
|
||||
return s, nil
|
||||
case int64:
|
||||
return int(s), nil
|
||||
case int32:
|
||||
@@ -406,11 +468,13 @@ func ToIntE(i interface{}) (int, error) {
|
||||
case float32:
|
||||
return int(s), nil
|
||||
case string:
|
||||
v, err := strconv.ParseInt(s, 0, 0)
|
||||
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||
if err == nil {
|
||||
return int(v), nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to cast %#v of type %T to int", i, i)
|
||||
return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
|
||||
case json.Number:
|
||||
return ToIntE(string(s))
|
||||
case bool:
|
||||
if s {
|
||||
return 1, nil
|
||||
@@ -427,18 +491,26 @@ func ToIntE(i interface{}) (int, error) {
|
||||
func ToUintE(i interface{}) (uint, error) {
|
||||
i = indirect(i)
|
||||
|
||||
switch s := i.(type) {
|
||||
case string:
|
||||
v, err := strconv.ParseUint(s, 0, 0)
|
||||
if err == nil {
|
||||
return uint(v), nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to cast %#v to uint: %s", i, err)
|
||||
case int:
|
||||
if s < 0 {
|
||||
intv, ok := toInt(i)
|
||||
if ok {
|
||||
if intv < 0 {
|
||||
return 0, errNegativeNotAllowed
|
||||
}
|
||||
return uint(s), nil
|
||||
return uint(intv), nil
|
||||
}
|
||||
|
||||
switch s := i.(type) {
|
||||
case string:
|
||||
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||
if err == nil {
|
||||
if v < 0 {
|
||||
return 0, errNegativeNotAllowed
|
||||
}
|
||||
return uint(v), nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to cast %#v of type %T to uint", i, i)
|
||||
case json.Number:
|
||||
return ToUintE(string(s))
|
||||
case int64:
|
||||
if s < 0 {
|
||||
return 0, errNegativeNotAllowed
|
||||
@@ -495,18 +567,26 @@ func ToUintE(i interface{}) (uint, error) {
|
||||
func ToUint64E(i interface{}) (uint64, error) {
|
||||
i = indirect(i)
|
||||
|
||||
switch s := i.(type) {
|
||||
case string:
|
||||
v, err := strconv.ParseUint(s, 0, 64)
|
||||
if err == nil {
|
||||
return v, nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to cast %#v to uint64: %s", i, err)
|
||||
case int:
|
||||
if s < 0 {
|
||||
intv, ok := toInt(i)
|
||||
if ok {
|
||||
if intv < 0 {
|
||||
return 0, errNegativeNotAllowed
|
||||
}
|
||||
return uint64(s), nil
|
||||
return uint64(intv), nil
|
||||
}
|
||||
|
||||
switch s := i.(type) {
|
||||
case string:
|
||||
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||
if err == nil {
|
||||
if v < 0 {
|
||||
return 0, errNegativeNotAllowed
|
||||
}
|
||||
return uint64(v), nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to cast %#v of type %T to uint64", i, i)
|
||||
case json.Number:
|
||||
return ToUint64E(string(s))
|
||||
case int64:
|
||||
if s < 0 {
|
||||
return 0, errNegativeNotAllowed
|
||||
@@ -563,18 +643,26 @@ func ToUint64E(i interface{}) (uint64, error) {
|
||||
func ToUint32E(i interface{}) (uint32, error) {
|
||||
i = indirect(i)
|
||||
|
||||
switch s := i.(type) {
|
||||
case string:
|
||||
v, err := strconv.ParseUint(s, 0, 32)
|
||||
if err == nil {
|
||||
return uint32(v), nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to cast %#v to uint32: %s", i, err)
|
||||
case int:
|
||||
if s < 0 {
|
||||
intv, ok := toInt(i)
|
||||
if ok {
|
||||
if intv < 0 {
|
||||
return 0, errNegativeNotAllowed
|
||||
}
|
||||
return uint32(s), nil
|
||||
return uint32(intv), nil
|
||||
}
|
||||
|
||||
switch s := i.(type) {
|
||||
case string:
|
||||
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||
if err == nil {
|
||||
if v < 0 {
|
||||
return 0, errNegativeNotAllowed
|
||||
}
|
||||
return uint32(v), nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to cast %#v of type %T to uint32", i, i)
|
||||
case json.Number:
|
||||
return ToUint32E(string(s))
|
||||
case int64:
|
||||
if s < 0 {
|
||||
return 0, errNegativeNotAllowed
|
||||
@@ -631,18 +719,26 @@ func ToUint32E(i interface{}) (uint32, error) {
|
||||
func ToUint16E(i interface{}) (uint16, error) {
|
||||
i = indirect(i)
|
||||
|
||||
switch s := i.(type) {
|
||||
case string:
|
||||
v, err := strconv.ParseUint(s, 0, 16)
|
||||
if err == nil {
|
||||
return uint16(v), nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to cast %#v to uint16: %s", i, err)
|
||||
case int:
|
||||
if s < 0 {
|
||||
intv, ok := toInt(i)
|
||||
if ok {
|
||||
if intv < 0 {
|
||||
return 0, errNegativeNotAllowed
|
||||
}
|
||||
return uint16(s), nil
|
||||
return uint16(intv), nil
|
||||
}
|
||||
|
||||
switch s := i.(type) {
|
||||
case string:
|
||||
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||
if err == nil {
|
||||
if v < 0 {
|
||||
return 0, errNegativeNotAllowed
|
||||
}
|
||||
return uint16(v), nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to cast %#v of type %T to uint16", i, i)
|
||||
case json.Number:
|
||||
return ToUint16E(string(s))
|
||||
case int64:
|
||||
if s < 0 {
|
||||
return 0, errNegativeNotAllowed
|
||||
@@ -699,18 +795,26 @@ func ToUint16E(i interface{}) (uint16, error) {
|
||||
func ToUint8E(i interface{}) (uint8, error) {
|
||||
i = indirect(i)
|
||||
|
||||
switch s := i.(type) {
|
||||
case string:
|
||||
v, err := strconv.ParseUint(s, 0, 8)
|
||||
if err == nil {
|
||||
return uint8(v), nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to cast %#v to uint8: %s", i, err)
|
||||
case int:
|
||||
if s < 0 {
|
||||
intv, ok := toInt(i)
|
||||
if ok {
|
||||
if intv < 0 {
|
||||
return 0, errNegativeNotAllowed
|
||||
}
|
||||
return uint8(s), nil
|
||||
return uint8(intv), nil
|
||||
}
|
||||
|
||||
switch s := i.(type) {
|
||||
case string:
|
||||
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
|
||||
if err == nil {
|
||||
if v < 0 {
|
||||
return 0, errNegativeNotAllowed
|
||||
}
|
||||
return uint8(v), nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to cast %#v of type %T to uint8", i, i)
|
||||
case json.Number:
|
||||
return ToUint8E(string(s))
|
||||
case int64:
|
||||
if s < 0 {
|
||||
return 0, errNegativeNotAllowed
|
||||
@@ -835,6 +939,8 @@ func ToStringE(i interface{}) (string, error) {
|
||||
return strconv.FormatUint(uint64(s), 10), nil
|
||||
case uint8:
|
||||
return strconv.FormatUint(uint64(s), 10), nil
|
||||
case json.Number:
|
||||
return s.String(), nil
|
||||
case []byte:
|
||||
return string(s), nil
|
||||
case template.HTML:
|
||||
@@ -1279,30 +1385,30 @@ func (f timeFormat) hasTimezone() bool {
|
||||
|
||||
var (
|
||||
timeFormats = []timeFormat{
|
||||
timeFormat{time.RFC3339, timeFormatNumericTimezone},
|
||||
timeFormat{"2006-01-02T15:04:05", timeFormatNoTimezone}, // iso8601 without timezone
|
||||
timeFormat{time.RFC1123Z, timeFormatNumericTimezone},
|
||||
timeFormat{time.RFC1123, timeFormatNamedTimezone},
|
||||
timeFormat{time.RFC822Z, timeFormatNumericTimezone},
|
||||
timeFormat{time.RFC822, timeFormatNamedTimezone},
|
||||
timeFormat{time.RFC850, timeFormatNamedTimezone},
|
||||
timeFormat{"2006-01-02 15:04:05.999999999 -0700 MST", timeFormatNumericAndNamedTimezone}, // Time.String()
|
||||
timeFormat{"2006-01-02T15:04:05-0700", timeFormatNumericTimezone}, // RFC3339 without timezone hh:mm colon
|
||||
timeFormat{"2006-01-02 15:04:05Z0700", timeFormatNumericTimezone}, // RFC3339 without T or timezone hh:mm colon
|
||||
timeFormat{"2006-01-02 15:04:05", timeFormatNoTimezone},
|
||||
timeFormat{time.ANSIC, timeFormatNoTimezone},
|
||||
timeFormat{time.UnixDate, timeFormatNamedTimezone},
|
||||
timeFormat{time.RubyDate, timeFormatNumericTimezone},
|
||||
timeFormat{"2006-01-02 15:04:05Z07:00", timeFormatNumericTimezone},
|
||||
timeFormat{"2006-01-02", timeFormatNoTimezone},
|
||||
timeFormat{"02 Jan 2006", timeFormatNoTimezone},
|
||||
timeFormat{"2006-01-02 15:04:05 -07:00", timeFormatNumericTimezone},
|
||||
timeFormat{"2006-01-02 15:04:05 -0700", timeFormatNumericTimezone},
|
||||
timeFormat{time.Kitchen, timeFormatTimeOnly},
|
||||
timeFormat{time.Stamp, timeFormatTimeOnly},
|
||||
timeFormat{time.StampMilli, timeFormatTimeOnly},
|
||||
timeFormat{time.StampMicro, timeFormatTimeOnly},
|
||||
timeFormat{time.StampNano, timeFormatTimeOnly},
|
||||
{time.RFC3339, timeFormatNumericTimezone},
|
||||
{"2006-01-02T15:04:05", timeFormatNoTimezone}, // iso8601 without timezone
|
||||
{time.RFC1123Z, timeFormatNumericTimezone},
|
||||
{time.RFC1123, timeFormatNamedTimezone},
|
||||
{time.RFC822Z, timeFormatNumericTimezone},
|
||||
{time.RFC822, timeFormatNamedTimezone},
|
||||
{time.RFC850, timeFormatNamedTimezone},
|
||||
{"2006-01-02 15:04:05.999999999 -0700 MST", timeFormatNumericAndNamedTimezone}, // Time.String()
|
||||
{"2006-01-02T15:04:05-0700", timeFormatNumericTimezone}, // RFC3339 without timezone hh:mm colon
|
||||
{"2006-01-02 15:04:05Z0700", timeFormatNumericTimezone}, // RFC3339 without T or timezone hh:mm colon
|
||||
{"2006-01-02 15:04:05", timeFormatNoTimezone},
|
||||
{time.ANSIC, timeFormatNoTimezone},
|
||||
{time.UnixDate, timeFormatNamedTimezone},
|
||||
{time.RubyDate, timeFormatNumericTimezone},
|
||||
{"2006-01-02 15:04:05Z07:00", timeFormatNumericTimezone},
|
||||
{"2006-01-02", timeFormatNoTimezone},
|
||||
{"02 Jan 2006", timeFormatNoTimezone},
|
||||
{"2006-01-02 15:04:05 -07:00", timeFormatNumericTimezone},
|
||||
{"2006-01-02 15:04:05 -0700", timeFormatNumericTimezone},
|
||||
{time.Kitchen, timeFormatTimeOnly},
|
||||
{time.Stamp, timeFormatTimeOnly},
|
||||
{time.StampMilli, timeFormatTimeOnly},
|
||||
{time.StampMicro, timeFormatTimeOnly},
|
||||
{time.StampNano, timeFormatTimeOnly},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1335,3 +1441,36 @@ func jsonStringToObject(s string, v interface{}) error {
|
||||
data := []byte(s)
|
||||
return json.Unmarshal(data, v)
|
||||
}
|
||||
|
||||
// toInt returns the int value of v if v or v's underlying type
|
||||
// is an int.
|
||||
// Note that this will return false for int64 etc. types.
|
||||
func toInt(v interface{}) (int, bool) {
|
||||
switch v := v.(type) {
|
||||
case int:
|
||||
return v, true
|
||||
case time.Weekday:
|
||||
return int(v), true
|
||||
case time.Month:
|
||||
return int(v), true
|
||||
default:
|
||||
return 0, false
|
||||
}
|
||||
}
|
||||
|
||||
func trimZeroDecimal(s string) string {
|
||||
var foundZero bool
|
||||
for i := len(s); i > 0; i-- {
|
||||
switch s[i-1] {
|
||||
case '.':
|
||||
if foundZero {
|
||||
return s[:i-1]
|
||||
}
|
||||
case '0':
|
||||
foundZero = true
|
||||
default:
|
||||
return s
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
2
vendor/github.com/spf13/viper/.editorconfig
generated
vendored
2
vendor/github.com/spf13/viper/.editorconfig
generated
vendored
@@ -11,5 +11,5 @@ trim_trailing_whitespace = true
|
||||
[*.go]
|
||||
indent_style = tab
|
||||
|
||||
[{Makefile, *.mk}]
|
||||
[{Makefile,*.mk}]
|
||||
indent_style = tab
|
||||
|
||||
@@ -3,7 +3,10 @@ run:
|
||||
|
||||
linters-settings:
|
||||
gci:
|
||||
local-prefixes: github.com/spf13/viper
|
||||
sections:
|
||||
- standard
|
||||
- default
|
||||
- prefix(github.com/spf13/viper)
|
||||
golint:
|
||||
min-confidence: 0
|
||||
goimports:
|
||||
6
vendor/github.com/spf13/viper/Makefile
generated
vendored
6
vendor/github.com/spf13/viper/Makefile
generated
vendored
@@ -15,8 +15,8 @@ TEST_FORMAT = short-verbose
|
||||
endif
|
||||
|
||||
# Dependency versions
|
||||
GOTESTSUM_VERSION = 1.7.0
|
||||
GOLANGCI_VERSION = 1.43.0
|
||||
GOTESTSUM_VERSION = 1.8.0
|
||||
GOLANGCI_VERSION = 1.49.0
|
||||
|
||||
# Add the ability to override some variables
|
||||
# Use with care
|
||||
@@ -48,7 +48,7 @@ bin/golangci-lint: bin/golangci-lint-${GOLANGCI_VERSION}
|
||||
@ln -sf golangci-lint-${GOLANGCI_VERSION} bin/golangci-lint
|
||||
bin/golangci-lint-${GOLANGCI_VERSION}:
|
||||
@mkdir -p bin
|
||||
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b ./bin/ v${GOLANGCI_VERSION}
|
||||
curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | bash -s -- -b ./bin/ v${GOLANGCI_VERSION}
|
||||
@mv bin/golangci-lint "$@"
|
||||
|
||||
.PHONY: lint
|
||||
|
||||
15
vendor/github.com/spf13/viper/README.md
generated
vendored
15
vendor/github.com/spf13/viper/README.md
generated
vendored
@@ -11,7 +11,7 @@
|
||||
[](https://github.com/spf13/viper/actions?query=workflow%3ACI)
|
||||
[](https://gitter.im/spf13/viper?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://goreportcard.com/report/github.com/spf13/viper)
|
||||

|
||||

|
||||
[](https://pkg.go.dev/mod/github.com/spf13/viper)
|
||||
|
||||
**Go configuration with fangs!**
|
||||
@@ -119,7 +119,7 @@ viper.AddConfigPath("$HOME/.appname") // call multiple times to add many search
|
||||
viper.AddConfigPath(".") // optionally look for config in the working directory
|
||||
err := viper.ReadInConfig() // Find and read the config file
|
||||
if err != nil { // Handle errors reading the config file
|
||||
panic(fmt.Errorf("Fatal error config file: %w \n", err))
|
||||
panic(fmt.Errorf("fatal error config file: %w", err))
|
||||
}
|
||||
```
|
||||
|
||||
@@ -447,6 +447,13 @@ viper.SetConfigType("json") // because there is no file extension in a stream of
|
||||
err := viper.ReadRemoteConfig()
|
||||
```
|
||||
|
||||
#### etcd3
|
||||
```go
|
||||
viper.AddRemoteProvider("etcd3", "http://127.0.0.1:4001","/config/hugo.json")
|
||||
viper.SetConfigType("json") // because there is no file extension in a stream of bytes, supported extensions are "json", "toml", "yaml", "yml", "properties", "props", "prop", "env", "dotenv"
|
||||
err := viper.ReadRemoteConfig()
|
||||
```
|
||||
|
||||
#### Consul
|
||||
You need to set a key to Consul key/value storage with JSON value containing your desired config.
|
||||
For example, create a Consul key/value store key `MY_CONSUL_KEY` with value:
|
||||
@@ -594,7 +601,7 @@ configuration level.
|
||||
|
||||
Viper can access array indices by using numbers in the path. For example:
|
||||
|
||||
```json
|
||||
```jsonc
|
||||
{
|
||||
"host": {
|
||||
"address": "localhost",
|
||||
@@ -622,7 +629,7 @@ GetInt("host.ports.1") // returns 6029
|
||||
Lastly, if there exists a key that matches the delimited key path, its value
|
||||
will be returned instead. E.g.
|
||||
|
||||
```json
|
||||
```jsonc
|
||||
{
|
||||
"datastore.metric.host": "0.0.0.0",
|
||||
"host": {
|
||||
|
||||
9
vendor/github.com/spf13/viper/TROUBLESHOOTING.md
generated
vendored
9
vendor/github.com/spf13/viper/TROUBLESHOOTING.md
generated
vendored
@@ -21,3 +21,12 @@ The solution is easy: switch to using Go Modules.
|
||||
Please refer to the [wiki](https://github.com/golang/go/wiki/Modules) on how to do that.
|
||||
|
||||
**tl;dr* `export GO111MODULE=on`
|
||||
|
||||
## Unquoted 'y' and 'n' characters get replaced with _true_ and _false_ when reading a YAML file
|
||||
|
||||
This is a YAML 1.1 feature according to [go-yaml/yaml#740](https://github.com/go-yaml/yaml/issues/740).
|
||||
|
||||
Potential solutions are:
|
||||
|
||||
1. Quoting values resolved as boolean
|
||||
1. Upgrading to YAML v3 (for the time being this is possible by passing the `viper_yaml3` tag to your build)
|
||||
|
||||
11
vendor/github.com/spf13/viper/experimental_logger.go
generated
vendored
Normal file
11
vendor/github.com/spf13/viper/experimental_logger.go
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
//go:build viper_logger
|
||||
// +build viper_logger
|
||||
|
||||
package viper
|
||||
|
||||
// WithLogger sets a custom logger.
|
||||
func WithLogger(l Logger) Option {
|
||||
return optionFunc(func(v *Viper) {
|
||||
v.logger = l
|
||||
})
|
||||
}
|
||||
6
vendor/github.com/spf13/viper/internal/encoding/decoder.go
generated
vendored
6
vendor/github.com/spf13/viper/internal/encoding/decoder.go
generated
vendored
@@ -4,10 +4,10 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Decoder decodes the contents of b into a v representation.
|
||||
// Decoder decodes the contents of b into v.
|
||||
// It's primarily used for decoding contents of a file into a map[string]interface{}.
|
||||
type Decoder interface {
|
||||
Decode(b []byte, v interface{}) error
|
||||
Decode(b []byte, v map[string]interface{}) error
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -48,7 +48,7 @@ func (e *DecoderRegistry) RegisterDecoder(format string, enc Decoder) error {
|
||||
}
|
||||
|
||||
// Decode calls the underlying Decoder based on the format.
|
||||
func (e *DecoderRegistry) Decode(format string, b []byte, v interface{}) error {
|
||||
func (e *DecoderRegistry) Decode(format string, b []byte, v map[string]interface{}) error {
|
||||
e.mu.RLock()
|
||||
decoder, ok := e.decoders[format]
|
||||
e.mu.RUnlock()
|
||||
|
||||
61
vendor/github.com/spf13/viper/internal/encoding/dotenv/codec.go
generated
vendored
Normal file
61
vendor/github.com/spf13/viper/internal/encoding/dotenv/codec.go
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
package dotenv
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/subosito/gotenv"
|
||||
)
|
||||
|
||||
const keyDelimiter = "_"
|
||||
|
||||
// Codec implements the encoding.Encoder and encoding.Decoder interfaces for encoding data containing environment variables
|
||||
// (commonly called as dotenv format).
|
||||
type Codec struct{}
|
||||
|
||||
func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
|
||||
flattened := map[string]interface{}{}
|
||||
|
||||
flattened = flattenAndMergeMap(flattened, v, "", keyDelimiter)
|
||||
|
||||
keys := make([]string, 0, len(flattened))
|
||||
|
||||
for key := range flattened {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
for _, key := range keys {
|
||||
_, err := buf.WriteString(fmt.Sprintf("%v=%v\n", strings.ToUpper(key), flattened[key]))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
func (Codec) Decode(b []byte, v map[string]interface{}) error {
|
||||
var buf bytes.Buffer
|
||||
|
||||
_, err := buf.Write(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
env, err := gotenv.StrictParse(&buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for key, value := range env {
|
||||
v[key] = value
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
41
vendor/github.com/spf13/viper/internal/encoding/dotenv/map_utils.go
generated
vendored
Normal file
41
vendor/github.com/spf13/viper/internal/encoding/dotenv/map_utils.go
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
package dotenv
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cast"
|
||||
)
|
||||
|
||||
// flattenAndMergeMap recursively flattens the given map into a new map
|
||||
// Code is based on the function with the same name in tha main package.
|
||||
// TODO: move it to a common place
|
||||
func flattenAndMergeMap(shadow map[string]interface{}, m map[string]interface{}, prefix string, delimiter string) map[string]interface{} {
|
||||
if shadow != nil && prefix != "" && shadow[prefix] != nil {
|
||||
// prefix is shadowed => nothing more to flatten
|
||||
return shadow
|
||||
}
|
||||
if shadow == nil {
|
||||
shadow = make(map[string]interface{})
|
||||
}
|
||||
|
||||
var m2 map[string]interface{}
|
||||
if prefix != "" {
|
||||
prefix += delimiter
|
||||
}
|
||||
for k, val := range m {
|
||||
fullKey := prefix + k
|
||||
switch val.(type) {
|
||||
case map[string]interface{}:
|
||||
m2 = val.(map[string]interface{})
|
||||
case map[interface{}]interface{}:
|
||||
m2 = cast.ToStringMap(val)
|
||||
default:
|
||||
// immediate value
|
||||
shadow[strings.ToLower(fullKey)] = val
|
||||
continue
|
||||
}
|
||||
// recursively merge to shadow map
|
||||
shadow = flattenAndMergeMap(shadow, m2, fullKey, delimiter)
|
||||
}
|
||||
return shadow
|
||||
}
|
||||
4
vendor/github.com/spf13/viper/internal/encoding/encoder.go
generated
vendored
4
vendor/github.com/spf13/viper/internal/encoding/encoder.go
generated
vendored
@@ -7,7 +7,7 @@ import (
|
||||
// Encoder encodes the contents of v into a byte representation.
|
||||
// It's primarily used for encoding a map[string]interface{} into a file format.
|
||||
type Encoder interface {
|
||||
Encode(v interface{}) ([]byte, error)
|
||||
Encode(v map[string]interface{}) ([]byte, error)
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -47,7 +47,7 @@ func (e *EncoderRegistry) RegisterEncoder(format string, enc Encoder) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *EncoderRegistry) Encode(format string, v interface{}) ([]byte, error) {
|
||||
func (e *EncoderRegistry) Encode(format string, v map[string]interface{}) ([]byte, error) {
|
||||
e.mu.RLock()
|
||||
encoder, ok := e.encoders[format]
|
||||
e.mu.RUnlock()
|
||||
|
||||
6
vendor/github.com/spf13/viper/internal/encoding/hcl/codec.go
generated
vendored
6
vendor/github.com/spf13/viper/internal/encoding/hcl/codec.go
generated
vendored
@@ -12,7 +12,7 @@ import (
|
||||
// TODO: add printer config to the codec?
|
||||
type Codec struct{}
|
||||
|
||||
func (Codec) Encode(v interface{}) ([]byte, error) {
|
||||
func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
|
||||
b, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -35,6 +35,6 @@ func (Codec) Encode(v interface{}) ([]byte, error) {
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
func (Codec) Decode(b []byte, v interface{}) error {
|
||||
return hcl.Unmarshal(b, v)
|
||||
func (Codec) Decode(b []byte, v map[string]interface{}) error {
|
||||
return hcl.Unmarshal(b, &v)
|
||||
}
|
||||
|
||||
99
vendor/github.com/spf13/viper/internal/encoding/ini/codec.go
generated
vendored
Normal file
99
vendor/github.com/spf13/viper/internal/encoding/ini/codec.go
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
package ini
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cast"
|
||||
"gopkg.in/ini.v1"
|
||||
)
|
||||
|
||||
// LoadOptions contains all customized options used for load data source(s).
|
||||
// This type is added here for convenience: this way consumers can import a single package called "ini".
|
||||
type LoadOptions = ini.LoadOptions
|
||||
|
||||
// Codec implements the encoding.Encoder and encoding.Decoder interfaces for INI encoding.
|
||||
type Codec struct {
|
||||
KeyDelimiter string
|
||||
LoadOptions LoadOptions
|
||||
}
|
||||
|
||||
func (c Codec) Encode(v map[string]interface{}) ([]byte, error) {
|
||||
cfg := ini.Empty()
|
||||
ini.PrettyFormat = false
|
||||
|
||||
flattened := map[string]interface{}{}
|
||||
|
||||
flattened = flattenAndMergeMap(flattened, v, "", c.keyDelimiter())
|
||||
|
||||
keys := make([]string, 0, len(flattened))
|
||||
|
||||
for key := range flattened {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
|
||||
for _, key := range keys {
|
||||
sectionName, keyName := "", key
|
||||
|
||||
lastSep := strings.LastIndex(key, ".")
|
||||
if lastSep != -1 {
|
||||
sectionName = key[:(lastSep)]
|
||||
keyName = key[(lastSep + 1):]
|
||||
}
|
||||
|
||||
// TODO: is this a good idea?
|
||||
if sectionName == "default" {
|
||||
sectionName = ""
|
||||
}
|
||||
|
||||
cfg.Section(sectionName).Key(keyName).SetValue(cast.ToString(flattened[key]))
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
_, err := cfg.WriteTo(&buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
func (c Codec) Decode(b []byte, v map[string]interface{}) error {
|
||||
cfg := ini.Empty(c.LoadOptions)
|
||||
|
||||
err := cfg.Append(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sections := cfg.Sections()
|
||||
|
||||
for i := 0; i < len(sections); i++ {
|
||||
section := sections[i]
|
||||
keys := section.Keys()
|
||||
|
||||
for j := 0; j < len(keys); j++ {
|
||||
key := keys[j]
|
||||
value := cfg.Section(section.Name()).Key(key.Name()).String()
|
||||
|
||||
deepestMap := deepSearch(v, strings.Split(section.Name(), c.keyDelimiter()))
|
||||
|
||||
// set innermost value
|
||||
deepestMap[key.Name()] = value
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Codec) keyDelimiter() string {
|
||||
if c.KeyDelimiter == "" {
|
||||
return "."
|
||||
}
|
||||
|
||||
return c.KeyDelimiter
|
||||
}
|
||||
74
vendor/github.com/spf13/viper/internal/encoding/ini/map_utils.go
generated
vendored
Normal file
74
vendor/github.com/spf13/viper/internal/encoding/ini/map_utils.go
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
package ini
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cast"
|
||||
)
|
||||
|
||||
// THIS CODE IS COPIED HERE: IT SHOULD NOT BE MODIFIED
|
||||
// AT SOME POINT IT WILL BE MOVED TO A COMMON PLACE
|
||||
// deepSearch scans deep maps, following the key indexes listed in the
|
||||
// sequence "path".
|
||||
// The last value is expected to be another map, and is returned.
|
||||
//
|
||||
// In case intermediate keys do not exist, or map to a non-map value,
|
||||
// a new map is created and inserted, and the search continues from there:
|
||||
// the initial map "m" may be modified!
|
||||
func deepSearch(m map[string]interface{}, path []string) map[string]interface{} {
|
||||
for _, k := range path {
|
||||
m2, ok := m[k]
|
||||
if !ok {
|
||||
// intermediate key does not exist
|
||||
// => create it and continue from there
|
||||
m3 := make(map[string]interface{})
|
||||
m[k] = m3
|
||||
m = m3
|
||||
continue
|
||||
}
|
||||
m3, ok := m2.(map[string]interface{})
|
||||
if !ok {
|
||||
// intermediate key is a value
|
||||
// => replace with a new map
|
||||
m3 = make(map[string]interface{})
|
||||
m[k] = m3
|
||||
}
|
||||
// continue search from here
|
||||
m = m3
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// flattenAndMergeMap recursively flattens the given map into a new map
|
||||
// Code is based on the function with the same name in tha main package.
|
||||
// TODO: move it to a common place
|
||||
func flattenAndMergeMap(shadow map[string]interface{}, m map[string]interface{}, prefix string, delimiter string) map[string]interface{} {
|
||||
if shadow != nil && prefix != "" && shadow[prefix] != nil {
|
||||
// prefix is shadowed => nothing more to flatten
|
||||
return shadow
|
||||
}
|
||||
if shadow == nil {
|
||||
shadow = make(map[string]interface{})
|
||||
}
|
||||
|
||||
var m2 map[string]interface{}
|
||||
if prefix != "" {
|
||||
prefix += delimiter
|
||||
}
|
||||
for k, val := range m {
|
||||
fullKey := prefix + k
|
||||
switch val.(type) {
|
||||
case map[string]interface{}:
|
||||
m2 = val.(map[string]interface{})
|
||||
case map[interface{}]interface{}:
|
||||
m2 = cast.ToStringMap(val)
|
||||
default:
|
||||
// immediate value
|
||||
shadow[strings.ToLower(fullKey)] = val
|
||||
continue
|
||||
}
|
||||
// recursively merge to shadow map
|
||||
shadow = flattenAndMergeMap(shadow, m2, fullKey, delimiter)
|
||||
}
|
||||
return shadow
|
||||
}
|
||||
86
vendor/github.com/spf13/viper/internal/encoding/javaproperties/codec.go
generated
vendored
Normal file
86
vendor/github.com/spf13/viper/internal/encoding/javaproperties/codec.go
generated
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
package javaproperties
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/magiconair/properties"
|
||||
"github.com/spf13/cast"
|
||||
)
|
||||
|
||||
// Codec implements the encoding.Encoder and encoding.Decoder interfaces for Java properties encoding.
|
||||
type Codec struct {
|
||||
KeyDelimiter string
|
||||
|
||||
// Store read properties on the object so that we can write back in order with comments.
|
||||
// This will only be used if the configuration read is a properties file.
|
||||
// TODO: drop this feature in v2
|
||||
// TODO: make use of the global properties object optional
|
||||
Properties *properties.Properties
|
||||
}
|
||||
|
||||
func (c *Codec) Encode(v map[string]interface{}) ([]byte, error) {
|
||||
if c.Properties == nil {
|
||||
c.Properties = properties.NewProperties()
|
||||
}
|
||||
|
||||
flattened := map[string]interface{}{}
|
||||
|
||||
flattened = flattenAndMergeMap(flattened, v, "", c.keyDelimiter())
|
||||
|
||||
keys := make([]string, 0, len(flattened))
|
||||
|
||||
for key := range flattened {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
|
||||
for _, key := range keys {
|
||||
_, _, err := c.Properties.Set(key, cast.ToString(flattened[key]))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
_, err := c.Properties.WriteComment(&buf, "#", properties.UTF8)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
func (c *Codec) Decode(b []byte, v map[string]interface{}) error {
|
||||
var err error
|
||||
c.Properties, err = properties.Load(b, properties.UTF8)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, key := range c.Properties.Keys() {
|
||||
// ignore existence check: we know it's there
|
||||
value, _ := c.Properties.Get(key)
|
||||
|
||||
// recursively build nested maps
|
||||
path := strings.Split(key, c.keyDelimiter())
|
||||
lastKey := strings.ToLower(path[len(path)-1])
|
||||
deepestMap := deepSearch(v, path[0:len(path)-1])
|
||||
|
||||
// set innermost value
|
||||
deepestMap[lastKey] = value
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Codec) keyDelimiter() string {
|
||||
if c.KeyDelimiter == "" {
|
||||
return "."
|
||||
}
|
||||
|
||||
return c.KeyDelimiter
|
||||
}
|
||||
74
vendor/github.com/spf13/viper/internal/encoding/javaproperties/map_utils.go
generated
vendored
Normal file
74
vendor/github.com/spf13/viper/internal/encoding/javaproperties/map_utils.go
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
package javaproperties
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cast"
|
||||
)
|
||||
|
||||
// THIS CODE IS COPIED HERE: IT SHOULD NOT BE MODIFIED
|
||||
// AT SOME POINT IT WILL BE MOVED TO A COMMON PLACE
|
||||
// deepSearch scans deep maps, following the key indexes listed in the
|
||||
// sequence "path".
|
||||
// The last value is expected to be another map, and is returned.
|
||||
//
|
||||
// In case intermediate keys do not exist, or map to a non-map value,
|
||||
// a new map is created and inserted, and the search continues from there:
|
||||
// the initial map "m" may be modified!
|
||||
func deepSearch(m map[string]interface{}, path []string) map[string]interface{} {
|
||||
for _, k := range path {
|
||||
m2, ok := m[k]
|
||||
if !ok {
|
||||
// intermediate key does not exist
|
||||
// => create it and continue from there
|
||||
m3 := make(map[string]interface{})
|
||||
m[k] = m3
|
||||
m = m3
|
||||
continue
|
||||
}
|
||||
m3, ok := m2.(map[string]interface{})
|
||||
if !ok {
|
||||
// intermediate key is a value
|
||||
// => replace with a new map
|
||||
m3 = make(map[string]interface{})
|
||||
m[k] = m3
|
||||
}
|
||||
// continue search from here
|
||||
m = m3
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// flattenAndMergeMap recursively flattens the given map into a new map
|
||||
// Code is based on the function with the same name in tha main package.
|
||||
// TODO: move it to a common place
|
||||
func flattenAndMergeMap(shadow map[string]interface{}, m map[string]interface{}, prefix string, delimiter string) map[string]interface{} {
|
||||
if shadow != nil && prefix != "" && shadow[prefix] != nil {
|
||||
// prefix is shadowed => nothing more to flatten
|
||||
return shadow
|
||||
}
|
||||
if shadow == nil {
|
||||
shadow = make(map[string]interface{})
|
||||
}
|
||||
|
||||
var m2 map[string]interface{}
|
||||
if prefix != "" {
|
||||
prefix += delimiter
|
||||
}
|
||||
for k, val := range m {
|
||||
fullKey := prefix + k
|
||||
switch val.(type) {
|
||||
case map[string]interface{}:
|
||||
m2 = val.(map[string]interface{})
|
||||
case map[interface{}]interface{}:
|
||||
m2 = cast.ToStringMap(val)
|
||||
default:
|
||||
// immediate value
|
||||
shadow[strings.ToLower(fullKey)] = val
|
||||
continue
|
||||
}
|
||||
// recursively merge to shadow map
|
||||
shadow = flattenAndMergeMap(shadow, m2, fullKey, delimiter)
|
||||
}
|
||||
return shadow
|
||||
}
|
||||
6
vendor/github.com/spf13/viper/internal/encoding/json/codec.go
generated
vendored
6
vendor/github.com/spf13/viper/internal/encoding/json/codec.go
generated
vendored
@@ -7,11 +7,11 @@ import (
|
||||
// Codec implements the encoding.Encoder and encoding.Decoder interfaces for JSON encoding.
|
||||
type Codec struct{}
|
||||
|
||||
func (Codec) Encode(v interface{}) ([]byte, error) {
|
||||
func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
|
||||
// TODO: expose prefix and indent in the Codec as setting?
|
||||
return json.MarshalIndent(v, "", " ")
|
||||
}
|
||||
|
||||
func (Codec) Decode(b []byte, v interface{}) error {
|
||||
return json.Unmarshal(b, v)
|
||||
func (Codec) Decode(b []byte, v map[string]interface{}) error {
|
||||
return json.Unmarshal(b, &v)
|
||||
}
|
||||
|
||||
42
vendor/github.com/spf13/viper/internal/encoding/toml/codec.go
generated
vendored
42
vendor/github.com/spf13/viper/internal/encoding/toml/codec.go
generated
vendored
@@ -1,3 +1,6 @@
|
||||
//go:build viper_toml1
|
||||
// +build viper_toml1
|
||||
|
||||
package toml
|
||||
|
||||
import (
|
||||
@@ -7,39 +10,30 @@ import (
|
||||
// Codec implements the encoding.Encoder and encoding.Decoder interfaces for TOML encoding.
|
||||
type Codec struct{}
|
||||
|
||||
func (Codec) Encode(v interface{}) ([]byte, error) {
|
||||
if m, ok := v.(map[string]interface{}); ok {
|
||||
t, err := toml.TreeFromMap(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s, err := t.ToTomlString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return []byte(s), nil
|
||||
func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
|
||||
t, err := toml.TreeFromMap(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return toml.Marshal(v)
|
||||
s, err := t.ToTomlString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return []byte(s), nil
|
||||
}
|
||||
|
||||
func (Codec) Decode(b []byte, v interface{}) error {
|
||||
func (Codec) Decode(b []byte, v map[string]interface{}) error {
|
||||
tree, err := toml.LoadBytes(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if m, ok := v.(*map[string]interface{}); ok {
|
||||
vmap := *m
|
||||
tmap := tree.ToMap()
|
||||
for k, v := range tmap {
|
||||
vmap[k] = v
|
||||
}
|
||||
|
||||
return nil
|
||||
tmap := tree.ToMap()
|
||||
for key, value := range tmap {
|
||||
v[key] = value
|
||||
}
|
||||
|
||||
return tree.Unmarshal(v)
|
||||
return nil
|
||||
}
|
||||
|
||||
19
vendor/github.com/spf13/viper/internal/encoding/toml/codec2.go
generated
vendored
Normal file
19
vendor/github.com/spf13/viper/internal/encoding/toml/codec2.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
//go:build !viper_toml1
|
||||
// +build !viper_toml1
|
||||
|
||||
package toml
|
||||
|
||||
import (
|
||||
"github.com/pelletier/go-toml/v2"
|
||||
)
|
||||
|
||||
// Codec implements the encoding.Encoder and encoding.Decoder interfaces for TOML encoding.
|
||||
type Codec struct{}
|
||||
|
||||
func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
|
||||
return toml.Marshal(v)
|
||||
}
|
||||
|
||||
func (Codec) Decode(b []byte, v map[string]interface{}) error {
|
||||
return toml.Unmarshal(b, &v)
|
||||
}
|
||||
8
vendor/github.com/spf13/viper/internal/encoding/yaml/codec.go
generated
vendored
8
vendor/github.com/spf13/viper/internal/encoding/yaml/codec.go
generated
vendored
@@ -1,14 +1,14 @@
|
||||
package yaml
|
||||
|
||||
import "gopkg.in/yaml.v2"
|
||||
// import "gopkg.in/yaml.v2"
|
||||
|
||||
// Codec implements the encoding.Encoder and encoding.Decoder interfaces for YAML encoding.
|
||||
type Codec struct{}
|
||||
|
||||
func (Codec) Encode(v interface{}) ([]byte, error) {
|
||||
func (Codec) Encode(v map[string]interface{}) ([]byte, error) {
|
||||
return yaml.Marshal(v)
|
||||
}
|
||||
|
||||
func (Codec) Decode(b []byte, v interface{}) error {
|
||||
return yaml.Unmarshal(b, v)
|
||||
func (Codec) Decode(b []byte, v map[string]interface{}) error {
|
||||
return yaml.Unmarshal(b, &v)
|
||||
}
|
||||
|
||||
14
vendor/github.com/spf13/viper/internal/encoding/yaml/yaml2.go
generated
vendored
Normal file
14
vendor/github.com/spf13/viper/internal/encoding/yaml/yaml2.go
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
//go:build viper_yaml2
|
||||
// +build viper_yaml2
|
||||
|
||||
package yaml
|
||||
|
||||
import yamlv2 "gopkg.in/yaml.v2"
|
||||
|
||||
var yaml = struct {
|
||||
Marshal func(in interface{}) (out []byte, err error)
|
||||
Unmarshal func(in []byte, out interface{}) (err error)
|
||||
}{
|
||||
Marshal: yamlv2.Marshal,
|
||||
Unmarshal: yamlv2.Unmarshal,
|
||||
}
|
||||
14
vendor/github.com/spf13/viper/internal/encoding/yaml/yaml3.go
generated
vendored
Normal file
14
vendor/github.com/spf13/viper/internal/encoding/yaml/yaml3.go
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
//go:build !viper_yaml2
|
||||
// +build !viper_yaml2
|
||||
|
||||
package yaml
|
||||
|
||||
import yamlv3 "gopkg.in/yaml.v3"
|
||||
|
||||
var yaml = struct {
|
||||
Marshal func(in interface{}) (out []byte, err error)
|
||||
Unmarshal func(in []byte, out interface{}) (err error)
|
||||
}{
|
||||
Marshal: yamlv3.Marshal,
|
||||
Unmarshal: yamlv3.Unmarshal,
|
||||
}
|
||||
4
vendor/github.com/spf13/viper/logger.go
generated
vendored
4
vendor/github.com/spf13/viper/logger.go
generated
vendored
@@ -7,8 +7,8 @@ import (
|
||||
)
|
||||
|
||||
// Logger is a unified interface for various logging use cases and practices, including:
|
||||
// - leveled logging
|
||||
// - structured logging
|
||||
// - leveled logging
|
||||
// - structured logging
|
||||
type Logger interface {
|
||||
// Trace logs a Trace event.
|
||||
//
|
||||
|
||||
33
vendor/github.com/spf13/viper/util.go
generated
vendored
33
vendor/github.com/spf13/viper/util.go
generated
vendored
@@ -64,18 +64,25 @@ func copyAndInsensitiviseMap(m map[string]interface{}) map[string]interface{} {
|
||||
return nm
|
||||
}
|
||||
|
||||
func insensitiviseVal(val interface{}) interface{} {
|
||||
switch val.(type) {
|
||||
case map[interface{}]interface{}:
|
||||
// nested map: cast and recursively insensitivise
|
||||
val = cast.ToStringMap(val)
|
||||
insensitiviseMap(val.(map[string]interface{}))
|
||||
case map[string]interface{}:
|
||||
// nested map: recursively insensitivise
|
||||
insensitiviseMap(val.(map[string]interface{}))
|
||||
case []interface{}:
|
||||
// nested array: recursively insensitivise
|
||||
insensitiveArray(val.([]interface{}))
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
func insensitiviseMap(m map[string]interface{}) {
|
||||
for key, val := range m {
|
||||
switch val.(type) {
|
||||
case map[interface{}]interface{}:
|
||||
// nested map: cast and recursively insensitivise
|
||||
val = cast.ToStringMap(val)
|
||||
insensitiviseMap(val.(map[string]interface{}))
|
||||
case map[string]interface{}:
|
||||
// nested map: recursively insensitivise
|
||||
insensitiviseMap(val.(map[string]interface{}))
|
||||
}
|
||||
|
||||
val = insensitiviseVal(val)
|
||||
lower := strings.ToLower(key)
|
||||
if key != lower {
|
||||
// remove old key (not lower-cased)
|
||||
@@ -86,6 +93,12 @@ func insensitiviseMap(m map[string]interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
func insensitiveArray(a []interface{}) {
|
||||
for i, val := range a {
|
||||
a[i] = insensitiviseVal(val)
|
||||
}
|
||||
}
|
||||
|
||||
func absPathify(logger Logger, inPath string) string {
|
||||
logger.Info("trying to resolve absolute path", "path", inPath)
|
||||
|
||||
|
||||
394
vendor/github.com/spf13/viper/viper.go
generated
vendored
394
vendor/github.com/spf13/viper/viper.go
generated
vendored
@@ -35,16 +35,16 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/magiconair/properties"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/spf13/afero"
|
||||
"github.com/spf13/cast"
|
||||
"github.com/spf13/pflag"
|
||||
"github.com/subosito/gotenv"
|
||||
"gopkg.in/ini.v1"
|
||||
|
||||
"github.com/spf13/viper/internal/encoding"
|
||||
"github.com/spf13/viper/internal/encoding/dotenv"
|
||||
"github.com/spf13/viper/internal/encoding/hcl"
|
||||
"github.com/spf13/viper/internal/encoding/ini"
|
||||
"github.com/spf13/viper/internal/encoding/javaproperties"
|
||||
"github.com/spf13/viper/internal/encoding/json"
|
||||
"github.com/spf13/viper/internal/encoding/toml"
|
||||
"github.com/spf13/viper/internal/encoding/yaml"
|
||||
@@ -67,47 +67,8 @@ type RemoteResponse struct {
|
||||
Error error
|
||||
}
|
||||
|
||||
var (
|
||||
encoderRegistry = encoding.NewEncoderRegistry()
|
||||
decoderRegistry = encoding.NewDecoderRegistry()
|
||||
)
|
||||
|
||||
func init() {
|
||||
v = New()
|
||||
|
||||
{
|
||||
codec := yaml.Codec{}
|
||||
|
||||
encoderRegistry.RegisterEncoder("yaml", codec)
|
||||
decoderRegistry.RegisterDecoder("yaml", codec)
|
||||
|
||||
encoderRegistry.RegisterEncoder("yml", codec)
|
||||
decoderRegistry.RegisterDecoder("yml", codec)
|
||||
}
|
||||
|
||||
{
|
||||
codec := json.Codec{}
|
||||
|
||||
encoderRegistry.RegisterEncoder("json", codec)
|
||||
decoderRegistry.RegisterDecoder("json", codec)
|
||||
}
|
||||
|
||||
{
|
||||
codec := toml.Codec{}
|
||||
|
||||
encoderRegistry.RegisterEncoder("toml", codec)
|
||||
decoderRegistry.RegisterDecoder("toml", codec)
|
||||
}
|
||||
|
||||
{
|
||||
codec := hcl.Codec{}
|
||||
|
||||
encoderRegistry.RegisterEncoder("hcl", codec)
|
||||
decoderRegistry.RegisterDecoder("hcl", codec)
|
||||
|
||||
encoderRegistry.RegisterEncoder("tfvars", codec)
|
||||
decoderRegistry.RegisterDecoder("tfvars", codec)
|
||||
}
|
||||
}
|
||||
|
||||
type remoteConfigFactory interface {
|
||||
@@ -171,10 +132,10 @@ type DecoderConfigOption func(*mapstructure.DecoderConfig)
|
||||
// DecodeHook returns a DecoderConfigOption which overrides the default
|
||||
// DecoderConfig.DecodeHook value, the default is:
|
||||
//
|
||||
// mapstructure.ComposeDecodeHookFunc(
|
||||
// mapstructure.StringToTimeDurationHookFunc(),
|
||||
// mapstructure.StringToSliceHookFunc(","),
|
||||
// )
|
||||
// mapstructure.ComposeDecodeHookFunc(
|
||||
// mapstructure.StringToTimeDurationHookFunc(),
|
||||
// mapstructure.StringToSliceHookFunc(","),
|
||||
// )
|
||||
func DecodeHook(hook mapstructure.DecodeHookFunc) DecoderConfigOption {
|
||||
return func(c *mapstructure.DecoderConfig) {
|
||||
c.DecodeHook = hook
|
||||
@@ -195,18 +156,18 @@ func DecodeHook(hook mapstructure.DecodeHookFunc) DecoderConfigOption {
|
||||
//
|
||||
// For example, if values from the following sources were loaded:
|
||||
//
|
||||
// Defaults : {
|
||||
// "secret": "",
|
||||
// "user": "default",
|
||||
// "endpoint": "https://localhost"
|
||||
// }
|
||||
// Config : {
|
||||
// "user": "root"
|
||||
// "secret": "defaultsecret"
|
||||
// }
|
||||
// Env : {
|
||||
// "secret": "somesecretkey"
|
||||
// }
|
||||
// Defaults : {
|
||||
// "secret": "",
|
||||
// "user": "default",
|
||||
// "endpoint": "https://localhost"
|
||||
// }
|
||||
// Config : {
|
||||
// "user": "root"
|
||||
// "secret": "defaultsecret"
|
||||
// }
|
||||
// Env : {
|
||||
// "secret": "somesecretkey"
|
||||
// }
|
||||
//
|
||||
// The resulting config will have the following values:
|
||||
//
|
||||
@@ -254,13 +215,13 @@ type Viper struct {
|
||||
aliases map[string]string
|
||||
typeByDefValue bool
|
||||
|
||||
// Store read properties on the object so that we can write back in order with comments.
|
||||
// This will only be used if the configuration read is a properties file.
|
||||
properties *properties.Properties
|
||||
|
||||
onConfigChange func(fsnotify.Event)
|
||||
|
||||
logger Logger
|
||||
|
||||
// TODO: should probably be protected with a mutex
|
||||
encoderRegistry *encoding.EncoderRegistry
|
||||
decoderRegistry *encoding.DecoderRegistry
|
||||
}
|
||||
|
||||
// New returns an initialized Viper instance.
|
||||
@@ -280,6 +241,8 @@ func New() *Viper {
|
||||
v.typeByDefValue = false
|
||||
v.logger = jwwLogger{}
|
||||
|
||||
v.resetEncoding()
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
@@ -326,6 +289,8 @@ func NewWithOptions(opts ...Option) *Viper {
|
||||
opt.apply(v)
|
||||
}
|
||||
|
||||
v.resetEncoding()
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
@@ -335,7 +300,85 @@ func NewWithOptions(opts ...Option) *Viper {
|
||||
func Reset() {
|
||||
v = New()
|
||||
SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "tfvars", "dotenv", "env", "ini"}
|
||||
SupportedRemoteProviders = []string{"etcd", "consul", "firestore"}
|
||||
SupportedRemoteProviders = []string{"etcd", "etcd3", "consul", "firestore"}
|
||||
}
|
||||
|
||||
// TODO: make this lazy initialization instead
|
||||
func (v *Viper) resetEncoding() {
|
||||
encoderRegistry := encoding.NewEncoderRegistry()
|
||||
decoderRegistry := encoding.NewDecoderRegistry()
|
||||
|
||||
{
|
||||
codec := yaml.Codec{}
|
||||
|
||||
encoderRegistry.RegisterEncoder("yaml", codec)
|
||||
decoderRegistry.RegisterDecoder("yaml", codec)
|
||||
|
||||
encoderRegistry.RegisterEncoder("yml", codec)
|
||||
decoderRegistry.RegisterDecoder("yml", codec)
|
||||
}
|
||||
|
||||
{
|
||||
codec := json.Codec{}
|
||||
|
||||
encoderRegistry.RegisterEncoder("json", codec)
|
||||
decoderRegistry.RegisterDecoder("json", codec)
|
||||
}
|
||||
|
||||
{
|
||||
codec := toml.Codec{}
|
||||
|
||||
encoderRegistry.RegisterEncoder("toml", codec)
|
||||
decoderRegistry.RegisterDecoder("toml", codec)
|
||||
}
|
||||
|
||||
{
|
||||
codec := hcl.Codec{}
|
||||
|
||||
encoderRegistry.RegisterEncoder("hcl", codec)
|
||||
decoderRegistry.RegisterDecoder("hcl", codec)
|
||||
|
||||
encoderRegistry.RegisterEncoder("tfvars", codec)
|
||||
decoderRegistry.RegisterDecoder("tfvars", codec)
|
||||
}
|
||||
|
||||
{
|
||||
codec := ini.Codec{
|
||||
KeyDelimiter: v.keyDelim,
|
||||
LoadOptions: v.iniLoadOptions,
|
||||
}
|
||||
|
||||
encoderRegistry.RegisterEncoder("ini", codec)
|
||||
decoderRegistry.RegisterDecoder("ini", codec)
|
||||
}
|
||||
|
||||
{
|
||||
codec := &javaproperties.Codec{
|
||||
KeyDelimiter: v.keyDelim,
|
||||
}
|
||||
|
||||
encoderRegistry.RegisterEncoder("properties", codec)
|
||||
decoderRegistry.RegisterDecoder("properties", codec)
|
||||
|
||||
encoderRegistry.RegisterEncoder("props", codec)
|
||||
decoderRegistry.RegisterDecoder("props", codec)
|
||||
|
||||
encoderRegistry.RegisterEncoder("prop", codec)
|
||||
decoderRegistry.RegisterDecoder("prop", codec)
|
||||
}
|
||||
|
||||
{
|
||||
codec := &dotenv.Codec{}
|
||||
|
||||
encoderRegistry.RegisterEncoder("dotenv", codec)
|
||||
decoderRegistry.RegisterDecoder("dotenv", codec)
|
||||
|
||||
encoderRegistry.RegisterEncoder("env", codec)
|
||||
decoderRegistry.RegisterDecoder("env", codec)
|
||||
}
|
||||
|
||||
v.encoderRegistry = encoderRegistry
|
||||
v.decoderRegistry = decoderRegistry
|
||||
}
|
||||
|
||||
type defaultRemoteProvider struct {
|
||||
@@ -376,7 +419,7 @@ type RemoteProvider interface {
|
||||
var SupportedExts = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop", "hcl", "tfvars", "dotenv", "env", "ini"}
|
||||
|
||||
// SupportedRemoteProviders are universally supported remote providers.
|
||||
var SupportedRemoteProviders = []string{"etcd", "consul", "firestore"}
|
||||
var SupportedRemoteProviders = []string{"etcd", "etcd3", "consul", "firestore"}
|
||||
|
||||
func OnConfigChange(run func(in fsnotify.Event)) { v.OnConfigChange(run) }
|
||||
func (v *Viper) OnConfigChange(run func(in fsnotify.Event)) {
|
||||
@@ -433,7 +476,7 @@ func (v *Viper) WatchConfig() {
|
||||
v.onConfigChange(event)
|
||||
}
|
||||
} else if filepath.Clean(event.Name) == configFile &&
|
||||
event.Op&fsnotify.Remove&fsnotify.Remove != 0 {
|
||||
event.Op&fsnotify.Remove != 0 {
|
||||
eventsWG.Done()
|
||||
return
|
||||
}
|
||||
@@ -530,7 +573,7 @@ func (v *Viper) AddConfigPath(in string) {
|
||||
|
||||
// AddRemoteProvider adds a remote configuration source.
|
||||
// Remote Providers are searched in the order they are added.
|
||||
// provider is a string value: "etcd", "consul" or "firestore" are currently supported.
|
||||
// provider is a string value: "etcd", "etcd3", "consul" or "firestore" are currently supported.
|
||||
// endpoint is the url. etcd requires http://ip:port consul requires ip:port
|
||||
// path is the path in the k/v store to retrieve configuration
|
||||
// To retrieve a config file called myapp.json from /configs/myapp.json
|
||||
@@ -561,7 +604,7 @@ func (v *Viper) AddRemoteProvider(provider, endpoint, path string) error {
|
||||
|
||||
// AddSecureRemoteProvider adds a remote configuration source.
|
||||
// Secure Remote Providers are searched in the order they are added.
|
||||
// provider is a string value: "etcd", "consul" or "firestore" are currently supported.
|
||||
// provider is a string value: "etcd", "etcd3", "consul" or "firestore" are currently supported.
|
||||
// endpoint is the url. etcd requires http://ip:port consul requires ip:port
|
||||
// secretkeyring is the filepath to your openpgp secret keyring. e.g. /etc/secrets/myring.gpg
|
||||
// path is the path in the k/v store to retrieve configuration
|
||||
@@ -742,7 +785,8 @@ func (v *Viper) searchMapWithPathPrefixes(
|
||||
// isPathShadowedInDeepMap makes sure the given path is not shadowed somewhere
|
||||
// on its path in the map.
|
||||
// e.g., if "foo.bar" has a value in the given map, it “shadows”
|
||||
// "foo.bar.baz" in a lower-priority map
|
||||
//
|
||||
// "foo.bar.baz" in a lower-priority map
|
||||
func (v *Viper) isPathShadowedInDeepMap(path []string, m map[string]interface{}) string {
|
||||
var parentVal interface{}
|
||||
for i := 1; i < len(path); i++ {
|
||||
@@ -767,7 +811,8 @@ func (v *Viper) isPathShadowedInDeepMap(path []string, m map[string]interface{})
|
||||
// isPathShadowedInFlatMap makes sure the given path is not shadowed somewhere
|
||||
// in a sub-path of the map.
|
||||
// e.g., if "foo.bar" has a value in the given map, it “shadows”
|
||||
// "foo.bar.baz" in a lower-priority map
|
||||
//
|
||||
// "foo.bar.baz" in a lower-priority map
|
||||
func (v *Viper) isPathShadowedInFlatMap(path []string, mi interface{}) string {
|
||||
// unify input map
|
||||
var m map[string]interface{}
|
||||
@@ -792,7 +837,8 @@ func (v *Viper) isPathShadowedInFlatMap(path []string, mi interface{}) string {
|
||||
// isPathShadowedInAutoEnv makes sure the given path is not shadowed somewhere
|
||||
// in the environment, when automatic env is on.
|
||||
// e.g., if "foo.bar" has a value in the environment, it “shadows”
|
||||
// "foo.bar.baz" in a lower-priority map
|
||||
//
|
||||
// "foo.bar.baz" in a lower-priority map
|
||||
func (v *Viper) isPathShadowedInAutoEnv(path []string) string {
|
||||
var parentKey string
|
||||
for i := 1; i < len(path); i++ {
|
||||
@@ -813,11 +859,11 @@ func (v *Viper) isPathShadowedInAutoEnv(path []string) string {
|
||||
// would return a string slice for the key if the key's type is inferred by
|
||||
// the default value and the Get function would return:
|
||||
//
|
||||
// []string {"a", "b", "c"}
|
||||
// []string {"a", "b", "c"}
|
||||
//
|
||||
// Otherwise the Get function would return:
|
||||
//
|
||||
// "a b c"
|
||||
// "a b c"
|
||||
func SetTypeByDefaultValue(enable bool) { v.SetTypeByDefaultValue(enable) }
|
||||
|
||||
func (v *Viper) SetTypeByDefaultValue(enable bool) {
|
||||
@@ -945,6 +991,13 @@ func (v *Viper) GetUint(key string) uint {
|
||||
return cast.ToUint(v.Get(key))
|
||||
}
|
||||
|
||||
// GetUint16 returns the value associated with the key as an unsigned integer.
|
||||
func GetUint16(key string) uint16 { return v.GetUint16(key) }
|
||||
|
||||
func (v *Viper) GetUint16(key string) uint16 {
|
||||
return cast.ToUint16(v.Get(key))
|
||||
}
|
||||
|
||||
// GetUint32 returns the value associated with the key as an unsigned integer.
|
||||
func GetUint32(key string) uint32 { return v.GetUint32(key) }
|
||||
|
||||
@@ -1094,9 +1147,8 @@ func (v *Viper) BindPFlags(flags *pflag.FlagSet) error {
|
||||
// BindPFlag binds a specific key to a pflag (as used by cobra).
|
||||
// Example (where serverCmd is a Cobra instance):
|
||||
//
|
||||
// serverCmd.Flags().Int("port", 1138, "Port to run Application server on")
|
||||
// Viper.BindPFlag("port", serverCmd.Flags().Lookup("port"))
|
||||
//
|
||||
// serverCmd.Flags().Int("port", 1138, "Port to run Application server on")
|
||||
// Viper.BindPFlag("port", serverCmd.Flags().Lookup("port"))
|
||||
func BindPFlag(key string, flag *pflag.Flag) error { return v.BindPFlag(key, flag) }
|
||||
|
||||
func (v *Viper) BindPFlag(key string, flag *pflag.Flag) error {
|
||||
@@ -1154,6 +1206,17 @@ func (v *Viper) BindEnv(input ...string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MustBindEnv wraps BindEnv in a panic.
|
||||
// If there is an error binding an environment variable, MustBindEnv will
|
||||
// panic.
|
||||
func MustBindEnv(input ...string) { v.MustBindEnv(input...) }
|
||||
|
||||
func (v *Viper) MustBindEnv(input ...string) {
|
||||
if err := v.BindEnv(input...); err != nil {
|
||||
panic(fmt.Sprintf("error while binding environment variable: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
// Given a key, find the value.
|
||||
//
|
||||
// Viper will check to see if an alias exists first.
|
||||
@@ -1634,53 +1697,11 @@ func (v *Viper) unmarshalReader(in io.Reader, c map[string]interface{}) error {
|
||||
buf.ReadFrom(in)
|
||||
|
||||
switch format := strings.ToLower(v.getConfigType()); format {
|
||||
case "yaml", "yml", "json", "toml", "hcl", "tfvars":
|
||||
err := decoderRegistry.Decode(format, buf.Bytes(), &c)
|
||||
case "yaml", "yml", "json", "toml", "hcl", "tfvars", "ini", "properties", "props", "prop", "dotenv", "env":
|
||||
err := v.decoderRegistry.Decode(format, buf.Bytes(), c)
|
||||
if err != nil {
|
||||
return ConfigParseError{err}
|
||||
}
|
||||
|
||||
case "dotenv", "env":
|
||||
env, err := gotenv.StrictParse(buf)
|
||||
if err != nil {
|
||||
return ConfigParseError{err}
|
||||
}
|
||||
for k, v := range env {
|
||||
c[k] = v
|
||||
}
|
||||
|
||||
case "properties", "props", "prop":
|
||||
v.properties = properties.NewProperties()
|
||||
var err error
|
||||
if v.properties, err = properties.Load(buf.Bytes(), properties.UTF8); err != nil {
|
||||
return ConfigParseError{err}
|
||||
}
|
||||
for _, key := range v.properties.Keys() {
|
||||
value, _ := v.properties.Get(key)
|
||||
// recursively build nested maps
|
||||
path := strings.Split(key, ".")
|
||||
lastKey := strings.ToLower(path[len(path)-1])
|
||||
deepestMap := deepSearch(c, path[0:len(path)-1])
|
||||
// set innermost value
|
||||
deepestMap[lastKey] = value
|
||||
}
|
||||
|
||||
case "ini":
|
||||
cfg := ini.Empty(v.iniLoadOptions)
|
||||
err := cfg.Append(buf.Bytes())
|
||||
if err != nil {
|
||||
return ConfigParseError{err}
|
||||
}
|
||||
sections := cfg.Sections()
|
||||
for i := 0; i < len(sections); i++ {
|
||||
section := sections[i]
|
||||
keys := section.Keys()
|
||||
for j := 0; j < len(keys); j++ {
|
||||
key := keys[j]
|
||||
value := cfg.Section(section.Name()).Key(key.Name()).String()
|
||||
c[section.Name()+"."+key.Name()] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
insensitiviseMap(c)
|
||||
@@ -1691,8 +1712,8 @@ func (v *Viper) unmarshalReader(in io.Reader, c map[string]interface{}) error {
|
||||
func (v *Viper) marshalWriter(f afero.File, configType string) error {
|
||||
c := v.AllSettings()
|
||||
switch configType {
|
||||
case "yaml", "yml", "json", "toml", "hcl", "tfvars":
|
||||
b, err := encoderRegistry.Encode(configType, c)
|
||||
case "yaml", "yml", "json", "toml", "hcl", "tfvars", "ini", "prop", "props", "properties", "dotenv", "env":
|
||||
b, err := v.encoderRegistry.Encode(configType, c)
|
||||
if err != nil {
|
||||
return ConfigMarshalError{err}
|
||||
}
|
||||
@@ -1701,50 +1722,6 @@ func (v *Viper) marshalWriter(f afero.File, configType string) error {
|
||||
if err != nil {
|
||||
return ConfigMarshalError{err}
|
||||
}
|
||||
|
||||
case "prop", "props", "properties":
|
||||
if v.properties == nil {
|
||||
v.properties = properties.NewProperties()
|
||||
}
|
||||
p := v.properties
|
||||
for _, key := range v.AllKeys() {
|
||||
_, _, err := p.Set(key, v.GetString(key))
|
||||
if err != nil {
|
||||
return ConfigMarshalError{err}
|
||||
}
|
||||
}
|
||||
_, err := p.WriteComment(f, "#", properties.UTF8)
|
||||
if err != nil {
|
||||
return ConfigMarshalError{err}
|
||||
}
|
||||
|
||||
case "dotenv", "env":
|
||||
lines := []string{}
|
||||
for _, key := range v.AllKeys() {
|
||||
envName := strings.ToUpper(strings.Replace(key, ".", "_", -1))
|
||||
val := v.Get(key)
|
||||
lines = append(lines, fmt.Sprintf("%v=%v", envName, val))
|
||||
}
|
||||
s := strings.Join(lines, "\n")
|
||||
if _, err := f.WriteString(s); err != nil {
|
||||
return ConfigMarshalError{err}
|
||||
}
|
||||
|
||||
case "ini":
|
||||
keys := v.AllKeys()
|
||||
cfg := ini.Empty()
|
||||
ini.PrettyFormat = false
|
||||
for i := 0; i < len(keys); i++ {
|
||||
key := keys[i]
|
||||
lastSep := strings.LastIndex(key, ".")
|
||||
sectionName := key[:(lastSep)]
|
||||
keyName := key[(lastSep + 1):]
|
||||
if sectionName == "default" {
|
||||
sectionName = ""
|
||||
}
|
||||
cfg.Section(sectionName).Key(keyName).SetValue(v.GetString(key))
|
||||
}
|
||||
cfg.WriteTo(f)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1761,7 +1738,8 @@ func keyExists(k string, m map[string]interface{}) string {
|
||||
}
|
||||
|
||||
func castToMapStringInterface(
|
||||
src map[interface{}]interface{}) map[string]interface{} {
|
||||
src map[interface{}]interface{},
|
||||
) map[string]interface{} {
|
||||
tgt := map[string]interface{}{}
|
||||
for k, v := range src {
|
||||
tgt[fmt.Sprintf("%v", k)] = v
|
||||
@@ -1799,7 +1777,8 @@ func castMapFlagToMapInterface(src map[string]FlagValue) map[string]interface{}
|
||||
// deep. Both map types are supported as there is a go-yaml fork that uses
|
||||
// `map[string]interface{}` instead.
|
||||
func mergeMaps(
|
||||
src, tgt map[string]interface{}, itgt map[interface{}]interface{}) {
|
||||
src, tgt map[string]interface{}, itgt map[interface{}]interface{},
|
||||
) {
|
||||
for sk, sv := range src {
|
||||
tk := keyExists(sk, tgt)
|
||||
if tk == "" {
|
||||
@@ -1823,17 +1802,6 @@ func mergeMaps(
|
||||
|
||||
svType := reflect.TypeOf(sv)
|
||||
tvType := reflect.TypeOf(tv)
|
||||
if tvType != nil && svType != tvType { // Allow for the target to be nil
|
||||
v.logger.Error(
|
||||
"svType != tvType",
|
||||
"key", sk,
|
||||
"st", svType,
|
||||
"tt", tvType,
|
||||
"sv", sv,
|
||||
"tv", tv,
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
v.logger.Trace(
|
||||
"processing",
|
||||
@@ -1847,13 +1815,37 @@ func mergeMaps(
|
||||
switch ttv := tv.(type) {
|
||||
case map[interface{}]interface{}:
|
||||
v.logger.Trace("merging maps (must convert)")
|
||||
tsv := sv.(map[interface{}]interface{})
|
||||
tsv, ok := sv.(map[interface{}]interface{})
|
||||
if !ok {
|
||||
v.logger.Error(
|
||||
"Could not cast sv to map[interface{}]interface{}",
|
||||
"key", sk,
|
||||
"st", svType,
|
||||
"tt", tvType,
|
||||
"sv", sv,
|
||||
"tv", tv,
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
ssv := castToMapStringInterface(tsv)
|
||||
stv := castToMapStringInterface(ttv)
|
||||
mergeMaps(ssv, stv, ttv)
|
||||
case map[string]interface{}:
|
||||
v.logger.Trace("merging maps")
|
||||
mergeMaps(sv.(map[string]interface{}), ttv, nil)
|
||||
tsv, ok := sv.(map[string]interface{})
|
||||
if !ok {
|
||||
v.logger.Error(
|
||||
"Could not cast sv to map[string]interface{}",
|
||||
"key", sk,
|
||||
"st", svType,
|
||||
"tt", tvType,
|
||||
"sv", sv,
|
||||
"tv", tv,
|
||||
)
|
||||
continue
|
||||
}
|
||||
mergeMaps(tsv, ttv, nil)
|
||||
default:
|
||||
v.logger.Trace("setting value")
|
||||
tgt[tk] = sv
|
||||
@@ -1887,6 +1879,10 @@ func (v *Viper) getKeyValueConfig() error {
|
||||
return RemoteConfigError("Enable the remote features by doing a blank import of the viper/remote package: '_ github.com/spf13/viper/remote'")
|
||||
}
|
||||
|
||||
if len(v.remoteProviders) == 0 {
|
||||
return RemoteConfigError("No Remote Providers")
|
||||
}
|
||||
|
||||
for _, rp := range v.remoteProviders {
|
||||
val, err := v.getRemoteConfig(rp)
|
||||
if err != nil {
|
||||
@@ -1913,6 +1909,10 @@ func (v *Viper) getRemoteConfig(provider RemoteProvider) (map[string]interface{}
|
||||
|
||||
// Retrieve the first found remote configuration.
|
||||
func (v *Viper) watchKeyValueConfigOnChannel() error {
|
||||
if len(v.remoteProviders) == 0 {
|
||||
return RemoteConfigError("No Remote Providers")
|
||||
}
|
||||
|
||||
for _, rp := range v.remoteProviders {
|
||||
respc, _ := RemoteConfig.WatchChannel(rp)
|
||||
// Todo: Add quit channel
|
||||
@@ -1930,9 +1930,15 @@ func (v *Viper) watchKeyValueConfigOnChannel() error {
|
||||
|
||||
// Retrieve the first found remote configuration.
|
||||
func (v *Viper) watchKeyValueConfig() error {
|
||||
if len(v.remoteProviders) == 0 {
|
||||
return RemoteConfigError("No Remote Providers")
|
||||
}
|
||||
|
||||
for _, rp := range v.remoteProviders {
|
||||
val, err := v.watchRemoteConfig(rp)
|
||||
if err != nil {
|
||||
v.logger.Error(fmt.Errorf("watch remote config: %w", err).Error())
|
||||
|
||||
continue
|
||||
}
|
||||
v.kvstore = val
|
||||
@@ -1975,9 +1981,10 @@ func (v *Viper) AllKeys() []string {
|
||||
|
||||
// flattenAndMergeMap recursively flattens the given map into a map[string]bool
|
||||
// of key paths (used as a set, easier to manipulate than a []string):
|
||||
// - each path is merged into a single key string, delimited with v.keyDelim
|
||||
// - if a path is shadowed by an earlier value in the initial shadow map,
|
||||
// it is skipped.
|
||||
// - each path is merged into a single key string, delimited with v.keyDelim
|
||||
// - if a path is shadowed by an earlier value in the initial shadow map,
|
||||
// it is skipped.
|
||||
//
|
||||
// The resulting set of paths is merged to the given shadow set at the same time.
|
||||
func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interface{}, prefix string) map[string]bool {
|
||||
if shadow != nil && prefix != "" && shadow[prefix] {
|
||||
@@ -2128,14 +2135,17 @@ func (v *Viper) getConfigFile() (string, error) {
|
||||
|
||||
// Debug prints all configuration registries for debugging
|
||||
// purposes.
|
||||
func Debug() { v.Debug() }
|
||||
func Debug() { v.Debug() }
|
||||
func DebugTo(w io.Writer) { v.DebugTo(w) }
|
||||
|
||||
func (v *Viper) Debug() {
|
||||
fmt.Printf("Aliases:\n%#v\n", v.aliases)
|
||||
fmt.Printf("Override:\n%#v\n", v.override)
|
||||
fmt.Printf("PFlags:\n%#v\n", v.pflags)
|
||||
fmt.Printf("Env:\n%#v\n", v.env)
|
||||
fmt.Printf("Key/Value Store:\n%#v\n", v.kvstore)
|
||||
fmt.Printf("Config:\n%#v\n", v.config)
|
||||
fmt.Printf("Defaults:\n%#v\n", v.defaults)
|
||||
func (v *Viper) Debug() { v.DebugTo(os.Stdout) }
|
||||
|
||||
func (v *Viper) DebugTo(w io.Writer) {
|
||||
fmt.Fprintf(w, "Aliases:\n%#v\n", v.aliases)
|
||||
fmt.Fprintf(w, "Override:\n%#v\n", v.override)
|
||||
fmt.Fprintf(w, "PFlags:\n%#v\n", v.pflags)
|
||||
fmt.Fprintf(w, "Env:\n%#v\n", v.env)
|
||||
fmt.Fprintf(w, "Key/Value Store:\n%#v\n", v.kvstore)
|
||||
fmt.Fprintf(w, "Config:\n%#v\n", v.config)
|
||||
fmt.Fprintf(w, "Defaults:\n%#v\n", v.defaults)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user