Merge pull request #1 from oscarhealth/naming_checks

Format output of naming checks more cleanly, and simplify regexes
This commit is contained in:
Alec Thomas 2017-02-24 09:12:26 +11:00 committed by GitHub
commit 1365ae24b0

View File

@ -8,23 +8,35 @@ import (
"github.com/UrbanCompass/thriftlint" "github.com/UrbanCompass/thriftlint"
) )
var ( type NamingStyle struct {
upperCamelCaseRegex = `^[_A-Z][a-z]*([A-Z][0-9a-z]*)*$` Name string
lowerCamelCaseRegex = `^[_a-z]+([A-Z0-9a-z]*)*$` Pattern *regexp.Regexp
upperSnakeCaseRegex = `^[A-Z_]+([A-Z0-9]+_?)*$` }
)
var ( var (
upperCamelCaseStyle = NamingStyle{
Name: "title case",
Pattern: regexp.MustCompile(`^_?([A-Z][0-9a-z]*)*$`),
}
lowerCamelCaseStyle = NamingStyle{
Name: "camel case",
Pattern: regexp.MustCompile(`^_?[a-z][A-Z0-9a-z]*$`),
}
upperSnakeCaseStyle = NamingStyle{
Name: "upper snake case",
Pattern: regexp.MustCompile(`^_?[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$`),
}
// CheckNamesDefaults is a map of Thrift AST node type to a regular expression for // CheckNamesDefaults is a map of Thrift AST node type to a regular expression for
// validating names of that type. // validating names of that type.
CheckNamesDefaults = map[reflect.Type]string{ CheckNamesDefaults = map[reflect.Type]NamingStyle{
thriftlint.ServiceType: upperCamelCaseRegex, thriftlint.ServiceType: upperCamelCaseStyle,
thriftlint.EnumType: upperCamelCaseRegex, thriftlint.EnumType: upperCamelCaseStyle,
thriftlint.StructType: upperCamelCaseRegex, thriftlint.StructType: upperCamelCaseStyle,
thriftlint.EnumValueType: upperSnakeCaseRegex, thriftlint.EnumValueType: upperSnakeCaseStyle,
thriftlint.FieldType: lowerCamelCaseRegex, thriftlint.FieldType: lowerCamelCaseStyle,
thriftlint.MethodType: lowerCamelCaseRegex, thriftlint.MethodType: lowerCamelCaseStyle,
thriftlint.ConstantType: upperSnakeCaseRegex, thriftlint.ConstantType: upperSnakeCaseStyle,
} }
// CheckNamesDefaultBlacklist is names that should never be used for symbols. // CheckNamesDefaultBlacklist is names that should never be used for symbols.
@ -36,18 +48,14 @@ var (
// CheckNames checks Thrift symbols comply with a set of regular expressions. // CheckNames checks Thrift symbols comply with a set of regular expressions.
// //
// If mathces or blacklist are nil, global defaults will be used. // If matches or blacklist are nil, global defaults will be used.
func CheckNames(matches map[reflect.Type]string, blacklist map[string]bool) thriftlint.Check { func CheckNames(matches map[reflect.Type]NamingStyle, blacklist map[string]bool) thriftlint.Check {
if matches == nil { if matches == nil {
matches = CheckNamesDefaults matches = CheckNamesDefaults
} }
if blacklist == nil { if blacklist == nil {
blacklist = CheckNamesDefaultBlacklist blacklist = CheckNamesDefaultBlacklist
} }
regexes := map[reflect.Type]*regexp.Regexp{}
for t, p := range matches {
regexes[t] = regexp.MustCompile(p)
}
return thriftlint.MakeCheck("naming", func(v interface{}) (messages thriftlint.Messages) { return thriftlint.MakeCheck("naming", func(v interface{}) (messages thriftlint.Messages) {
rv := reflect.Indirect(reflect.ValueOf(v)) rv := reflect.Indirect(reflect.ValueOf(v))
nameField := rv.FieldByName("Name") nameField := rv.FieldByName("Name")
@ -56,16 +64,16 @@ func CheckNames(matches map[reflect.Type]string, blacklist map[string]bool) thri
} }
name := nameField.Interface().(string) name := nameField.Interface().(string)
// Special-case DEPRECATED_ fields. // Special-case DEPRECATED_ fields.
checker, ok := regexes[rv.Type()] checker, ok := matches[rv.Type()]
if !ok || strings.HasPrefix(name, "DEPRECATED_") { if !ok || strings.HasPrefix(name, "DEPRECATED_") {
return nil return nil
} }
if blacklist[name] { if blacklist[name] {
messages.Warning(v, "%q is a disallowed name", name) messages.Warning(v, "%q is a disallowed name", name)
} }
if ok := checker.MatchString(name); !ok { if ok := checker.Pattern.MatchString(name); !ok {
messages.Warning(v, "name of %s %q should match %q", strings.ToLower(rv.Type().Name()), messages.Warning(v, "name of %s %q should be %s", strings.ToLower(rv.Type().Name()),
name, checker.String()) name, checker.Name)
} }
return return
}) })