[chore] update latest deps, ensure readme up to date (#1873)

* [chore] update latest deps, ensure readme up to date

* remove double entry
This commit is contained in:
tobi
2023-06-05 10:15:05 +02:00
committed by GitHub
parent f1b70cc00f
commit b401bd1ccb
156 changed files with 11730 additions and 2842 deletions

View File

@ -1,7 +1,7 @@
Package validator
=================
<img align="right" src="https://raw.githubusercontent.com/go-playground/validator/v10/logo.png">[![Join the chat at https://gitter.im/go-playground/validator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
![Project status](https://img.shields.io/badge/version-10.14.0-green.svg)
![Project status](https://img.shields.io/badge/version-10.14.1-green.svg)
[![Build Status](https://travis-ci.org/go-playground/validator.svg?branch=master)](https://travis-ci.org/go-playground/validator)
[![Coverage Status](https://coveralls.io/repos/go-playground/validator/badge.svg?branch=master&service=github)](https://coveralls.io/github/go-playground/validator?branch=master)
[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/validator)](https://goreportcard.com/report/github.com/go-playground/validator)

View File

@ -1414,25 +1414,21 @@ func isURL(fl FieldLevel) bool {
switch field.Kind() {
case reflect.String:
var i int
s := field.String()
// checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195
// emulate browser and strip the '#' suffix prior to validation. see issue-#237
if i = strings.Index(s, "#"); i > -1 {
s = s[:i]
}
if len(s) == 0 {
return false
}
url, err := url.ParseRequestURI(s)
url, err := url.Parse(s)
if err != nil || url.Scheme == "" {
return false
}
if url.Host == "" && url.Fragment == "" && url.Opaque == "" {
return false
}
return true
}
@ -1450,7 +1446,13 @@ func isHttpURL(fl FieldLevel) bool {
case reflect.String:
s := strings.ToLower(field.String())
return strings.HasPrefix(s, "http://") || strings.HasPrefix(s, "https://")
url, err := url.Parse(s)
if err != nil || url.Host == "" {
return false
}
return url.Scheme == "http" || url.Scheme == "https"
}
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
@ -2568,9 +2570,17 @@ func isDirPath(fl FieldLevel) bool {
func isJSON(fl FieldLevel) bool {
field := fl.Field()
if field.Kind() == reflect.String {
switch field.Kind() {
case reflect.String:
val := field.String()
return json.Valid([]byte(val))
case reflect.Slice:
fieldType := field.Type()
if fieldType.ConvertibleTo(byteSliceType) {
b := field.Convert(byteSliceType).Interface().([]byte)
return json.Valid(b)
}
}
panic(fmt.Sprintf("Bad field type %T", field.Interface()))

View File

@ -53,6 +53,8 @@ var (
timeDurationType = reflect.TypeOf(time.Duration(0))
timeType = reflect.TypeOf(time.Time{})
byteSliceType = reflect.TypeOf([]byte{})
defaultCField = &cField{namesEqual: true}
)

View File

@ -386,8 +386,14 @@ func (u *Unmarshaler) unmarshalMessage(m protoreflect.Message, in []byte) error
}
func isSingularWellKnownValue(fd protoreflect.FieldDescriptor) bool {
if fd.Cardinality() == protoreflect.Repeated {
return false
}
if md := fd.Message(); md != nil {
return md.FullName() == "google.protobuf.Value" && fd.Cardinality() != protoreflect.Repeated
return md.FullName() == "google.protobuf.Value"
}
if ed := fd.Enum(); ed != nil {
return ed.FullName() == "google.protobuf.NullValue"
}
return false
}

View File

@ -97,7 +97,7 @@ type Fs interface {
// Chown changes the uid and gid of the named file.
Chown(name string, uid, gid int) error
//Chtimes changes the access and modification times of the named file
// Chtimes changes the access and modification times of the named file
Chtimes(name string, atime time.Time, mtime time.Time) error
}

View File

@ -40,7 +40,6 @@ func (f *BasePathFile) Name() string {
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)
}

View File

@ -223,7 +223,7 @@ func (u *CopyOnWriteFs) OpenFile(name string, flag int, perm os.FileMode) (File,
return nil, err
}
if isaDir {
if err = u.layer.MkdirAll(dir, 0777); err != nil {
if err = u.layer.MkdirAll(dir, 0o777); err != nil {
return nil, err
}
return u.layer.OpenFile(name, flag, perm)
@ -247,8 +247,9 @@ func (u *CopyOnWriteFs) OpenFile(name string, flag int, perm os.FileMode) (File,
// This function handles the 9 different possibilities caused
// by the union which are the intersection of the following...
// layer: doesn't exist, exists as a file, and exists as a directory
// base: doesn't exist, exists as a file, and exists as a directory
//
// layer: doesn't exist, exists as a file, and exists as a directory
// base: doesn't exist, exists as a file, and exists as a directory
func (u *CopyOnWriteFs) Open(name string) (File, error) {
// Since the overlay overrides the base we check that first
b, err := u.isBaseFile(name)
@ -322,5 +323,5 @@ func (u *CopyOnWriteFs) MkdirAll(name string, perm os.FileMode) error {
}
func (u *CopyOnWriteFs) Create(name string) (File, error) {
return u.OpenFile(name, os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0666)
return u.OpenFile(name, os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0o666)
}

View File

@ -141,8 +141,10 @@ 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 randNum uint32
var randmu sync.Mutex
var (
randNum uint32
randmu sync.Mutex
)
func reseed() uint32 {
return uint32(time.Now().UnixNano() + int64(os.Getpid()))
@ -190,7 +192,7 @@ func TempFile(fs Fs, dir, pattern string) (f File, err error) {
nconflict := 0
for i := 0; i < 10000; i++ {
name := filepath.Join(dir, prefix+nextRandom()+suffix)
f, err = fs.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
f, err = fs.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0o600)
if os.IsExist(err) {
if nconflict++; nconflict > 10 {
randmu.Lock()
@ -214,6 +216,7 @@ func TempFile(fs Fs, dir, pattern string) (f File, err error) {
func (a Afero) TempDir(dir, prefix string) (name string, err error) {
return TempDir(a.Fs, dir, prefix)
}
func TempDir(fs Fs, dir, prefix string) (name string, err error) {
if dir == "" {
dir = os.TempDir()
@ -222,7 +225,7 @@ func TempDir(fs Fs, dir, prefix string) (name string, err error) {
nconflict := 0
for i := 0; i < 10000; i++ {
try := filepath.Join(dir, prefix+nextRandom())
err = fs.Mkdir(try, 0700)
err = fs.Mkdir(try, 0o700)
if os.IsExist(err) {
if nconflict++; nconflict > 10 {
randmu.Lock()

View File

@ -245,7 +245,7 @@ func (f *File) Truncate(size int64) error {
defer f.fileData.Unlock()
if size > int64(len(f.fileData.data)) {
diff := size - int64(len(f.fileData.data))
f.fileData.data = append(f.fileData.data, bytes.Repeat([]byte{00}, int(diff))...)
f.fileData.data = append(f.fileData.data, bytes.Repeat([]byte{0o0}, int(diff))...)
} else {
f.fileData.data = f.fileData.data[0:size]
}
@ -285,7 +285,7 @@ func (f *File) Write(b []byte) (n int, err error) {
tail = f.fileData.data[n+int(cur):]
}
if diff > 0 {
f.fileData.data = append(f.fileData.data, append(bytes.Repeat([]byte{00}, int(diff)), b...)...)
f.fileData.data = append(f.fileData.data, append(bytes.Repeat([]byte{0o0}, int(diff)), b...)...)
f.fileData.data = append(f.fileData.data, tail...)
} else {
f.fileData.data = append(f.fileData.data[:cur], b...)
@ -321,16 +321,19 @@ func (s *FileInfo) Name() string {
s.Unlock()
return name
}
func (s *FileInfo) Mode() os.FileMode {
s.Lock()
defer s.Unlock()
return s.mode
}
func (s *FileInfo) ModTime() time.Time {
s.Lock()
defer s.Unlock()
return s.modtime
}
func (s *FileInfo) IsDir() bool {
s.Lock()
defer s.Unlock()

View File

@ -15,6 +15,7 @@ package afero
import (
"fmt"
"io"
"log"
"os"
"path/filepath"
@ -43,7 +44,7 @@ func (m *MemMapFs) getData() map[string]*mem.FileData {
// Root should always exist, right?
// TODO: what about windows?
root := mem.CreateDir(FilePathSeparator)
mem.SetMode(root, os.ModeDir|0755)
mem.SetMode(root, os.ModeDir|0o755)
m.data[FilePathSeparator] = root
})
return m.data
@ -96,12 +97,12 @@ func (m *MemMapFs) registerWithParent(f *mem.FileData, perm os.FileMode) {
pdir := filepath.Dir(filepath.Clean(f.Name()))
err := m.lockfreeMkdir(pdir, perm)
if err != nil {
//log.Println("Mkdir error:", err)
// log.Println("Mkdir error:", err)
return
}
parent, err = m.lockfreeOpen(pdir)
if err != nil {
//log.Println("Open after Mkdir error:", err)
// log.Println("Open after Mkdir error:", err)
return
}
}
@ -237,7 +238,7 @@ func (m *MemMapFs) OpenFile(name string, flag int, perm os.FileMode) (File, erro
file = mem.NewReadOnlyFileHandle(file.(*mem.File).Data())
}
if flag&os.O_APPEND > 0 {
_, err = file.Seek(0, os.SEEK_END)
_, err = file.Seek(0, io.SeekEnd)
if err != nil {
file.Close()
return nil, err
@ -319,6 +320,18 @@ func (m *MemMapFs) Rename(oldname, newname string) error {
} else {
return &os.PathError{Op: "rename", Path: oldname, Err: ErrFileNotFound}
}
for p, fileData := range m.getData() {
if strings.HasPrefix(p, oldname+FilePathSeparator) {
m.mu.RUnlock()
m.mu.Lock()
delete(m.getData(), p)
p := strings.Replace(p, oldname, newname, 1)
m.getData()[p] = fileData
m.mu.Unlock()
m.mu.RLock()
}
}
return nil
}

View File

@ -10,7 +10,6 @@ import (
// The RegexpFs filters files (not directories) by regular expression. Only
// files matching the given regexp will be allowed, all others get a ENOENT error (
// "No such file or directory").
//
type RegexpFs struct {
re *regexp.Regexp
source Fs

View File

@ -21,9 +21,9 @@ import (
// filesystems saying so.
// It indicates support for 3 symlink related interfaces that implement the
// behaviors of the os methods:
// - Lstat
// - Symlink, and
// - Readlink
// - Lstat
// - Symlink, and
// - Readlink
type Symlinker interface {
Lstater
Linker

View File

@ -47,7 +47,7 @@ func (f *UnionFile) Read(s []byte) (int, error) {
if (err == nil || err == io.EOF) && f.Base != nil {
// advance the file position also in the base file, the next
// call may be a write at this position (or a seek with SEEK_CUR)
if _, seekErr := f.Base.Seek(int64(n), os.SEEK_CUR); seekErr != nil {
if _, seekErr := f.Base.Seek(int64(n), io.SeekCurrent); seekErr != nil {
// only overwrite err in case the seek fails: we need to
// report an eventual io.EOF to the caller
err = seekErr
@ -130,7 +130,7 @@ func (f *UnionFile) Name() string {
type DirsMerger func(lofi, bofi []os.FileInfo) ([]os.FileInfo, error)
var defaultUnionMergeDirsFn = func(lofi, bofi []os.FileInfo) ([]os.FileInfo, error) {
var files = make(map[string]os.FileInfo)
files := make(map[string]os.FileInfo)
for _, fi := range lofi {
files[fi.Name()] = fi
@ -151,7 +151,6 @@ var defaultUnionMergeDirsFn = func(lofi, bofi []os.FileInfo) ([]os.FileInfo, err
}
return rfi, nil
}
// Readdir will weave the two directories together and
@ -275,7 +274,7 @@ func copyFile(base Fs, layer Fs, name string, bfh File) error {
return err
}
if !exists {
err = layer.MkdirAll(filepath.Dir(name), 0777) // FIXME?
err = layer.MkdirAll(filepath.Dir(name), 0o777) // FIXME?
if err != nil {
return err
}

View File

@ -43,7 +43,7 @@ func WriteReader(fs Fs, path string, r io.Reader) (err error) {
ospath := filepath.FromSlash(dir)
if ospath != "" {
err = fs.MkdirAll(ospath, 0777) // rwx, rw, r
err = fs.MkdirAll(ospath, 0o777) // rwx, rw, r
if err != nil {
if err != os.ErrExist {
return err
@ -71,7 +71,7 @@ func SafeWriteReader(fs Fs, path string, r io.Reader) (err error) {
ospath := filepath.FromSlash(dir)
if ospath != "" {
err = fs.MkdirAll(ospath, 0777) // rwx, rw, r
err = fs.MkdirAll(ospath, 0o777) // rwx, rw, r
if err != nil {
return
}
@ -124,7 +124,7 @@ func GetTempDir(fs Fs, subPath string) string {
return addSlash(dir)
}
err := fs.MkdirAll(dir, 0777)
err := fs.MkdirAll(dir, 0o777)
if err != nil {
panic(err)
}
@ -197,7 +197,6 @@ func FileContainsAnyBytes(fs Fs, filename string, subslices [][]byte) (bool, err
// readerContains reports whether any of the subslices is within r.
func readerContainsAny(r io.Reader, subslices ...[]byte) bool {
if r == nil || len(subslices) == 0 {
return false
}

View File

@ -1,7 +1,8 @@
cast
====
[![GoDoc](https://godoc.org/github.com/spf13/cast?status.svg)](https://godoc.org/github.com/spf13/cast)
[![Build Status](https://github.com/spf13/cast/actions/workflows/go.yml/badge.svg)](https://github.com/spf13/cast/actions/workflows/go.yml)
# cast
[![Build Status](https://github.com/spf13/cast/actions/workflows/ci.yml/badge.svg)](https://github.com/spf13/cast/actions/workflows/ci.yml)
[![PkgGoDev](https://pkg.go.dev/badge/mod/github.com/spf13/cast)](https://pkg.go.dev/mod/github.com/spf13/cast)
![Go Version](https://img.shields.io/badge/go%20version-%3E=1.16-61CFDD.svg?style=flat-square)
[![Go Report Card](https://goreportcard.com/badge/github.com/spf13/cast)](https://goreportcard.com/report/github.com/spf13/cast)
Easy and safe casting from one type to another in Go
@ -17,7 +18,7 @@ interface into a bool, etc. Cast does this intelligently when an obvious
conversion is possible. It doesnt make any attempts to guess what you meant,
for example you can only convert a string to an int when it is a string
representation of an int such as “8”. Cast was developed for use in
[Hugo](http://hugo.spf13.com), a website engine which uses YAML, TOML or JSON
[Hugo](https://gohugo.io), a website engine which uses YAML, TOML or JSON
for meta data.
## Why use Cast?
@ -72,4 +73,3 @@ the code for a complete set.
var eight interface{} = 8
cast.ToInt(eight) // 8
cast.ToInt(nil) // 0

View File

@ -98,10 +98,31 @@ func ToBoolE(i interface{}) (bool, error) {
case nil:
return false, nil
case int:
if i.(int) != 0 {
return true, nil
}
return false, nil
return b != 0, nil
case int64:
return b != 0, nil
case int32:
return b != 0, nil
case int16:
return b != 0, nil
case int8:
return b != 0, nil
case uint:
return b != 0, nil
case uint64:
return b != 0, nil
case uint32:
return b != 0, nil
case uint16:
return b != 0, nil
case uint8:
return b != 0, nil
case float64:
return b != 0, nil
case float32:
return b != 0, nil
case time.Duration:
return b != 0, nil
case string:
return strconv.ParseBool(i.(string))
case json.Number:
@ -1385,6 +1406,8 @@ func (f timeFormat) hasTimezone() bool {
var (
timeFormats = []timeFormat{
// Keep common formats at the top.
{"2006-01-02", timeFormatNoTimezone},
{time.RFC3339, timeFormatNumericTimezone},
{"2006-01-02T15:04:05", timeFormatNoTimezone}, // iso8601 without timezone
{time.RFC1123Z, timeFormatNumericTimezone},
@ -1400,7 +1423,6 @@ var (
{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},

View File

@ -16,7 +16,6 @@ linters:
disable-all: true
enable:
- bodyclose
- deadcode
- dogsled
- dupl
- durationcheck
@ -43,14 +42,12 @@ linters:
- rowserrcheck
- sqlclosecheck
- staticcheck
- structcheck
- stylecheck
- tparallel
- typecheck
- unconvert
- unparam
- unused
- varcheck
- wastedassign
- whitespace
@ -83,6 +80,11 @@ linters:
# - goheader
# - gomodguard
# deprecated
# - deadcode
# - structcheck
# - varcheck
# don't enable:
# - asciicheck
# - funlen

View File

@ -15,8 +15,8 @@ TEST_FORMAT = short-verbose
endif
# Dependency versions
GOTESTSUM_VERSION = 1.8.0
GOLANGCI_VERSION = 1.50.1
GOTESTSUM_VERSION = 1.9.0
GOLANGCI_VERSION = 1.52.2
# Add the ability to override some variables
# Use with care

View File

@ -27,6 +27,9 @@ Many Go projects are built using Viper including:
* [doctl](https://github.com/digitalocean/doctl)
* [Clairctl](https://github.com/jgsqware/clairctl)
* [Mercure](https://mercure.rocks)
* [Meshery](https://github.com/meshery/meshery)
* [Bearer](https://github.com/bearer/bearer)
* [Coder](https://github.com/coder/coder)
## Install

View File

@ -31,6 +31,11 @@ func (pe ConfigParseError) Error() string {
return fmt.Sprintf("While parsing config: %s", pe.err.Error())
}
// Unwrap returns the wrapped error.
func (pe ConfigParseError) Unwrap() error {
return pe.err
}
// toCaseInsensitiveValue checks if the value is a map;
// if so, create a copy and lower-case the keys recursively.
func toCaseInsensitiveValue(value interface{}) interface{} {

View File

@ -25,7 +25,6 @@ import (
"errors"
"fmt"
"io"
"log"
"os"
"path/filepath"
"reflect"
@ -206,6 +205,7 @@ type Viper struct {
envKeyReplacer StringReplacer
allowEmptyEnv bool
parents []string
config map[string]interface{}
override map[string]interface{}
defaults map[string]interface{}
@ -232,6 +232,7 @@ func New() *Viper {
v.configPermissions = os.FileMode(0o644)
v.fs = afero.NewOsFs()
v.config = make(map[string]interface{})
v.parents = []string{}
v.override = make(map[string]interface{})
v.defaults = make(map[string]interface{})
v.kvstore = make(map[string]interface{})
@ -439,13 +440,14 @@ func (v *Viper) WatchConfig() {
go func() {
watcher, err := newWatcher()
if err != nil {
log.Fatal(err)
v.logger.Error(fmt.Sprintf("failed to create watcher: %s", err))
os.Exit(1)
}
defer watcher.Close()
// we have to watch the entire directory to pick up renames/atomic saves in a cross-platform way
filename, err := v.getConfigFile()
if err != nil {
log.Printf("error: %v\n", err)
v.logger.Error(fmt.Sprintf("get config file: %s", err))
initWG.Done()
return
}
@ -474,7 +476,7 @@ func (v *Viper) WatchConfig() {
realConfigFile = currentConfigFile
err := v.ReadInConfig()
if err != nil {
log.Printf("error reading config file: %v\n", err)
v.logger.Error(fmt.Sprintf("read config file: %s", err))
}
if v.onConfigChange != nil {
v.onConfigChange(event)
@ -486,7 +488,7 @@ func (v *Viper) WatchConfig() {
case err, ok := <-watcher.Errors:
if ok { // 'Errors' channel is not closed
log.Printf("watcher error: %v\n", err)
v.logger.Error(fmt.Sprintf("watcher error: %s", err))
}
eventsWG.Done()
return
@ -928,6 +930,8 @@ func (v *Viper) Get(key string) interface{} {
return cast.ToStringSlice(val)
case []int:
return cast.ToIntSlice(val)
case []time.Duration:
return cast.ToDurationSlice(val)
}
}
@ -946,6 +950,10 @@ func (v *Viper) Sub(key string) *Viper {
}
if reflect.TypeOf(data).Kind() == reflect.Map {
subv.parents = append(v.parents, strings.ToLower(key))
subv.automaticEnvApplied = v.automaticEnvApplied
subv.envPrefix = v.envPrefix
subv.envKeyReplacer = v.envKeyReplacer
subv.config = cast.ToStringMap(data)
return subv
}
@ -1099,7 +1107,7 @@ func (v *Viper) Unmarshal(rawVal interface{}, opts ...DecoderConfigOption) error
return decode(v.AllSettings(), defaultDecoderConfig(rawVal, opts...))
}
// defaultDecoderConfig returns default mapsstructure.DecoderConfig with suppot
// defaultDecoderConfig returns default mapstructure.DecoderConfig with support
// of time.Duration values & string slices
func defaultDecoderConfig(output interface{}, opts ...DecoderConfigOption) *mapstructure.DecoderConfig {
c := &mapstructure.DecoderConfig{
@ -1274,8 +1282,15 @@ func (v *Viper) find(lcaseKey string, flagDefault bool) interface{} {
s = strings.TrimSuffix(s, "]")
res, _ := readAsCSV(s)
return cast.ToIntSlice(res)
case "durationSlice":
s := strings.TrimPrefix(flag.ValueString(), "[")
s = strings.TrimSuffix(s, "]")
slice := strings.Split(s, ",")
return cast.ToDurationSlice(slice)
case "stringToString":
return stringToStringConv(flag.ValueString())
case "stringToInt":
return stringToIntConv(flag.ValueString())
default:
return flag.ValueString()
}
@ -1286,9 +1301,10 @@ func (v *Viper) find(lcaseKey string, flagDefault bool) interface{} {
// Env override next
if v.automaticEnvApplied {
envKey := strings.Join(append(v.parents, lcaseKey), ".")
// even if it hasn't been registered, if automaticEnv is used,
// check any Get request
if val, ok := v.getEnv(v.mergeWithEnvPrefix(lcaseKey)); ok {
if val, ok := v.getEnv(v.mergeWithEnvPrefix(envKey)); ok {
return val
}
if nested && v.isPathShadowedInAutoEnv(path) != "" {
@ -1355,6 +1371,13 @@ func (v *Viper) find(lcaseKey string, flagDefault bool) interface{} {
return cast.ToIntSlice(res)
case "stringToString":
return stringToStringConv(flag.ValueString())
case "stringToInt":
return stringToIntConv(flag.ValueString())
case "durationSlice":
s := strings.TrimPrefix(flag.ValueString(), "[")
s = strings.TrimSuffix(s, "]")
slice := strings.Split(s, ",")
return cast.ToDurationSlice(slice)
default:
return flag.ValueString()
}
@ -1398,6 +1421,30 @@ func stringToStringConv(val string) interface{} {
return out
}
// mostly copied from pflag's implementation of this operation here https://github.com/spf13/pflag/blob/d5e0c0615acee7028e1e2740a11102313be88de1/string_to_int.go#L68
// alterations are: errors are swallowed, map[string]interface{} is returned in order to enable cast.ToStringMap
func stringToIntConv(val string) interface{} {
val = strings.Trim(val, "[]")
// An empty string would cause an empty map
if len(val) == 0 {
return map[string]interface{}{}
}
ss := strings.Split(val, ",")
out := make(map[string]interface{}, len(ss))
for _, pair := range ss {
kv := strings.SplitN(pair, "=", 2)
if len(kv) != 2 {
return nil
}
var err error
out[kv[0]], err = strconv.Atoi(kv[1])
if err != nil {
return nil
}
}
return out
}
// IsSet checks to see if the key has been set in any of the data locations.
// IsSet is case-insensitive for a key.
func IsSet(key string) bool { return v.IsSet(key) }

View File

@ -280,6 +280,7 @@ Options:
- `KeepVarNames` keeps variable names as they are and omits shortening variable names
- `Precision` number of significant digits to preserve for numbers, `0` means no trimming
- `Version` ECMAScript version to use for output, `0` is the latest
### Comparison with other tools

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,12 @@
## [1.1.14](https://github.com/uptrace/bun/compare/v1.1.13...v1.1.14) (2023-05-24)
### Bug Fixes
* enable CompositeIn for MySQL ([9f377b5](https://github.com/uptrace/bun/commit/9f377b5e744cb38ef4aadd61213855c009e47354))
## [1.1.13](https://github.com/uptrace/bun/compare/v1.1.12...v1.1.13) (2023-05-06)

View File

@ -11,12 +11,11 @@ test:
done
go_mod_tidy:
go get -u && go mod tidy -go=1.18
set -e; for dir in $(ALL_GO_MOD_DIRS); do \
echo "go mod tidy in $${dir}"; \
(cd "$${dir}" && \
go get -u ./... && \
go mod tidy -go=1.18); \
go mod tidy -go=1.19); \
done
fmt:

View File

@ -2,5 +2,5 @@ package pgdialect
// Version is the current release version.
func Version() string {
return "1.1.13"
return "1.1.14"
}

View File

@ -2,5 +2,5 @@ package sqlitedialect
// Version is the current release version.
func Version() string {
return "1.1.13"
return "1.1.14"
}

View File

@ -10,9 +10,8 @@ import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/metric/global"
"go.opentelemetry.io/otel/metric/instrument"
semconv "go.opentelemetry.io/otel/semconv/v1.12.0"
"go.opentelemetry.io/otel/metric"
semconv "go.opentelemetry.io/otel/semconv/v1.20.0"
"go.opentelemetry.io/otel/trace"
"github.com/uptrace/bun"
@ -23,12 +22,12 @@ import (
var (
tracer = otel.Tracer("github.com/uptrace/bun")
meter = global.Meter("github.com/uptrace/bun")
meter = otel.Meter("github.com/uptrace/bun")
queryHistogram, _ = meter.Int64Histogram(
"go.sql.query_timing",
instrument.WithDescription("Timing of processed queries"),
instrument.WithUnit("milliseconds"),
metric.WithDescription("Timing of processed queries"),
metric.WithUnit("milliseconds"),
)
)
@ -75,7 +74,8 @@ func (h *QueryHook) AfterQuery(ctx context.Context, event *bun.QueryEvent) {
}
}
queryHistogram.Record(ctx, time.Since(event.StartTime).Milliseconds(), labels...)
dur := time.Since(event.StartTime)
queryHistogram.Record(ctx, dur.Milliseconds(), metric.WithAttributes(labels...))
span := trace.SpanFromContext(ctx)
if !span.IsRecording() {

View File

@ -4,7 +4,7 @@ import (
"context"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"regexp"
"time"
@ -255,7 +255,7 @@ func (m *Migrator) CreateGoMigration(
fpath := filepath.Join(m.migrations.getDirectory(), fname)
content := fmt.Sprintf(cfg.goTemplate, cfg.packageName)
if err := ioutil.WriteFile(fpath, []byte(content), 0o644); err != nil {
if err := os.WriteFile(fpath, []byte(content), 0o644); err != nil {
return nil, err
}
@ -290,7 +290,7 @@ func (m *Migrator) CreateSQLMigrations(ctx context.Context, name string) ([]*Mig
func (m *Migrator) createSQL(ctx context.Context, fname string) (*MigrationFile, error) {
fpath := filepath.Join(m.migrations.getDirectory(), fname)
if err := ioutil.WriteFile(fpath, []byte(sqlTemplate), 0o644); err != nil {
if err := os.WriteFile(fpath, []byte(sqlTemplate), 0o644); err != nil {
return nil, err
}

View File

@ -1,6 +1,6 @@
{
"name": "gobun",
"version": "1.1.13",
"version": "1.1.14",
"main": "index.js",
"repository": "git@github.com:uptrace/bun.git",
"author": "Vladimir Mihailenco <vladimir.webdev@gmail.com>",

View File

@ -2,5 +2,5 @@ package bun
// Version is the current release version.
func Version() string {
return "1.1.13"
return "1.1.14"
}

View File

@ -11,8 +11,6 @@ import (
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/metric/global"
"go.opentelemetry.io/otel/metric/instrument"
semconv "go.opentelemetry.io/otel/semconv/v1.10.0"
"go.opentelemetry.io/otel/trace"
)
@ -36,7 +34,7 @@ type config struct {
func newConfig(opts []Option) *config {
c := &config{
tracerProvider: otel.GetTracerProvider(),
meterProvider: global.MeterProvider(),
meterProvider: otel.GetMeterProvider(),
}
for _, opt := range opts {
opt(c)
@ -54,7 +52,7 @@ func (c *config) formatQuery(query string) string {
type dbInstrum struct {
*config
queryHistogram instrument.Int64Histogram
queryHistogram metric.Int64Histogram
}
func newDBInstrum(opts []Option) *dbInstrum {
@ -72,8 +70,8 @@ func newDBInstrum(opts []Option) *dbInstrum {
var err error
t.queryHistogram, err = t.meter.Int64Histogram(
"go.sql.query_timing",
instrument.WithDescription("Timing of processed queries"),
instrument.WithUnit("milliseconds"),
metric.WithDescription("Timing of processed queries"),
metric.WithUnit("milliseconds"),
)
if err != nil {
panic(err)
@ -106,7 +104,7 @@ func (t *dbInstrum) withSpan(
span.End()
if query != "" {
t.queryHistogram.Record(ctx, time.Since(startTime).Milliseconds(), t.attrs...)
t.queryHistogram.Record(ctx, time.Since(startTime).Milliseconds(), metric.WithAttributes(t.attrs...))
}
if !span.IsRecording() {
@ -185,57 +183,57 @@ func ReportDBStatsMetrics(db *sql.DB, opts ...Option) {
maxOpenConns, _ := meter.Int64ObservableGauge(
"go.sql.connections_max_open",
instrument.WithDescription("Maximum number of open connections to the database"),
metric.WithDescription("Maximum number of open connections to the database"),
)
openConns, _ := meter.Int64ObservableGauge(
"go.sql.connections_open",
instrument.WithDescription("The number of established connections both in use and idle"),
metric.WithDescription("The number of established connections both in use and idle"),
)
inUseConns, _ := meter.Int64ObservableGauge(
"go.sql.connections_in_use",
instrument.WithDescription("The number of connections currently in use"),
metric.WithDescription("The number of connections currently in use"),
)
idleConns, _ := meter.Int64ObservableGauge(
"go.sql.connections_idle",
instrument.WithDescription("The number of idle connections"),
metric.WithDescription("The number of idle connections"),
)
connsWaitCount, _ := meter.Int64ObservableCounter(
"go.sql.connections_wait_count",
instrument.WithDescription("The total number of connections waited for"),
metric.WithDescription("The total number of connections waited for"),
)
connsWaitDuration, _ := meter.Int64ObservableCounter(
"go.sql.connections_wait_duration",
instrument.WithDescription("The total time blocked waiting for a new connection"),
instrument.WithUnit("nanoseconds"),
metric.WithDescription("The total time blocked waiting for a new connection"),
metric.WithUnit("nanoseconds"),
)
connsClosedMaxIdle, _ := meter.Int64ObservableCounter(
"go.sql.connections_closed_max_idle",
instrument.WithDescription("The total number of connections closed due to SetMaxIdleConns"),
metric.WithDescription("The total number of connections closed due to SetMaxIdleConns"),
)
connsClosedMaxIdleTime, _ := meter.Int64ObservableCounter(
"go.sql.connections_closed_max_idle_time",
instrument.WithDescription("The total number of connections closed due to SetConnMaxIdleTime"),
metric.WithDescription("The total number of connections closed due to SetConnMaxIdleTime"),
)
connsClosedMaxLifetime, _ := meter.Int64ObservableCounter(
"go.sql.connections_closed_max_lifetime",
instrument.WithDescription("The total number of connections closed due to SetConnMaxLifetime"),
metric.WithDescription("The total number of connections closed due to SetConnMaxLifetime"),
)
if _, err := meter.RegisterCallback(
func(ctx context.Context, o metric.Observer) error {
stats := db.Stats()
o.ObserveInt64(maxOpenConns, int64(stats.MaxOpenConnections), labels...)
o.ObserveInt64(maxOpenConns, int64(stats.MaxOpenConnections), metric.WithAttributes(labels...))
o.ObserveInt64(openConns, int64(stats.OpenConnections), labels...)
o.ObserveInt64(inUseConns, int64(stats.InUse), labels...)
o.ObserveInt64(idleConns, int64(stats.Idle), labels...)
o.ObserveInt64(openConns, int64(stats.OpenConnections), metric.WithAttributes(labels...))
o.ObserveInt64(inUseConns, int64(stats.InUse), metric.WithAttributes(labels...))
o.ObserveInt64(idleConns, int64(stats.Idle), metric.WithAttributes(labels...))
o.ObserveInt64(connsWaitCount, stats.WaitCount, labels...)
o.ObserveInt64(connsWaitDuration, int64(stats.WaitDuration), labels...)
o.ObserveInt64(connsClosedMaxIdle, stats.MaxIdleClosed, labels...)
o.ObserveInt64(connsClosedMaxIdleTime, stats.MaxIdleTimeClosed, labels...)
o.ObserveInt64(connsClosedMaxLifetime, stats.MaxLifetimeClosed, labels...)
o.ObserveInt64(connsWaitCount, stats.WaitCount, metric.WithAttributes(labels...))
o.ObserveInt64(connsWaitDuration, int64(stats.WaitDuration), metric.WithAttributes(labels...))
o.ObserveInt64(connsClosedMaxIdle, stats.MaxIdleClosed, metric.WithAttributes(labels...))
o.ObserveInt64(connsClosedMaxIdleTime, stats.MaxIdleTimeClosed, metric.WithAttributes(labels...))
o.ObserveInt64(connsClosedMaxLifetime, stats.MaxLifetimeClosed, metric.WithAttributes(labels...))
return nil
},

View File

@ -2,5 +2,5 @@ package otelsql
// Version is the current release version.
func Version() string {
return "0.1.21"
return "0.2.1"
}