Skip to content

Commit

Permalink
add tags to rules and the "checks" cmd (#586)
Browse files Browse the repository at this point in the history
  • Loading branch information
reuvenharrison authored Jul 20, 2024
1 parent 6e06613 commit d2e44ea
Show file tree
Hide file tree
Showing 6 changed files with 449 additions and 288 deletions.
585 changes: 314 additions & 271 deletions checker/rules.go

Large diffs are not rendered by default.

20 changes: 5 additions & 15 deletions internal/checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"
"io"
"sort"
"strings"

"github.com/spf13/cobra"
"github.com/tufin/oasdiff/checker"
Expand Down Expand Up @@ -46,8 +45,8 @@ func getChecksCmd() *cobra.Command {

enumWithOptions(&cmd, newEnumValue(localizations.GetSupportedLanguages(), localizations.LangDefault, &flags.lang), "lang", "l", "language for localized output")
enumWithOptions(&cmd, newEnumValue(formatters.SupportedFormatsByContentType(formatters.OutputChecks), string(formatters.FormatText), &flags.format), "format", "f", "output format")
enumWithOptions(&cmd, newEnumSliceValue([]string{"info", "warn", "error"}, nil, &flags.severity), "severity", "s", "list of severities to include (experimental)")
cmd.PersistentFlags().StringSliceVarP(&flags.tags, "tags", "t", []string{}, "list of tags to include, eg. parameter, request (experimental)")
enumWithOptions(&cmd, newEnumSliceValue([]string{"info", "warn", "error"}, nil, &flags.severity), "severity", "s", "include only checks with any of specified severities")
enumWithOptions(&cmd, newEnumSliceValue(getAllTags(), nil, &flags.tags), "tags", "t", "include only checks with all specified tags")

return &cmd
}
Expand Down Expand Up @@ -81,18 +80,9 @@ func outputChecks(stdout io.Writer, flags ChecksFlags, rules []checker.BackwardC
}
}

