-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into gitlab_provider
- Loading branch information
Showing
5 changed files
with
251 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package rules | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/qonto/standards-insights/config" | ||
"github.com/qonto/standards-insights/pkg/project" | ||
) | ||
|
||
type ProjectRule struct { | ||
config config.ProjectRule | ||
} | ||
|
||
func NewProjectRule(config config.ProjectRule) *ProjectRule { | ||
return &ProjectRule{ | ||
config: config, | ||
} | ||
} | ||
|
||
func (rule *ProjectRule) Do(ctx context.Context, project project.Project) error { | ||
match := true | ||
if rule.config.Match != nil { | ||
match = *rule.config.Match | ||
} | ||
|
||
if len(rule.config.Names) > 0 { | ||
if match && !contains(project.Name, rule.config.Names) { | ||
return fmt.Errorf("project name %s is not in %v", project.Name, rule.config.Names) | ||
} | ||
if !match && contains(project.Name, rule.config.Names) { | ||
return fmt.Errorf("project name %s is matching one of %v", project.Name, rule.config.Names) | ||
} | ||
} | ||
|
||
if len(rule.config.Labels) > 0 { | ||
if match && !isSubset(rule.config.Labels, project.Labels) { | ||
return fmt.Errorf("project labels %v does not contain %v", project.Labels, rule.config.Labels) | ||
} | ||
if !match && isSubset(rule.config.Labels, project.Labels) { | ||
return fmt.Errorf("project labels %v contain %v", project.Labels, rule.config.Labels) | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func isSubset(a, b map[string]string) bool { | ||
if len(a) > len(b) { | ||
return false | ||
} | ||
for k, vsub := range a { | ||
if vm, found := b[k]; !found || vm != vsub { | ||
return false | ||
} | ||
} | ||
return true | ||
} | ||
|
||
func contains(s string, slice []string) bool { | ||
for _, v := range slice { | ||
if s == v { | ||
return true | ||
} | ||
} | ||
return false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
package rules | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"testing" | ||
|
||
"github.com/qonto/standards-insights/config" | ||
"github.com/qonto/standards-insights/pkg/project" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestProjectRule_Do(t *testing.T) { | ||
f := false | ||
tests := []struct { | ||
name string | ||
config config.ProjectRule | ||
project project.Project | ||
wantErr error | ||
}{ | ||
{ | ||
name: "empty rule should pass", | ||
config: config.ProjectRule{}, | ||
project: project.Project{Name: "a", Labels: map[string]string{"a": "b"}}, | ||
wantErr: nil, | ||
}, | ||
{ | ||
name: "project name list match", | ||
config: config.ProjectRule{ | ||
Names: []string{"a", "b", "c"}, | ||
}, | ||
project: project.Project{Name: "b"}, | ||
wantErr: nil, | ||
}, | ||
{ | ||
name: "project name does not match list", | ||
config: config.ProjectRule{ | ||
Names: []string{"a", "b", "c"}, | ||
}, | ||
project: project.Project{Name: "f"}, | ||
wantErr: errors.New("project name f is not in [a b c]"), | ||
}, | ||
{ | ||
name: "project name matches list and should not", | ||
config: config.ProjectRule{ | ||
Names: []string{"a", "b", "c"}, | ||
Match: &f, | ||
}, | ||
project: project.Project{Name: "a"}, | ||
wantErr: errors.New("project name a is matching one of [a b c]"), | ||
}, | ||
{ | ||
name: "project name does not match list and should not", | ||
config: config.ProjectRule{ | ||
Names: []string{"a", "b", "c"}, | ||
Match: &f, | ||
}, | ||
project: project.Project{Name: "e"}, | ||
wantErr: nil, | ||
}, | ||
|
||
{ | ||
name: "project labels full match", | ||
config: config.ProjectRule{ | ||
Labels: map[string]string{ | ||
"a": "b", | ||
"e": "f", | ||
}, | ||
}, | ||
project: project.Project{Labels: map[string]string{ | ||
"a": "b", | ||
"c": "d", | ||
"e": "f", | ||
}}, | ||
wantErr: nil, | ||
}, | ||
{ | ||
name: "project labels not matching", | ||
config: config.ProjectRule{ | ||
Labels: map[string]string{ | ||
"a": "b", | ||
"e": "f", | ||
}, | ||
}, | ||
project: project.Project{Labels: map[string]string{ | ||
"a": "b", | ||
"c": "d", | ||
"g": "h", | ||
}}, | ||
wantErr: errors.New("project labels map[a:b c:d g:h] does not contain map[a:b e:f]"), | ||
}, | ||
{ | ||
name: "project labels should not match", | ||
config: config.ProjectRule{ | ||
Labels: map[string]string{ | ||
"a": "b", | ||
"e": "f", | ||
}, | ||
Match: &f, | ||
}, | ||
project: project.Project{Labels: map[string]string{ | ||
"a": "b", | ||
"c": "d", | ||
"e": "f", | ||
}}, | ||
wantErr: errors.New("project labels map[a:b c:d e:f] contain map[a:b e:f]"), | ||
}, | ||
{ | ||
name: "project labels should not match and don't match", | ||
config: config.ProjectRule{ | ||
Labels: map[string]string{ | ||
"a": "b", | ||
"e": "h", | ||
}, | ||
Match: &f, | ||
}, | ||
project: project.Project{Labels: map[string]string{ | ||
"a": "b", | ||
"c": "d", | ||
"e": "f", | ||
}}, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
rule := NewProjectRule(tt.config) | ||
|
||
err := rule.Do(context.Background(), tt.project) | ||
assert.Equal(t, tt.wantErr, err) | ||
}) | ||
} | ||
} |