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:
		
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							9d600b6df1
						
					
				
				
					commit
					f07a47a1bf
				
			| @@ -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. | ||||
|  | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -21,6 +21,7 @@ func TestStructTagWithUserOptions(t *testing.T) { | ||||
| 			"mapstructure,myMapstructureOption", | ||||
| 			"validate,displayName", | ||||
| 			"toml,unknown", | ||||
| 			"spanner,mySpannerOption", | ||||
| 		}, | ||||
| 	}) | ||||
| } | ||||
|   | ||||
							
								
								
									
										14
									
								
								testdata/struct_tag.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								testdata/struct_tag.go
									
									
									
									
										vendored
									
									
								
							| @@ -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/ | ||||
| } | ||||
							
								
								
									
										5
									
								
								testdata/struct_tag_user_options.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								testdata/struct_tag_user_options.go
									
									
									
									
										vendored
									
									
								
							| @@ -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/ | ||||
| } | ||||
		Reference in New Issue
	
	Block a user