Browse Source

refactor(allowlist): deduplicate commits & keywords (#1596)

Richard Gomez 1 year ago
parent
commit
8cf93b9ad5
3 changed files with 81 additions and 1 deletions
  1. 19 0
      config/allowlist.go
  2. 62 0
      config/allowlist_test.go
  3. 0 1
      config/config_test.go

+ 19 - 0
config/allowlist.go

@@ -4,6 +4,8 @@ import (
 	"fmt"
 	"regexp"
 	"strings"
+
+	"golang.org/x/exp/maps"
 )
 
 type AllowlistMatchCondition int
@@ -95,5 +97,22 @@ func (a *Allowlist) Validate() error {
 		return fmt.Errorf("[[rules.allowlists]] must contain at least one check for: commits, paths, regexes, or stopwords")
 	}
 
+	// Deduplicate commits and stopwords.
+	if len(a.Commits) > 0 {
+		uniqueCommits := make(map[string]struct{})
+		for _, commit := range a.Commits {
+			uniqueCommits[commit] = struct{}{}
+		}
+		a.Commits = maps.Keys(uniqueCommits)
+	}
+
+	if len(a.StopWords) > 0 {
+		uniqueStopwords := make(map[string]struct{})
+		for _, stopWord := range a.StopWords {
+			uniqueStopwords[stopWord] = struct{}{}
+		}
+		a.StopWords = maps.Keys(uniqueStopwords)
+	}
+
 	return nil
 }

+ 62 - 0
config/allowlist_test.go

@@ -1,9 +1,12 @@
 package config
 
 import (
+	"errors"
 	"regexp"
 	"testing"
 
+	"github.com/google/go-cmp/cmp"
+	"github.com/google/go-cmp/cmp/cmpopts"
 	"github.com/stretchr/testify/assert"
 )
 
@@ -91,3 +94,62 @@ func TestPathAllowed(t *testing.T) {
 		assert.Equal(t, tt.pathAllowed, tt.allowlist.PathAllowed(tt.path))
 	}
 }
+
+func TestValidate(t *testing.T) {
+	tests := map[string]struct {
+		input    Allowlist
+		expected Allowlist
+		wantErr  error
+	}{
+		"empty conditions": {
+			input:   Allowlist{},
+			wantErr: errors.New("[[rules.allowlists]] must contain at least one check for: commits, paths, regexes, or stopwords"),
+		},
+		"deduplicated commits and stopwords": {
+			input: Allowlist{
+				Commits:   []string{"commitA", "commitB", "commitA"},
+				StopWords: []string{"stopwordA", "stopwordB", "stopwordA"},
+			},
+			expected: Allowlist{
+				Commits:   []string{"commitA", "commitB"},
+				StopWords: []string{"stopwordA", "stopwordB"},
+			},
+		},
+	}
+
+	for _, tt := range tests {
+		// Expected an error.
+		err := tt.input.Validate()
+		if err != nil {
+			if tt.wantErr == nil {
+				t.Fatalf("Received unexpected error: %v", err)
+			} else if !assert.EqualError(t, err, tt.wantErr.Error()) {
+				t.Fatalf("Received unexpected error, expected '%v', got '%v'", tt.wantErr, err)
+			}
+		} else {
+			if tt.wantErr != nil {
+				t.Fatalf("Did not receive expected error: %v", tt.wantErr)
+			}
+		}
+
+		var (
+			regexComparer = func(x, y *regexp.Regexp) bool {
+				// Compare the string representation of the regex patterns.
+				if x == nil || y == nil {
+					return x == y
+				}
+				return x.String() == y.String()
+			}
+			arrayComparer = func(a, b string) bool {
+				return a < b
+			}
+			opts = cmp.Options{
+				cmp.Comparer(regexComparer),
+				cmpopts.SortSlices(arrayComparer),
+			}
+		)
+		if diff := cmp.Diff(tt.input, tt.expected, opts); diff != "" {
+			t.Errorf("diff: (-want +got)\n%s", diff)
+		}
+	}
+}

+ 0 - 1
config/config_test.go

@@ -381,7 +381,6 @@ func TestTranslate(t *testing.T) {
 			}
 
 			var regexComparer = func(x, y *regexp.Regexp) bool {
-				// Compare the string representation of the regex patterns.
 				if x == nil || y == nil {
 					return x == y
 				}