mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/yunionio/cloudpods.git
synced 2026-09-20 08:03:53 +08:00
fix: task params nil params panic (#25699)
Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
This commit is contained in:
2
go.mod
2
go.mod
@@ -122,7 +122,7 @@ require (
|
|||||||
yunion.io/x/jsonutils v1.0.1-0.20260917025845-3108cd9a32ea
|
yunion.io/x/jsonutils v1.0.1-0.20260917025845-3108cd9a32ea
|
||||||
yunion.io/x/log v1.0.1-0.20240305175729-7cf2d6cd5a91
|
yunion.io/x/log v1.0.1-0.20240305175729-7cf2d6cd5a91
|
||||||
yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900
|
yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900
|
||||||
yunion.io/x/pkg v1.10.4-0.20260916163305-b7743fa5e758
|
yunion.io/x/pkg v1.10.4-0.20260918012554-27cd9d2e093b
|
||||||
yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1
|
yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1
|
||||||
yunion.io/x/sqlchemy v1.1.3-0.20260917035232-d682485b3a12
|
yunion.io/x/sqlchemy v1.1.3-0.20260917035232-d682485b3a12
|
||||||
yunion.io/x/structarg v0.0.0-20260917033311-96c7653334ac
|
yunion.io/x/structarg v0.0.0-20260917033311-96c7653334ac
|
||||||
|
|||||||
3
go.sum
3
go.sum
@@ -1989,8 +1989,9 @@ yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900 h1:Hu/4ERvoWaN6aiFs4h4/yvVB
|
|||||||
yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900/go.mod h1:0vLkNEhlmA64HViPBAnSTUMrx5QP1CLsxXmxDKQ80tc=
|
yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900/go.mod h1:0vLkNEhlmA64HViPBAnSTUMrx5QP1CLsxXmxDKQ80tc=
|
||||||
yunion.io/x/pkg v0.0.0-20190628082551-f4033ba2ea30/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
|
yunion.io/x/pkg v0.0.0-20190628082551-f4033ba2ea30/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
|
||||||
yunion.io/x/pkg v0.0.0-20200814072949-4f1b541857d6/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
|
yunion.io/x/pkg v0.0.0-20200814072949-4f1b541857d6/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
|
||||||
yunion.io/x/pkg v1.10.4-0.20260916163305-b7743fa5e758 h1:3p/GCOPvDfvlSfovOh9GKxsSa7PPqp//DUjGRX8Wyus=
|
|
||||||
yunion.io/x/pkg v1.10.4-0.20260916163305-b7743fa5e758/go.mod h1:Crp6aUYB+Yq16DFjZPHhHq7ha5HL2DfyPvzCo2LJ+LU=
|
yunion.io/x/pkg v1.10.4-0.20260916163305-b7743fa5e758/go.mod h1:Crp6aUYB+Yq16DFjZPHhHq7ha5HL2DfyPvzCo2LJ+LU=
|
||||||
|
yunion.io/x/pkg v1.10.4-0.20260918012554-27cd9d2e093b h1:XUJLpD48685DE8hwxEC+ms1F4T6/g2KKAfGuVn8rZeo=
|
||||||
|
yunion.io/x/pkg v1.10.4-0.20260918012554-27cd9d2e093b/go.mod h1:S8ITTpENaL3qSXi8Y4L6wVbVlP8XZ5BvABO10DFqF7M=
|
||||||
yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1 h1:1KJ3YYinydPHpDEQRXdr/T8SYcKZ5Er+m489H+PnaQ4=
|
yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1 h1:1KJ3YYinydPHpDEQRXdr/T8SYcKZ5Er+m489H+PnaQ4=
|
||||||
yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1/go.mod h1:0iFKpOs1y4lbCxeOmq3Xx/0AcQoewVPwj62eRluioEo=
|
yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1/go.mod h1:0iFKpOs1y4lbCxeOmq3Xx/0AcQoewVPwj62eRluioEo=
|
||||||
yunion.io/x/sqlchemy v1.1.3-0.20260917035232-d682485b3a12 h1:xU8Z/Zg+zc199Y58eB3fA8mvOHsA28UCDfd7OuK3QKA=
|
yunion.io/x/sqlchemy v1.1.3-0.20260917035232-d682485b3a12 h1:xU8Z/Zg+zc199Y58eB3fA8mvOHsA28UCDfd7OuK3QKA=
|
||||||
|
|||||||
@@ -951,7 +951,22 @@ func (task *STask) ClearPendingUsage(index int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (task *STask) GetParams() *jsonutils.JSONDict {
|
func (task *STask) GetParams() *jsonutils.JSONDict {
|
||||||
return task.Params
|
result := jsonutils.NewDict()
|
||||||
|
if task.Params == nil {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
copied := task.Params.DeepCopy()
|
||||||
|
copyParams, ok := copied.(*jsonutils.JSONDict)
|
||||||
|
if !ok || copyParams == nil {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
paramsJsonMap, _ := copyParams.GetMap()
|
||||||
|
for k, v := range paramsJsonMap {
|
||||||
|
if !strings.HasPrefix(k, "__") {
|
||||||
|
result.Set(k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (task *STask) GetUserCred() mcclient.TokenCredential {
|
func (task *STask) GetUserCred() mcclient.TokenCredential {
|
||||||
|
|||||||
144
pkg/cloudcommon/db/taskman/tasks_test.go
Normal file
144
pkg/cloudcommon/db/taskman/tasks_test.go
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
// Copyright 2019 Yunion
|
||||||
|
//
|
||||||
|
// 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 taskman
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"yunion.io/x/jsonutils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSTaskGetParams(t *testing.T) {
|
||||||
|
newParams := func(pairs map[string]jsonutils.JSONObject) *jsonutils.JSONDict {
|
||||||
|
params := jsonutils.NewDict()
|
||||||
|
for k, v := range pairs {
|
||||||
|
params.Set(k, v)
|
||||||
|
}
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
nested := jsonutils.NewDict()
|
||||||
|
nested.Set("ip", jsonutils.NewString("10.0.0.1"))
|
||||||
|
stages := jsonutils.NewArray(
|
||||||
|
jsonutils.NewDict(),
|
||||||
|
jsonutils.NewString("on_init"),
|
||||||
|
)
|
||||||
|
|
||||||
|
cases := []struct {
|
||||||
|
name string
|
||||||
|
params *jsonutils.JSONDict
|
||||||
|
want *jsonutils.JSONDict
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "nil_params",
|
||||||
|
params: nil,
|
||||||
|
want: jsonutils.NewDict(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty_params",
|
||||||
|
params: jsonutils.NewDict(),
|
||||||
|
want: jsonutils.NewDict(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "keep_public_keys",
|
||||||
|
params: newParams(map[string]jsonutils.JSONObject{
|
||||||
|
"parent_task_id": jsonutils.NewString("task-1"),
|
||||||
|
"auto_start": jsonutils.JSONTrue,
|
||||||
|
}),
|
||||||
|
want: newParams(map[string]jsonutils.JSONObject{
|
||||||
|
"parent_task_id": jsonutils.NewString("task-1"),
|
||||||
|
"auto_start": jsonutils.JSONTrue,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "drop_internal_keys",
|
||||||
|
params: newParams(map[string]jsonutils.JSONObject{
|
||||||
|
"__stages": stages,
|
||||||
|
"__pending_usage__": jsonutils.NewDict(),
|
||||||
|
"__request_context": jsonutils.NewDict(),
|
||||||
|
"__parent_task_notifyurl": jsonutils.NewString("http://notify"),
|
||||||
|
}),
|
||||||
|
want: jsonutils.NewDict(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "mixed_keys",
|
||||||
|
params: newParams(map[string]jsonutils.JSONObject{
|
||||||
|
"desc": nested,
|
||||||
|
"__stages": stages,
|
||||||
|
"_private": jsonutils.NewString("keep"),
|
||||||
|
"__": jsonutils.NewString("drop"),
|
||||||
|
"guest_id": jsonutils.NewString("g-1"),
|
||||||
|
}),
|
||||||
|
want: newParams(map[string]jsonutils.JSONObject{
|
||||||
|
"desc": nested,
|
||||||
|
"_private": jsonutils.NewString("keep"),
|
||||||
|
"guest_id": jsonutils.NewString("g-1"),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
c := c
|
||||||
|
t.Run(c.name, func(t *testing.T) {
|
||||||
|
task := &STask{}
|
||||||
|
task.Params = c.params
|
||||||
|
got := task.GetParams()
|
||||||
|
if got == nil {
|
||||||
|
t.Fatal("GetParams() returned nil, want empty dict")
|
||||||
|
}
|
||||||
|
if !got.Equals(c.want) {
|
||||||
|
t.Fatalf("GetParams() = %s, want %s", got, c.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSTaskGetParamsDoesNotMutateOriginal(t *testing.T) {
|
||||||
|
orig := jsonutils.NewDict()
|
||||||
|
orig.Set("guest_id", jsonutils.NewString("g-1"))
|
||||||
|
orig.Set("__stages", jsonutils.NewArray(jsonutils.NewString("on_init")))
|
||||||
|
nested := jsonutils.NewDict()
|
||||||
|
nested.Set("ip", jsonutils.NewString("10.0.0.1"))
|
||||||
|
orig.Set("desc", nested)
|
||||||
|
|
||||||
|
task := &STask{STaskBase: STaskBase{Params: orig}}
|
||||||
|
got := task.GetParams()
|
||||||
|
got.Set("guest_id", jsonutils.NewString("g-2"))
|
||||||
|
got.Set("extra", jsonutils.JSONTrue)
|
||||||
|
desc, err := got.Get("desc")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("get desc: %v", err)
|
||||||
|
}
|
||||||
|
descDict, ok := desc.(*jsonutils.JSONDict)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("desc type %T, want *jsonutils.JSONDict", desc)
|
||||||
|
}
|
||||||
|
descDict.Set("ip", jsonutils.NewString("10.0.0.2"))
|
||||||
|
|
||||||
|
if got.Contains("__stages") {
|
||||||
|
t.Fatal("GetParams() leaked internal key __stages")
|
||||||
|
}
|
||||||
|
guestId, _ := orig.GetString("guest_id")
|
||||||
|
if guestId != "g-1" {
|
||||||
|
t.Fatalf("original guest_id = %s, want g-1", guestId)
|
||||||
|
}
|
||||||
|
if !orig.Contains("__stages") {
|
||||||
|
t.Fatal("original __stages was removed")
|
||||||
|
}
|
||||||
|
origIp, _ := orig.GetString("desc", "ip")
|
||||||
|
if origIp != "10.0.0.1" {
|
||||||
|
t.Fatalf("original nested ip = %s, want 10.0.0.1", origIp)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -356,6 +356,7 @@ func (self *SBaremetalGuestDriver) RequestStartOnHost(ctx context.Context, guest
|
|||||||
if params.Length() > 0 {
|
if params.Length() > 0 {
|
||||||
config.Add(params, "params")
|
config.Add(params, "params")
|
||||||
}
|
}
|
||||||
|
log.Debugf("RequestStartOnHost config: %s", config.String())
|
||||||
headers := task.GetTaskRequestHeader()
|
headers := task.GetTaskRequestHeader()
|
||||||
url := fmt.Sprintf("/baremetals/%s/servers/%s/start", host.Id, guest.Id)
|
url := fmt.Sprintf("/baremetals/%s/servers/%s/start", host.Id, guest.Id)
|
||||||
_, err := host.BaremetalSyncRequest(ctx, "POST", url, headers, config)
|
_, err := host.BaremetalSyncRequest(ctx, "POST", url, headers, config)
|
||||||
|
|||||||
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@@ -2788,7 +2788,7 @@ yunion.io/x/log/hooks
|
|||||||
yunion.io/x/ovsdb/cli_util
|
yunion.io/x/ovsdb/cli_util
|
||||||
yunion.io/x/ovsdb/schema/ovn_nb
|
yunion.io/x/ovsdb/schema/ovn_nb
|
||||||
yunion.io/x/ovsdb/types
|
yunion.io/x/ovsdb/types
|
||||||
# yunion.io/x/pkg v1.10.4-0.20260916163305-b7743fa5e758
|
# yunion.io/x/pkg v1.10.4-0.20260918012554-27cd9d2e093b
|
||||||
## explicit; go 1.18
|
## explicit; go 1.18
|
||||||
yunion.io/x/pkg/appctx
|
yunion.io/x/pkg/appctx
|
||||||
yunion.io/x/pkg/errors
|
yunion.io/x/pkg/errors
|
||||||
|
|||||||
26
vendor/yunion.io/x/pkg/util/reflectutils/ambiguous.go
generated
vendored
26
vendor/yunion.io/x/pkg/util/reflectutils/ambiguous.go
generated
vendored
@@ -57,7 +57,7 @@ func expandAmbiguousPrefix(fields SStructFieldValueSet) SStructFieldValueSet {
|
|||||||
if prefixed[idx] {
|
if prefixed[idx] {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
amPrefix, ok := fields[idx].Info.Tags[TAG_AMBIGUOUS_PREFIX]
|
amPrefix, ok := fields[idx].Info.Tag(TAG_AMBIGUOUS_PREFIX)
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -65,15 +65,25 @@ func expandAmbiguousPrefix(fields SStructFieldValueSet) SStructFieldValueSet {
|
|||||||
if takenByOther(fields, expanded, indexes) {
|
if takenByOther(fields, expanded, indexes) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fields[idx].Info.Name = expanded
|
info := fields[idx].Info
|
||||||
if depBy, ok := fields[idx].Info.Tags[TAG_DEPRECATED_BY]; ok {
|
info.Name = expanded
|
||||||
fields[idx].Info.Tags[TAG_DEPRECATED_BY] = fmt.Sprintf("%s%s", amPrefix, depBy)
|
_, newDepBy := info.tags[TAG_DEPRECATED_BY]
|
||||||
|
_, oldDepBy := info.tags[TAG_OLD_DEPRECATED_BY]
|
||||||
|
if newDepBy || oldDepBy {
|
||||||
|
// the tags may still be shared with other callers
|
||||||
|
info.copyTags()
|
||||||
}
|
}
|
||||||
if depBy, ok := fields[idx].Info.Tags[TAG_OLD_DEPRECATED_BY]; ok {
|
if newDepBy {
|
||||||
fields[idx].Info.Tags[TAG_OLD_DEPRECATED_BY] = fmt.Sprintf("%s%s", amPrefix, depBy)
|
info.tags[TAG_DEPRECATED_BY] = fmt.Sprintf("%s%s", amPrefix, info.tags[TAG_DEPRECATED_BY])
|
||||||
|
}
|
||||||
|
if oldDepBy {
|
||||||
|
info.tags[TAG_OLD_DEPRECATED_BY] = fmt.Sprintf("%s%s", amPrefix, info.tags[TAG_OLD_DEPRECATED_BY])
|
||||||
|
}
|
||||||
|
if len(info.aliases) > 0 {
|
||||||
|
info.copyAliases()
|
||||||
|
for i := range info.aliases {
|
||||||
|
info.aliases[i] = fmt.Sprintf("%s%s", amPrefix, info.aliases[i])
|
||||||
}
|
}
|
||||||
for i := range fields[idx].Info.Aliases {
|
|
||||||
fields[idx].Info.Aliases[i] = fmt.Sprintf("%s%s", amPrefix, fields[idx].Info.Aliases[i])
|
|
||||||
}
|
}
|
||||||
prefixed[idx] = true
|
prefixed[idx] = true
|
||||||
changed = true
|
changed = true
|
||||||
|
|||||||
89
vendor/yunion.io/x/pkg/util/reflectutils/jsonfield.go
generated
vendored
89
vendor/yunion.io/x/pkg/util/reflectutils/jsonfield.go
generated
vendored
@@ -30,9 +30,10 @@ import (
|
|||||||
// package. Do not construct a literal or modify the exported fields in an
|
// package. Do not construct a literal or modify the exported fields in an
|
||||||
// unmanaged way
|
// unmanaged way
|
||||||
//
|
//
|
||||||
// The tags of a field are meant to be read through Tag and TagMap rather than
|
// The tags of a field are read through Tag and TagMap. The map behind them
|
||||||
// off the Tags map, which is not handed out to stay writable by whoever read
|
// is shared with the other callers of the fetch functions, which is what
|
||||||
// it; a caller may modify what TagMap returns.
|
// makes reading a field several times cheap, so a caller may only modify what
|
||||||
|
// TagMap hands out, which is a copy of its own.
|
||||||
type SStructFieldInfo struct {
|
type SStructFieldInfo struct {
|
||||||
// True if the field has json tag `json:"-"`
|
// True if the field has json tag `json:"-"`
|
||||||
Ignore bool
|
Ignore bool
|
||||||
@@ -72,40 +73,34 @@ type SStructFieldInfo struct {
|
|||||||
// value as a json string
|
// value as a json string
|
||||||
ForceString bool
|
ForceString bool
|
||||||
|
|
||||||
// Tags holds the tags of the field keyed by tag name, a tag without a
|
// tags holds the tags of the field keyed by tag name, a tag without a
|
||||||
// value being mapped to the empty string. Read it through Tag or
|
// value being mapped to the empty string. The map is shared with the
|
||||||
// TagMap rather than off here.
|
// other callers of the fetch functions, so it has to be copied with
|
||||||
Tags map[string]string
|
// copyTags before being written to; read it through Tag or TagMap.
|
||||||
|
tags map[string]string
|
||||||
|
|
||||||
// Aliases are the other names the field is looked up by, taken from
|
// aliases are the other names the field is looked up by, taken from
|
||||||
// the "alias" tag
|
// the "alias" tag. Like tags it is shared, and has to be copied with
|
||||||
Aliases []string
|
// copyAliases before being written to.
|
||||||
|
aliases []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SStructFieldInfo) updateTags(k, v string) {
|
// copyTags takes a private copy of the tags, so that they can be written to
|
||||||
s.Tags[k] = v
|
// without touching the ones this info was read out of.
|
||||||
}
|
func (s *SStructFieldInfo) copyTags() {
|
||||||
|
tags := make(map[string]string, len(s.tags)+1)
|
||||||
func (s SStructFieldInfo) deepCopy() *SStructFieldInfo {
|
for k, v := range s.tags {
|
||||||
scopy := SStructFieldInfo{
|
|
||||||
Ignore: s.Ignore,
|
|
||||||
OmitEmpty: s.OmitEmpty,
|
|
||||||
OmitFalse: s.OmitFalse,
|
|
||||||
OmitZero: s.OmitZero,
|
|
||||||
Name: s.Name,
|
|
||||||
FieldName: s.FieldName,
|
|
||||||
ForceString: s.ForceString,
|
|
||||||
kebabFieldName: s.kebabFieldName,
|
|
||||||
}
|
|
||||||
tags := make(map[string]string, len(s.Tags))
|
|
||||||
for k, v := range s.Tags {
|
|
||||||
tags[k] = v
|
tags[k] = v
|
||||||
}
|
}
|
||||||
scopy.Tags = tags
|
s.tags = tags
|
||||||
aliases := make([]string, len(s.Aliases))
|
}
|
||||||
copy(aliases, s.Aliases)
|
|
||||||
scopy.Aliases = aliases
|
// copyAliases takes a private copy of the aliases, so that they can be
|
||||||
return &scopy
|
// written to without touching the ones this info was read out of.
|
||||||
|
func (s *SStructFieldInfo) copyAliases() {
|
||||||
|
aliases := make([]string, len(s.aliases))
|
||||||
|
copy(aliases, s.aliases)
|
||||||
|
s.aliases = aliases
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseStructFieldJsonInfo(sf reflect.StructField) SStructFieldInfo {
|
func ParseStructFieldJsonInfo(sf reflect.StructField) SStructFieldInfo {
|
||||||
@@ -120,8 +115,8 @@ func ParseFieldJsonInfo(name string, tag reflect.StructTag) SStructFieldInfo {
|
|||||||
info.OmitZero = false
|
info.OmitZero = false
|
||||||
info.OmitFalse = false
|
info.OmitFalse = false
|
||||||
|
|
||||||
info.Tags = utils.TagMap(tag)
|
info.tags = utils.TagMap(tag)
|
||||||
if val, ok := info.Tags["json"]; ok {
|
if val, ok := info.tags["json"]; ok {
|
||||||
keys := strings.Split(val, ",")
|
keys := strings.Split(val, ",")
|
||||||
if len(keys) > 0 {
|
if len(keys) > 0 {
|
||||||
if keys[0] == "-" {
|
if keys[0] == "-" {
|
||||||
@@ -155,14 +150,14 @@ func ParseFieldJsonInfo(name string, tag reflect.StructTag) SStructFieldInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if val, ok := info.Tags["name"]; ok {
|
if val, ok := info.tags["name"]; ok {
|
||||||
info.Name = val
|
info.Name = val
|
||||||
}
|
}
|
||||||
if !info.Ignore && len(info.Name) == 0 {
|
if !info.Ignore && len(info.Name) == 0 {
|
||||||
info.Name = info.kebabFieldName
|
info.Name = info.kebabFieldName
|
||||||
}
|
}
|
||||||
if val, ok := info.Tags["alias"]; !info.Ignore && ok {
|
if val, ok := info.tags["alias"]; !info.Ignore && ok {
|
||||||
info.Aliases = strings.Split(val, ",")
|
info.aliases = strings.Split(val, ",")
|
||||||
}
|
}
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
@@ -179,15 +174,15 @@ func (info *SStructFieldInfo) MarshalName() string {
|
|||||||
// Tag returns the value of the tag named name and whether the field has it.
|
// Tag returns the value of the tag named name and whether the field has it.
|
||||||
// A tag without a value is reported as present with an empty value.
|
// A tag without a value is reported as present with an empty value.
|
||||||
func (info *SStructFieldInfo) Tag(name string) (string, bool) {
|
func (info *SStructFieldInfo) Tag(name string) (string, bool) {
|
||||||
val, ok := info.Tags[name]
|
val, ok := info.tags[name]
|
||||||
return val, ok
|
return val, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// TagMap returns a copy of the tags of the field, which the caller owns and
|
// TagMap returns a copy of the tags of the field, which the caller owns and
|
||||||
// is free to modify.
|
// is free to modify.
|
||||||
func (info *SStructFieldInfo) TagMap() map[string]string {
|
func (info *SStructFieldInfo) TagMap() map[string]string {
|
||||||
tags := make(map[string]string, len(info.Tags))
|
tags := make(map[string]string, len(info.tags))
|
||||||
for k, v := range info.Tags {
|
for k, v := range info.tags {
|
||||||
tags[k] = v
|
tags[k] = v
|
||||||
}
|
}
|
||||||
return tags
|
return tags
|
||||||
@@ -375,10 +370,10 @@ func fetchStructFieldValueSet3(dataValue reflect.Value, allocatePtr bool, tags m
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fieldInfo := fieldInfos[sf.Name].deepCopy()
|
fieldInfo := fieldInfos[sf.Name]
|
||||||
if !fieldInfo.Ignore || includeIgnore {
|
if !fieldInfo.Ignore || includeIgnore {
|
||||||
structFieldVaule := SStructFieldValue{
|
structFieldVaule := SStructFieldValue{
|
||||||
Info: fieldInfo,
|
Info: &fieldInfo,
|
||||||
Value: fv,
|
Value: fv,
|
||||||
}
|
}
|
||||||
if parent != nil {
|
if parent != nil {
|
||||||
@@ -390,6 +385,7 @@ func fetchStructFieldValueSet3(dataValue reflect.Value, allocatePtr bool, tags m
|
|||||||
if len(tags) > 0 {
|
if len(tags) > 0 {
|
||||||
for i := range fields {
|
for i := range fields {
|
||||||
fieldName := fields[i].Info.MarshalName()
|
fieldName := fields[i].Info.MarshalName()
|
||||||
|
owned := false
|
||||||
for k, v := range tags {
|
for k, v := range tags {
|
||||||
target := ""
|
target := ""
|
||||||
pos := strings.Index(k, "->")
|
pos := strings.Index(k, "->")
|
||||||
@@ -400,7 +396,12 @@ func fetchStructFieldValueSet3(dataValue reflect.Value, allocatePtr bool, tags m
|
|||||||
if len(target) > 0 && target != fieldName {
|
if len(target) > 0 && target != fieldName {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fields[i].Info.updateTags(k, v)
|
if !owned {
|
||||||
|
// the tags may still be shared with other callers
|
||||||
|
fields[i].Info.copyTags()
|
||||||
|
owned = true
|
||||||
|
}
|
||||||
|
fields[i].Info.tags[k] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -445,7 +446,7 @@ func (fields SStructFieldValueSet) GetStructFieldIndexes2(name string, strictMod
|
|||||||
ret = append(ret, i)
|
ret = append(ret, i)
|
||||||
} else if info.FieldName == capName {
|
} else if info.FieldName == capName {
|
||||||
ret = append(ret, i)
|
ret = append(ret, i)
|
||||||
} else if len(info.Aliases) > 0 && utils.IsInArray(name, info.Aliases) {
|
} else if len(info.aliases) > 0 && utils.IsInArray(name, info.aliases) {
|
||||||
ret = append(ret, i)
|
ret = append(ret, i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user