Skip to content

Commit

Permalink
fix: exclude etag from field_behavior lints (#1009)
Browse files Browse the repository at this point in the history
  • Loading branch information
noahdietz authored Sep 7, 2022
1 parent 8be4f1a commit b521af0
Show file tree
Hide file tree
Showing 11 changed files with 52 additions and 5 deletions.
5 changes: 4 additions & 1 deletion rules/aip0203/aip0203.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ import (
"fmt"
"regexp"

"bitbucket.org/creachadair/stringset"
"github.com/googleapis/api-linter/lint"
"github.com/googleapis/api-linter/rules/internal/utils"
"github.com/jhump/protoreflect/desc"
)

var standardFields = stringset.New("etag")

// AddRules adds all of the AIP-203 rules to the provided registry.
func AddRules(r lint.RuleRegistry) error {
return r.Register(
Expand Down Expand Up @@ -61,5 +64,5 @@ func checkLeadingComments(pattern *regexp.Regexp, annotation string, unless ...*
}

func withoutFieldBehavior(f *desc.FieldDescriptor) bool {
return utils.GetFieldBehavior(f).Len() == 0
return utils.GetFieldBehavior(f).Len() == 0 && !standardFields.Contains(f.GetName())
}
2 changes: 1 addition & 1 deletion rules/aip0203/immutable.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,5 @@ var immutable = &lint.FieldRule{
var immutableRegexp = regexp.MustCompile("(?i).*immutable.*")

func withoutImmutableFieldBehavior(f *desc.FieldDescriptor) bool {
return !utils.GetFieldBehavior(f).Contains("IMMUTABLE")
return !utils.GetFieldBehavior(f).Contains("IMMUTABLE") && !standardFields.Contains(f.GetName())
}
6 changes: 6 additions & 0 deletions rules/aip0203/immutable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ func TestImmutable(t *testing.T) {
field: fieldPartWithImmtutableBehavior,
problems: nil,
},
{
name: "Valid-exclude-etag",
comment: "Immutable.",
field: "string etag = 1;",
problems: nil,
},
{
name: "Invalid-immutable",
comment: "immutable",
Expand Down
2 changes: 1 addition & 1 deletion rules/aip0203/input_only.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,5 @@ var inputOnly = &lint.FieldRule{
var inputOnlyRegexp = regexp.MustCompile("(?i).*input.?only.*")

func withoutInputOnlyFieldBehavior(f *desc.FieldDescriptor) bool {
return !utils.GetFieldBehavior(f).Contains("INPUT_ONLY")
return !utils.GetFieldBehavior(f).Contains("INPUT_ONLY") && !standardFields.Contains(f.GetName())
}
6 changes: 6 additions & 0 deletions rules/aip0203/input_only_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ func TestInputOnly(t *testing.T) {
field: "string secret = 1 [(google.api.field_behavior) = INPUT_ONLY];",
problems: nil,
},
{
name: "valid_exclude_etag",
comment: "Input only.",
field: "string etag = 1;",
problems: nil,
},
{
name: "input_only",
comment: "input_only",
Expand Down
2 changes: 1 addition & 1 deletion rules/aip0203/optional_consistency.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ var optionalBehaviorConsistency = &lint.MessageRule{
OnlyIf: messageHasOptionalFieldBehavior,
LintMessage: func(m *desc.MessageDescriptor) (problems []lint.Problem) {
for _, f := range m.GetFields() {
if utils.GetFieldBehavior(f).Len() == 0 && f.GetOneOf() == nil {
if utils.GetFieldBehavior(f).Len() == 0 && !standardFields.Contains(f.GetName()) && f.GetOneOf() == nil {
problems = append(problems, lint.Problem{
Message: "Within a single message, either all optional fields should be indicated, or none of them should be.",
Descriptor: f,
Expand Down
14 changes: 14 additions & 0 deletions rules/aip0203/optional_consistency_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,20 @@ oneof other {
}`,
problems: nil,
},
{
name: "Valid-IgnoreEtag",
field: `
string name = 1 [
(google.api.field_behavior) = IMMUTABLE,
(google.api.field_behavior) = OUTPUT_ONLY];
string title = 2 [(google.api.field_behavior) = REQUIRED];
string summary = 3 [(google.api.field_behavior) = OPTIONAL];
string etag = 4;`,
problems: nil,
},
}

for _, test := range testCases {
Expand Down
6 changes: 6 additions & 0 deletions rules/aip0203/optional_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ func TestOptional(t *testing.T) {
field: titleWithOptionalBehavior,
problems: nil,
},
{
name: "Valid-exclude-etag",
comment: "Optional.",
field: "string etag = 1;",
problems: nil,
},
{
name: "Invalid-optional",
comment: "optional",
Expand Down
2 changes: 1 addition & 1 deletion rules/aip0203/output_only.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,5 @@ var outputOnly = &lint.FieldRule{
var outputOnlyRegexp = regexp.MustCompile("(?i).*output.?only.*")

func withoutOutputOnlyFieldBehavior(f *desc.FieldDescriptor) bool {
return !utils.GetFieldBehavior(f).Contains("OUTPUT_ONLY")
return !utils.GetFieldBehavior(f).Contains("OUTPUT_ONLY") && !standardFields.Contains(f.GetName())
}
6 changes: 6 additions & 0 deletions rules/aip0203/output_only_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ func TestOutput(t *testing.T) {
field: generatedURIWithOutputOnlyBehavior,
problems: nil,
},
{
name: "Valid-exclude-etag",
comment: "Output Only.",
field: "string etag = 1;",
problems: nil,
},
{
name: "Invalid-Output Only",
comment: "Output Only",
Expand Down
6 changes: 6 additions & 0 deletions rules/aip0203/required_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ func TestRequired(t *testing.T) {
field: title,
problems: nil,
},
{
name: "Valid-exclude-etag",
comment: "Required",
field: "string etag = 1;",
problems: nil,
},
{
name: "Invalid-required",
comment: "required",
Expand Down

0 comments on commit b521af0

Please sign in to comment.