Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions docs/rules/0004/resource-plural.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ verifies the `plural` field exists.
message Book {
// no plural annotation
option (aep.api.resource) = {
type: "library.googleapis.com/BookShelf"
pattern: "publishers/{publisher}/bookShelves/{book_shelf}"
type: "library.googleapis.com/book-shelf"
pattern: "publishers/{publisher}/book-shelves/{book_shelf}"
};

string path = 1;
Expand All @@ -41,9 +41,9 @@ message Book {
// Correct.
message Book {
option (aep.api.resource) = {
type: "library.googleapis.com/BookShelf"
pattern: "publishers/{publisher}/bookShelves/{book_shelf}"
plural: "bookShelves",
type: "library.googleapis.com/book-shelf"
pattern: "publishers/{publisher}/book-shelves/{book_shelf}"
plural: "book-shelves",
};

string path = 1;
Expand Down
5 changes: 2 additions & 3 deletions internal/cmd/quality-checker/rule_name.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,11 @@ import (
"fmt"
"os"
"regexp"

"github.com/stoewer/go-strcase"
"strings"
)

func checkRuleName(aep int, name string) []error {
path := fmt.Sprintf("rules/aep%04d/%s.go", aep, strcase.SnakeCase(name))
path := fmt.Sprintf("rules/aep%04d/%s.go", aep, strings.ReplaceAll(name, "-", "_"))

// Read in the file.
contentsBytes, err := os.ReadFile(path)
Expand Down
4 changes: 1 addition & 3 deletions internal/cmd/quality-checker/rule_registered.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@ import (
"os"
"regexp"
"strings"

"github.com/stoewer/go-strcase"
)

func checkRuleRegistered(aep int, name string) []error {
path := fmt.Sprintf("rules/aep%04d/%s.go", aep, strcase.SnakeCase(name))
path := fmt.Sprintf("rules/aep%04d/%s.go", aep, strings.ReplaceAll(name, "-", "_"))

// Read in the file.
contents, err := os.ReadFile(path)
Expand Down
2 changes: 1 addition & 1 deletion rules/aep0004/aep0004.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func getDesiredPattern(pattern string) string {
varname := token[1 : len(token)-1]
want = append(want, fmt.Sprintf("{%s}", strcase.SnakeCase(varname)))
} else {
want = append(want, strcase.LowerCamelCase(token))
want = append(want, strcase.KebabCase(token))
}
}
return strings.Join(want, "/")
Expand Down
20 changes: 16 additions & 4 deletions rules/aep0004/resource_pattern.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,24 +50,36 @@ func lintResourcePatternCommon(patterns []string, desc desc.Descriptor, loc *dpb
}}
}

// Ensure that the constant segments of the pattern uses camel case,
// Ensure that the constant segments of the pattern uses kebab case,
// not snake case, and there are no spaces.
for _, pattern := range patterns {
plainPattern := getPlainPattern(pattern)

if strings.Contains(plainPattern, " ") {
return []lint.Problem{{
Message: "Resource patterns should not have spaces",
Descriptor: desc,
Location: loc,
}}
}

if strings.Contains(plainPattern, "_") {
return []lint.Problem{{
Message: fmt.Sprintf(
"Resource patterns should use camel case (apart from the variable names), such as %q.",
"Resource patterns should use kebab case (apart from the variable names), such as %q.",
getDesiredPattern(pattern),
),
Descriptor: desc,
Location: loc,
}}
}
if strings.Contains(plainPattern, " ") {

if getDesiredPattern(pattern) != pattern {
return []lint.Problem{{
Message: "Resource patterns should not have spaces",
Message: fmt.Sprintf(
"Resource patterns should use kebab case (apart from the variable names), such as %q.",
getDesiredPattern(pattern),
),
Descriptor: desc,
Location: loc,
}}
Expand Down
6 changes: 4 additions & 2 deletions rules/aep0004/resource_pattern_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ func TestResourcePattern(t *testing.T) {
problems testutils.Problems
}{
{"Valid", `pattern: "publishers/{publisher}/books/{book}"`, testutils.Problems{}},
{"ValidCamel", `pattern: "publishers/{publisher}/electronicBooks/{electronic_book}"`, testutils.Problems{}},
{"InvalidCamel", `pattern: "publishers/{publisher}/electronicBooks/{electronic_book}"`, testutils.Problems{{
Message: "Resource patterns should use kebab case (apart from the variable names), such as \"publishers/{publisher}/electronic-books/{electronic_book}\".",
}}},
{"Missing", "", testutils.Problems{{Message: "declare resource name pattern"}}},
{"SnakeCase", `pattern: "book_publishers/{book_publisher}/books/{book}"`, testutils.Problems{{
Message: "bookPublishers/{book_publisher}/books/{book}",
Message: `Resource patterns should use kebab case (apart from the variable names), such as "book-publishers/{book_publisher}/books/{book}".`,
}}},
{"HasSpaces", `pattern: "publishers/{publisher}/ books /{book}"`, testutils.Problems{{
Message: "Resource patterns should not have spaces",
Expand Down
7 changes: 4 additions & 3 deletions rules/aep0004/resource_plural.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/aep-dev/api-linter/locations"
"github.com/aep-dev/api-linter/rules/internal/utils"
"github.com/jhump/protoreflect/desc"
"github.com/stoewer/go-strcase"
)

var resourcePlural = &lint.MessageRule{
Expand All @@ -31,18 +32,18 @@ var resourcePlural = &lint.MessageRule{
r := utils.GetResource(m)
l := locations.MessageResource(m)
p := r.GetPlural()
pLower := utils.ToKebabCase(p)
pKebab := strcase.KebabCase(p)
if p == "" {
return []lint.Problem{{
Message: "Resources should declare plural.",
Descriptor: m,
Location: l,
}}
}
if pLower != p {
if pKebab != p {
return []lint.Problem{{
Message: fmt.Sprintf(
"Resource plural should be lowerCamelCase: %q", pLower,
"Resource plural should be kebab-case: %q", pKebab,
),
Descriptor: m,
Location: l,
Expand Down
4 changes: 2 additions & 2 deletions rules/aep0004/resource_plural_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ func TestResourcePlural(t *testing.T) {
"InvalidUpperCamel",
`plural: "BookShelves"`,
testutils.Problems{{
Message: "Resource plural should be lowerCamelCase",
Message: `Resource plural should be kebab-case: "book-shelves"`,
}},
},
{
"InvalidDash",
`plural: "Book-Shelves"`,
testutils.Problems{{
Message: "Resource plural should be lowerCamelCase",
Message: `Resource plural should be kebab-case: "book-shelves"`,
}},
},
} {
Expand Down
3 changes: 2 additions & 1 deletion rules/aep0004/resource_singular.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/aep-dev/api-linter/locations"
"github.com/aep-dev/api-linter/rules/internal/utils"
"github.com/jhump/protoreflect/desc"
"github.com/stoewer/go-strcase"
)

var resourceSingular = &lint.MessageRule{
Expand All @@ -32,7 +33,7 @@ var resourceSingular = &lint.MessageRule{
l := locations.MessageResource(m)
s := r.GetSingular()
_, typeName, ok := utils.SplitResourceTypeName(r.GetType())
lowerTypeName := utils.ToKebabCase(typeName)
lowerTypeName := strcase.KebabCase(typeName)
if s == "" {
return []lint.Problem{{
Message: fmt.Sprintf("Resources should declare singular: %q", lowerTypeName),
Expand Down
12 changes: 10 additions & 2 deletions rules/aep0004/resource_type_name.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ package aep0004

import (
"fmt"
"regexp"

"github.com/aep-dev/api-linter/lint"
"github.com/aep-dev/api-linter/locations"
"github.com/aep-dev/api-linter/rules/internal/utils"
"github.com/jhump/protoreflect/desc"
"github.com/stoewer/go-strcase"
)

var resourceTypeName = &lint.MessageRule{
Expand All @@ -32,21 +34,27 @@ var resourceTypeName = &lint.MessageRule{
LintMessage: func(m *desc.MessageDescriptor) []lint.Problem {
resource := utils.GetResource(m)
_, typeName, ok := utils.SplitResourceTypeName(resource.GetType())
kebabCase := utils.ToKebabCase(typeName)
if !ok {
return []lint.Problem{{
Message: "Resource type names must be of the form {Service Name}/{Type}.",
Descriptor: m,
Location: locations.MessageResource(m),
}}
}
kebabCase := removeNonAlphanumeric(strcase.KebabCase(typeName))
if kebabCase != typeName {
return []lint.Problem{{
Message: fmt.Sprintf("Type must be kebob-case with alphanumeric characters: %q", kebabCase),
Message: fmt.Sprintf("Type must be kebab-case with alphanumeric characters: %q", kebabCase),
Descriptor: m,
Location: locations.MessageResource(m),
}}
}
return nil
},
}

var notAlphaNumericReg = regexp.MustCompile(`[^a-zA-Z0-9-]+`)

func removeNonAlphanumeric(s string) string {
return notAlphaNumericReg.ReplaceAllString(s, "")
}
12 changes: 6 additions & 6 deletions rules/aep0004/resource_type_name_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ func TestResourceTypeName(t *testing.T) {
{"Valid", "library.googleapis.com/book", testutils.Problems{}},
{"InvalidTooMany", "library.googleapis.com/shelf/Book", testutils.Problems{{Message: "{Service Name}/{Type}"}}},
{"InvalidNotEnough", "library.googleapis.com~Book", testutils.Problems{{Message: "{Service Name}/{Type}"}}},
{"InvalidWithUnicode", "library.googleapis.com/BoØkLibre", testutils.Problems{{Message: `Type must be kebob-case`}}},
{"InvalidLowerCamelCase", "library.googleapis.com/bookLoan", testutils.Problems{{Message: `Type must be kebob-case with alphanumeric characters: "book-loan"`}}},
{"InvalidWithUnicode", "library.googleapis.com/BoØkLibre", testutils.Problems{{Message: `Type must be kebab-case`}}},
{"InvalidLowerCamelCase", "library.googleapis.com/bookLoan", testutils.Problems{{Message: `Type must be kebab-case with alphanumeric characters: "book-loan"`}}},
{"ValidLowerCamelCase", "library.googleapis.com/book-loan", testutils.Problems{}},
{"InvalidTypeNotAlphaNumeric", "library.googleapis.com/Book.:3", testutils.Problems{{Message: `Type must be kebob-case with alphanumeric characters: "book-:3"`}}},
{"InvalidTypeContainsEmoji", "library.googleapis.com/Book♥️", testutils.Problems{{Message: `Type must be kebob-case with alphanumeric characters: "book♥️"`}}},
{"InvalidTypeContainsDashes", "library.googleapis.com/Book-Shelf️", testutils.Problems{{Message: `Type must be kebob-case with alphanumeric characters: "book--she`}}},
{"InvalidTypeContainsUnderscore", "library.googleapis.com/Book_Shelf️", testutils.Problems{{Message: `Type must be kebob-case with alphanumeric characters: "book--she`}}},
{"InvalidTypeNotAlphaNumeric", "library.googleapis.com/Book.:3", testutils.Problems{{Message: `Type must be kebab-case with alphanumeric characters: "book3"`}}},
{"InvalidTypeContainsEmoji", "library.googleapis.com/Book♥️", testutils.Problems{{Message: `Type must be kebab-case with alphanumeric characters: "book"`}}},
Comment thread
kindermoumoute marked this conversation as resolved.
{"InvalidTypeContainsDashes", "library.googleapis.com/Book-Shelf️", testutils.Problems{{Message: `Type must be kebab-case with alphanumeric characters: "book-she`}}},
{"InvalidTypeContainsUnderscore", "library.googleapis.com/Book_Shelf️", testutils.Problems{{Message: `Type must be kebab-case with alphanumeric characters: "book-she`}}},
} {
t.Run(test.name, func(t *testing.T) {
f := testutils.ParseProto3Tmpl(t, `
Expand Down
2 changes: 1 addition & 1 deletion rules/aep0004/resource_variables_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func TestResourceVariables(t *testing.T) {
{"Valid", "publishers/{publisher}/electronicBooks/{electronic_book}", testutils.Problems{}},
{"ValidWithIdSuffix", "publishers/{publisher_id}/electronicBooks/{electronic_book_id}", testutils.Problems{}},
{"CamelCase", "publishers/{publisher}/electronicBooks/{electronicBook}", testutils.Problems{{
Message: "publishers/{publisher}/electronicBooks/{electronic_book}",
Message: `Variable names in patterns should use snake case, such as "publishers/{publisher}/electronic-books/{electronic_book}".`,
}}},
} {
t.Run(test.name, func(t *testing.T) {
Expand Down
40 changes: 0 additions & 40 deletions rules/internal/utils/casing.go

This file was deleted.

78 changes: 0 additions & 78 deletions rules/internal/utils/casing_test.go

This file was deleted.

Loading