Skip to content

Commit c35c926

Browse files
authored
fix: update linter to support _id in variable names and kebab-case in path (#108)
Fixes #107
1 parent 3c3b820 commit c35c926

8 files changed

+19
-18
lines changed

rules/aep0004/aep0004.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ func getDesiredPattern(pattern string) string {
9191
for _, token := range strings.Split(pattern, "/") {
9292
if strings.HasPrefix(token, "{") && strings.HasSuffix(token, "}") {
9393
varname := token[1 : len(token)-1]
94-
want = append(want, fmt.Sprintf("{%s}", strings.TrimSuffix(strcase.SnakeCase(varname), "_id")))
94+
want = append(want, fmt.Sprintf("{%s}", strcase.SnakeCase(varname)))
9595
} else {
9696
want = append(want, strcase.LowerCamelCase(token))
9797
}

rules/aep0004/resource_definition_variables_test.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,10 @@ func TestResourceDefinitionVariables(t *testing.T) {
2727
problems testutils.Problems
2828
}{
2929
{"Valid", "publishers/{publisher}/electronicBooks/{electronic_book}", testutils.Problems{}},
30+
{"ValidWithIdSuffix", "publishers/{publisher_id}/electronicBooks/{electronic_book_id}", testutils.Problems{}},
3031
{"CamelCase", "publishers/{publisher}/electronicBooks/{electronicBook}", testutils.Problems{{
3132
Message: "publishers/{publisher}/electronicBooks/{electronic_book}",
3233
}}},
33-
{"ID", "publishers/{publisher}/electronicBooks/{electronic_book_id}", testutils.Problems{{
34-
Message: "publishers/{publisher}/electronicBooks/{electronic_book}",
35-
}}},
3634
} {
3735
t.Run(test.name, func(t *testing.T) {
3836
f := testutils.ParseProto3Tmpl(t, `

rules/aep0004/resource_name_components_alternate.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import (
2525
"github.com/jhump/protoreflect/desc"
2626
)
2727

28-
var identifierRegexp = regexp.MustCompile("^{[a-z][-a-z0-9]*[a-z0-9]}$")
28+
var identifierRegexp = regexp.MustCompile("^{[a-z][_a-z0-9-]*[a-z0-9]}$")
2929

3030
var resourceNameComponentsAlternate = &lint.MessageRule{
3131
Name: lint.NewRuleName(4, "resource-name-components-alternate"),

rules/aep0004/resource_name_components_alternate_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ func TestResourceNameComponentsAlternate(t *testing.T) {
2929
{"Valid", "author/{author}/books/{book}", testutils.Problems{}},
3030
{"Valid", "publishers/{publisher}/books/{book}/editions/{book-edition}", testutils.Problems{}},
3131
{"ValidSingleton", "user/{user}/config", testutils.Problems{}},
32+
{"ValidWithIdSuffix", "stores/{store_id}/items/{item_id}", testutils.Problems{}},
3233
{"InvalidDoubleCollection", "author/books/{book}", testutils.Problems{{Message: "must alternate"}}},
3334
{"InvalidDoubleIdentifier", "books/{author}/{book}", testutils.Problems{{Message: "must alternate"}}},
3435
} {

rules/aep0004/resource_variables.go

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,6 @@ func lintResourceVariables(resource *annotations.ResourceDescriptor, desc desc.D
5454
Location: loc,
5555
}}
5656
}
57-
if strings.HasSuffix(variable, "_id") {
58-
return []lint.Problem{{
59-
Message: fmt.Sprintf(
60-
"Variable names should omit the `_id` suffix, such as %q.",
61-
getDesiredPattern(pattern),
62-
),
63-
Descriptor: desc,
64-
Location: loc,
65-
}}
66-
}
6757
}
6858
}
6959
return nil

rules/aep0004/resource_variables_test.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,10 @@ func TestResourceVariables(t *testing.T) {
2727
problems testutils.Problems
2828
}{
2929
{"Valid", "publishers/{publisher}/electronicBooks/{electronic_book}", testutils.Problems{}},
30+
{"ValidWithIdSuffix", "publishers/{publisher_id}/electronicBooks/{electronic_book_id}", testutils.Problems{}},
3031
{"CamelCase", "publishers/{publisher}/electronicBooks/{electronicBook}", testutils.Problems{{
3132
Message: "publishers/{publisher}/electronicBooks/{electronic_book}",
3233
}}},
33-
{"ID", "publishers/{publisher}/electronicBooks/{electronic_book_id}", testutils.Problems{{
34-
Message: "publishers/{publisher}/electronicBooks/{electronic_book}",
35-
}}},
3634
} {
3735
t.Run(test.name, func(t *testing.T) {
3836
f := testutils.ParseProto3Tmpl(t, `

rules/aep0122/resource_collection_identifiers.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,18 @@ var resourceCollectionIdentifiers = &lint.MessageRule{
4545

4646
segs := strings.Split(p, "/")
4747
for _, seg := range segs {
48+
if strings.HasPrefix(seg, "{") && strings.HasSuffix(seg, "}") {
49+
// Variable segments can contain underscores, but must be lowercase
50+
varName := seg[1 : len(seg)-1] // Remove { and }
51+
if HasUpper(varName) {
52+
problems = append(problems, lint.Problem{
53+
Message: "Resource pattern variables must be lowercase.",
54+
Descriptor: m,
55+
Location: locations.MessageResource(m),
56+
})
57+
}
58+
continue
59+
}
4860
if HasUpper(seg) || strings.Contains(seg, "_") {
4961
problems = append(problems, lint.Problem{
5062
Message: "Resource patterns must use kebab-case for collection identifiers.",

rules/aep0122/resource_collection_identifiers_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ func TestResourceCollectionIdentifiers(t *testing.T) {
2727
problems testutils.Problems
2828
}{
2929
{"Valid", "author/{author}/books/{book}", testutils.Problems{}},
30+
{"ValidWithIdSuffix", "stores/{store_id}/items/{item_id}", testutils.Problems{}},
31+
{"InvalidCapitalIdSuffix", "stores/{Store_id}/items/{item_id}", testutils.Problems{{Message: "lowercase"}}},
3032
{"InvalidUpperCase", "author/{author}/Books/{book}", testutils.Problems{{Message: "kebab-case"}}},
3133
{"InvalidStartsWithSlash", "/author/{author}/Books/{book}", testutils.Problems{{Message: "lowercase letter"}}},
3234
{"InvalidStartsWithCapitalLetter", "Author/{author}/Books/{book}", testutils.Problems{{Message: "lowercase letter"}}},

0 commit comments

Comments
 (0)