// tags (experimental, the string contains approach is not very robust)
if len(flags.tags) > 0 {
match := false
for _, tag := range flags.tags {
if strings.Contains(rule.Id, tag) {
match = true
}
}

if !match {
continue
}
// tags
if !matchTags(flags.tags, rule) {
continue
}

checks = append(checks, formatters.Check{
Expand Down
1 change: 0 additions & 1 deletion internal/enum_slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ func (s *enumSliceValue) checkAllowedValues(values []string) error {
if len(notAllowed) == 1 {
verb = "is"
}
// TODO: find a better way to document the options
return fmt.Errorf("%s %s not one of the allowed values: %s", strings.Join(notAllowed.ToStringList(), ","), verb, s.listOf())
}
return nil
Expand Down
2 changes: 1 addition & 1 deletion internal/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ func Test_FlattenCmdInvalid(t *testing.T) {
}

func Test_Checks(t *testing.T) {
require.Zero(t, internal.Run(cmdToArgs("oasdiff checks -l ru"), io.Discard, io.Discard))
require.Zero(t, internal.Run(cmdToArgs("oasdiff checks -l ru --tags decrease,parameters --severity info,warn,error"), io.Discard, io.Discard))
}

func Test_Color(t *testing.T) {
Expand Down
91 changes: 91 additions & 0 deletions internal/tags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package internal

import "github.com/tufin/oasdiff/checker"

func getAllTags() []string {
return []string{"request", "response", "add", "remove", "change", "generalize", "specialize", "increase", "decrease", "set", "body", "parameters", "properties", "headers", "security", "components"}
}

// matchTags returns true if the rule matches all the tags
func matchTags(tags []string, rule checker.BackwardCompatibilityRule) bool {
if len(tags) == 0 {
return true
}

for _, tag := range tags {
if !matchTag(tag, rule) {
return false
}
}

return true
}

func matchTag(tag string, rule checker.BackwardCompatibilityRule) bool {
if matchLocationTag(tag, rule.Location) {
return true
}

if matchActionTag(tag, rule.Action) {
return true
}

if matchDirectionTag(tag, rule.Direction) {
return true
}

return false
}

func matchDirectionTag(tag string, direction checker.Direction) bool {
switch tag {
case "request":
return direction == checker.DirectionRequest
case "response":
return direction == checker.DirectionResponse
}

return false
}

func matchActionTag(tag string, action checker.Action) bool {
switch tag {
case "add":
return action == checker.ActionAdd
case "remove":
return action == checker.ActionRemove
case "change":
return action == checker.ActionChange
case "generalize":
return action == checker.ActionGeneralize
case "specialize":
return action == checker.ActionSpecialize
case "increase":
return action == checker.ActionIncrease
case "decrease":
return action == checker.ActionDecrease
case "set":
return action == checker.ActionSet
}

return false
}

func matchLocationTag(tag string, location checker.Location) bool {
switch tag {
case "body":
return location == checker.LocationBody
case "parameters":
return location == checker.LocationParameters
case "properties":
return location == checker.LocationProperties
case "headers":
return location == checker.LocationHeaders
case "security":
return location == checker.LocationSecurity
case "components":
return location == checker.LocationComponents
}

return false
}
38 changes: 38 additions & 0 deletions internal/tags_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package internal_test

import (
"io"
"testing"

"github.com/stretchr/testify/require"
"github.com/tufin/oasdiff/internal"
)

func Test_ChecksNoTags(t *testing.T) {
require.Zero(t, internal.Run(cmdToArgs("oasdiff checks -l ru"), io.Discard, io.Discard))
}

func Test_ChecksTagsDirection(t *testing.T) {
require.Zero(t, internal.Run(cmdToArgs("oasdiff checks -l ru --tags request"), io.Discard, io.Discard))
require.Zero(t, internal.Run(cmdToArgs("oasdiff checks -l ru --tags response"), io.Discard, io.Discard))
}

func Test_ChecksTagsAction(t *testing.T) {
require.Zero(t, internal.Run(cmdToArgs("oasdiff checks -l ru --tags add"), io.Discard, io.Discard))
require.Zero(t, internal.Run(cmdToArgs("oasdiff checks -l ru --tags remove"), io.Discard, io.Discard))
require.Zero(t, internal.Run(cmdToArgs("oasdiff checks -l ru --tags change"), io.Discard, io.Discard))
require.Zero(t, internal.Run(cmdToArgs("oasdiff checks -l ru --tags generalize"), io.Discard, io.Discard))
require.Zero(t, internal.Run(cmdToArgs("oasdiff checks -l ru --tags specialize"), io.Discard, io.Discard))
require.Zero(t, internal.Run(cmdToArgs("oasdiff checks -l ru --tags increase"), io.Discard, io.Discard))
require.Zero(t, internal.Run(cmdToArgs("oasdiff checks -l ru --tags decrease"), io.Discard, io.Discard))
require.Zero(t, internal.Run(cmdToArgs("oasdiff checks -l ru --tags set"), io.Discard, io.Discard))
}

func Test_ChecksTagsLocation(t *testing.T) {
require.Zero(t, internal.Run(cmdToArgs("oasdiff checks -l ru --tags body"), io.Discard, io.Discard))
require.Zero(t, internal.Run(cmdToArgs("oasdiff checks -l ru --tags parameters"), io.Discard, io.Discard))
require.Zero(t, internal.Run(cmdToArgs("oasdiff checks -l ru --tags properties"), io.Discard, io.Discard))
require.Zero(t, internal.Run(cmdToArgs("oasdiff checks -l ru --tags headers"), io.Discard, io.Discard))
require.Zero(t, internal.Run(cmdToArgs("oasdiff checks -l ru --tags security"), io.Discard, io.Discard))
require.Zero(t, internal.Run(cmdToArgs("oasdiff checks -l ru --tags components"), io.Discard, io.Discard))
}

0 comments on commit d2e44ea

Please sign in to comment.