1
0
mirror of https://github.com/mgechev/revive.git synced 2025-10-30 23:37:49 +02:00

feature: support spanner struct tag in struct-tag rule (#1479)

This commit is contained in:
Sarthak S. Waghmare
2025-08-16 01:00:40 +05:30
committed by GitHub
parent 9d600b6df1
commit f07a47a1bf
5 changed files with 36 additions and 2 deletions

View File

@@ -1104,7 +1104,7 @@ _Configuration_: N/A
_Description_: Struct tags are not checked at compile time.
This rule spots errors in struct tags of the following types:
asn1, bson, datastore, default, json, mapstructure, properties, protobuf, required, toml, url, validate, xml, yaml.
asn1, bson, datastore, default, json, mapstructure, properties, protobuf, required, spanner, toml, url, validate, xml, yaml.
_Configuration_: (optional) list of user defined options.

View File

@@ -30,6 +30,7 @@ const (
keyProperties tagKey = "properties"
keyProtobuf tagKey = "protobuf"
keyRequired tagKey = "required"
keySpanner tagKey = "spanner"
keyTOML tagKey = "toml"
keyURL tagKey = "url"
keyValidate tagKey = "validate"
@@ -49,6 +50,7 @@ var tagCheckers = map[tagKey]tagChecker{
keyProperties: checkPropertiesTag,
keyProtobuf: checkProtobufTag,
keyRequired: checkRequiredTag,
keySpanner: checkSpannerTag,
keyTOML: checkTOMLTag,
keyURL: checkURLTag,
keyValidate: checkValidateTag,
@@ -198,7 +200,7 @@ func (w lintStructTagRule) checkTagNameIfNeed(checkCtx *checkContext, tag *struc
key := tagKey(tag.Key)
switch key {
case keyBSON, keyJSON, keyXML, keyYAML, keyProtobuf:
case keyBSON, keyJSON, keyXML, keyYAML, keyProtobuf, keySpanner:
default:
return "", true
}
@@ -558,6 +560,18 @@ func checkYAMLTag(checkCtx *checkContext, tag *structtag.Tag, _ ast.Expr) (messa
return "", true
}
func checkSpannerTag(checkCtx *checkContext, tag *structtag.Tag, _ ast.Expr) (message string, succeeded bool) {
if tag.Name == "-" {
return "", true
}
for _, opt := range tag.Options {
if !checkCtx.isUserDefined(keySpanner, opt) {
return fmt.Sprintf(msgUnknownOption, opt), false
}
}
return "", true
}
func checkValidateOptionsAlternatives(checkCtx *checkContext, alternatives []string) (message string, succeeded bool) {
for _, alternative := range alternatives {
alternative := strings.TrimSpace(alternative)

View File

@@ -21,6 +21,7 @@ func TestStructTagWithUserOptions(t *testing.T) {
"mapstructure,myMapstructureOption",
"validate,displayName",
"toml,unknown",
"spanner,mySpannerOption",
},
})
}

View File

@@ -88,6 +88,12 @@ type TestDuplicatedProtobufTags struct {
C int `protobuf:"varint,name=c"` // MATCH /duplicated tag name "c" in protobuf tag/
}
type SpannerDuplicatedTags struct {
A int `spanner:"field_a"`
B int `spanner:"field_a"` // MATCH /duplicated tag name "field_a" in spanner tag/
C int `spanner:"field_c"`
}
// test case from
// sigs.k8s.io/kustomize/api/types/helmchartargs.go
@@ -182,3 +188,11 @@ type PropertiesTags struct {
Field []string `properties:",default=a;b;c"`
Field map[string]string `properties:"myName,omitempty"` // MATCH /unknown or malformed option "omitempty" in properties tag/
}
type SpannerUser struct {
ID int `spanner:"user_id"`
Name string `spanner:"full_name"`
Email string `spanner:"-"` // Valid: ignore field
CreatedAt time.Time `spanner:"created_at"`
UpdatedAt time.Time `spanner:"updated_at,unknown"` // MATCH /unknown option "unknown" in spanner tag/
}

View File

@@ -46,3 +46,8 @@ type TomlUser struct {
Username string `toml:"username,omitempty"`
Location string `toml:"location,unknown"`
}
type SpannerUserOptions struct {
ID int `spanner:"user_id,mySpannerOption"`
Name string `spanner:"full_name,unknownOption"` // MATCH /unknown option "unknownOption" in spanner tag/
}