micro--go-micro
3e885308a0
Fixes #2988. Brings 'golangci-lint run ./...' to zero issues (was ~373): - errcheck: explicitly ignore fire-and-forget calls with '_ =' (and a small errcheck.exclude-functions list for response writes — json Encoder.Encode, http ResponseWriter.Write, fmt.Fprint*); genuine cases handled. - unused: remove dead code (unexported decls and dead test helpers) and the imports they orphaned. - staticcheck: ST1005 error strings, ST1016 receiver names, S1000/S1017/S1019/ S1023 simplifications, SA4004/SA4006/SA4010 dead code, SA1021 net.IP.Equal, SA6002 (store *[]byte in sync.Pool). - govet: fix a context leak (lostcancel) in internal/util/mdns and move t.Fatal/Fatalf out of goroutines (testinggoroutine) in tests. - ineffassign, unconvert: mechanical fixes. CI: the Lint workflow now runs a blocking full-tree 'golangci-lint run' on pushes and PRs (dropped only-new-issues now that the tree is clean). Verified: go build, go vet, test compilation, and unit tests for the behaviourally-touched packages all pass. Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL Co-authored-by: Claude <noreply@anthropic.com>
210 行
3.4 KiB
Go
210 行
3.4 KiB
Go
package json
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
simple "github.com/bitly/go-simplejson"
|
|
"go-micro.dev/v6/config/reader"
|
|
"go-micro.dev/v6/config/source"
|
|
)
|
|
|
|
type jsonValues struct {
|
|
ch *source.ChangeSet
|
|
sj *simple.Json
|
|
}
|
|
|
|
type jsonValue struct {
|
|
*simple.Json
|
|
}
|
|
|
|
func NewValues(val []byte) (reader.Values, error) {
|
|
sj := simple.New()
|
|
data, _ := reader.ReplaceEnvVars(val)
|
|
if err := sj.UnmarshalJSON(data); err != nil {
|
|
sj.SetPath(nil, string(data))
|
|
}
|
|
return &jsonValues{sj: sj}, nil
|
|
}
|
|
|
|
func newValues(ch *source.ChangeSet) (reader.Values, error) {
|
|
sj := simple.New()
|
|
data, _ := reader.ReplaceEnvVars(ch.Data)
|
|
if err := sj.UnmarshalJSON(data); err != nil {
|
|
sj.SetPath(nil, string(ch.Data))
|
|
}
|
|
return &jsonValues{ch, sj}, nil
|
|
}
|
|
|
|
func (j *jsonValues) Get(path ...string) (reader.Value, error) {
|
|
return &jsonValue{j.sj.GetPath(path...)}, nil
|
|
}
|
|
|
|
func (j *jsonValues) Del(path ...string) {
|
|
// delete the tree?
|
|
if len(path) == 0 {
|
|
j.sj = simple.New()
|
|
return
|
|
}
|
|
|
|
if len(path) == 1 {
|
|
j.sj.Del(path[0])
|
|
return
|
|
}
|
|
|
|
vals := j.sj.GetPath(path[:len(path)-1]...)
|
|
vals.Del(path[len(path)-1])
|
|
j.sj.SetPath(path[:len(path)-1], vals.Interface())
|
|
}
|
|
|
|
func (j *jsonValues) Set(val interface{}, path ...string) {
|
|
j.sj.SetPath(path, val)
|
|
}
|
|
|
|
func (j *jsonValues) Bytes() []byte {
|
|
b, _ := j.sj.MarshalJSON()
|
|
return b
|
|
}
|
|
|
|
func (j *jsonValues) Map() map[string]interface{} {
|
|
m, _ := j.sj.Map()
|
|
return m
|
|
}
|
|
|
|
func (j *jsonValues) Scan(v interface{}) error {
|
|
b, err := j.sj.MarshalJSON()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return json.Unmarshal(b, v)
|
|
}
|
|
|
|
func (j *jsonValues) String() string {
|
|
return "json"
|
|
}
|
|
|
|
func (j *jsonValue) Bool(def bool) bool {
|
|
b, err := j.Json.Bool()
|
|
if err == nil {
|
|
return b
|
|
}
|
|
|
|
str, ok := j.Interface().(string)
|
|
if !ok {
|
|
return def
|
|
}
|
|
|
|
b, err = strconv.ParseBool(str)
|
|
if err != nil {
|
|
return def
|
|
}
|
|
|
|
return b
|
|
}
|
|
|
|
func (j *jsonValue) Int(def int) int {
|
|
i, err := j.Json.Int()
|
|
if err == nil {
|
|
return i
|
|
}
|
|
|
|
str, ok := j.Interface().(string)
|
|
if !ok {
|
|
return def
|
|
}
|
|
|
|
i, err = strconv.Atoi(str)
|
|
if err != nil {
|
|
return def
|
|
}
|
|
|
|
return i
|
|
}
|
|
|
|
func (j *jsonValue) String(def string) string {
|
|
return j.MustString(def)
|
|
}
|
|
|
|
func (j *jsonValue) Float64(def float64) float64 {
|
|
f, err := j.Json.Float64()
|
|
if err == nil {
|
|
return f
|
|
}
|
|
|
|
str, ok := j.Interface().(string)
|
|
if !ok {
|
|
return def
|
|
}
|
|
|
|
f, err = strconv.ParseFloat(str, 64)
|
|
if err != nil {
|
|
return def
|
|
}
|
|
|
|
return f
|
|
}
|
|
|
|
func (j *jsonValue) Duration(def time.Duration) time.Duration {
|
|
v, err := j.Json.String()
|
|
if err != nil {
|
|
return def
|
|
}
|
|
|
|
value, err := time.ParseDuration(v)
|
|
if err != nil {
|
|
return def
|
|
}
|
|
|
|
return value
|
|
}
|
|
|
|
func (j *jsonValue) StringSlice(def []string) []string {
|
|
v, err := j.Json.String()
|
|
if err == nil {
|
|
sl := strings.Split(v, ",")
|
|
if len(sl) > 0 {
|
|
return sl
|
|
}
|
|
}
|
|
return j.MustStringArray(def)
|
|
}
|
|
|
|
func (j *jsonValue) StringMap(def map[string]string) map[string]string {
|
|
m, err := j.Map()
|
|
if err != nil {
|
|
return def
|
|
}
|
|
|
|
res := map[string]string{}
|
|
|
|
for k, v := range m {
|
|
res[k] = fmt.Sprintf("%v", v)
|
|
}
|
|
|
|
return res
|
|
}
|
|
|
|
func (j *jsonValue) Scan(v interface{}) error {
|
|
b, err := j.MarshalJSON()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return json.Unmarshal(b, v)
|
|
}
|
|
|
|
func (j *jsonValue) Bytes() []byte {
|
|
b, err := j.Json.Bytes()
|
|
if err != nil {
|
|
// try return marshaled
|
|
b, err = j.MarshalJSON()
|
|
if err != nil {
|
|
return []byte{}
|
|
}
|
|
return b
|
|
}
|
|
return b
|
|
}
|