Skip to content
This repository has been archived by the owner on Jul 29, 2024. It is now read-only.

Commit

Permalink
Add path and ignore path pattern filters (#57)
Browse files Browse the repository at this point in the history
Close #16
  • Loading branch information
samcontesse committed Feb 13, 2022
1 parent ec12954 commit 8a865c6
Show file tree
Hide file tree
Showing 5 changed files with 237 additions and 0 deletions.
40 changes: 40 additions & 0 deletions pkg/check/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ func (command *Command) Run(request Request) (Response, error) {
continue
}

match, err := matchPathPatterns(command.client, mr, request.Source)
if err != nil {
return nil, err
}

if !match {
continue
}

target := request.Source.GetTargetURL()
name := request.Source.GetPipelineName()

Expand All @@ -91,6 +100,37 @@ func (command *Command) Run(request Request) (Response, error) {
return versions, nil
}

func matchPathPatterns(api *gitlab.Client, mr *gitlab.MergeRequest, source pkg.Source) (bool, error) {

if len(source.Paths) == 0 && len(source.IgnorePaths) == 0 {
return true, nil
}

modified := 0

versions, _, err := api.MergeRequests.GetMergeRequestDiffVersions(mr.ProjectID, mr.IID, nil)
if err != nil {
return false, err
}

if len(versions) > 0 {

latest := versions[0].ID
version, _, err := api.MergeRequests.GetSingleMergeRequestDiffVersion(mr.ProjectID, mr.IID, latest)
if err != nil {
return false, err
}

for _, d := range version.Diffs {
if source.AcceptPath(d.OldPath) || source.AcceptPath(d.NewPath) {
modified += 1
}
}
}

return modified > 0, nil
}

func getMostRecentUpdateTime(notes []*gitlab.Note, updatedAt *time.Time) *time.Time {
for _, note := range notes {
if strings.Contains(note.Body, "[trigger ci]") && updatedAt.Before(*note.UpdatedAt) {
Expand Down
11 changes: 11 additions & 0 deletions pkg/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"net/http"
"os"
"path/filepath"
)

func Fatal(doing string, err error) {
Expand All @@ -16,3 +17,13 @@ func GetDefaultClient(insecure bool) *http.Client {
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: insecure}
return http.DefaultClient
}

func matchPath(patterns []string, path string) bool {
for _, pattern := range patterns {
ok, _ := filepath.Match(pattern, path)
if ok {
return true
}
}
return false
}
18 changes: 18 additions & 0 deletions pkg/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ type Source struct {
Labels []string `json:"labels,omitempty"`
TargetBranch string `json:"target_branch,omitempty"`
Sort string `json:"sort,omitempty"`
Paths []string `json:"paths,omitempty"`
IgnorePaths []string `json:"ignore_paths,omitempty"`
}

type Version struct {
Expand Down Expand Up @@ -84,3 +86,19 @@ func (source *Source) GetSort() (string, error) {
}
return "", fmt.Errorf("invalid value for sort: %v", source.Sort)
}

func (source *Source) AcceptPath(path string) bool {

excluded := len(source.IgnorePaths) > 0
included := len(source.Paths) == 0

if excluded {
excluded = matchPath(source.IgnorePaths, path)
}

if len(source.Paths) > 0 {
included = matchPath(source.Paths, path)
}

return !excluded && included
}
155 changes: 155 additions & 0 deletions pkg/models_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,158 @@ func TestSource_GetSort(t *testing.T) {
})
}
}

func TestSource_GetProjectPath_WithNamespace(t *testing.T) {
source := Source{
URI: "https://git.example.com/namespace/project.git",
}

actual := source.GetProjectPath()
expected := "namespace/project"

if actual != expected {
t.Errorf("Project path %s expected to be %s", actual, expected)
}
}

func TestSource_GetProjectPath_WithSubgroup(t *testing.T) {
source := Source{
URI: "https://git.example.com/group/subgroup1/subgroup2/project.git",
}

actual := source.GetProjectPath()
expected := "group/subgroup1/subgroup2/project"

if actual != expected {
t.Errorf("Project path %s expected to be %s", actual, expected)
}
}

func TestSource_GetProjectPath_WithoutNamespace(t *testing.T) {
source := Source{
URI: "https://git.example.com/project.git",
}

actual := source.GetProjectPath()
expected := "project"

if actual != expected {
t.Errorf("Project path %s expected to be %s", actual, expected)
}
}

func TestSource_AcceptPath(t *testing.T) {
type fields struct {
Paths []string
IgnorePaths []string
}
type args struct {
path string
}
tests := []struct {
name string
fields fields
args args
want bool
}{
{
name: "match with no include and no exclude",
fields: fields{
Paths: nil,
IgnorePaths: nil,
},
args: args{
path: "Makefile",
},
want: true,
},
{
name: "match with include and no exclude",
fields: fields{
Paths: []string{"Makefile"},
IgnorePaths: nil,
},
args: args{
path: "Makefile",
},
want: true,
},
{
name: "match with glob include and no exclude",
fields: fields{
Paths: []string{"**/README.md"},
IgnorePaths: nil,
},
args: args{
path: "README.md",
},
want: false,
},
{
name: "match with include pattern and no exclude",
fields: fields{
Paths: []string{"Make*"},
IgnorePaths: nil,
},
args: args{
path: "Makefile",
},
want: true,
},
{
name: "no match with include pattern and no exclude",
fields: fields{
Paths: []string{"Other*"},
IgnorePaths: nil,
},
args: args{
path: "Makefile",
},
want: false,
},
{
name: "no match with include pattern and exclude pattern",
fields: fields{
Paths: []string{"Make*"},
IgnorePaths: []string{"Makefi??"},
},
args: args{
path: "Makefile",
},
want: false,
},
{
name: "no match with include and no exclude",
fields: fields{
Paths: []string{"Makefile"},
IgnorePaths: nil,
},
args: args{
path: "Other",
},
want: false,
},
{
name: "no match with include and exclude",
fields: fields{
Paths: []string{"Makefile"},
IgnorePaths: []string{"Makefile"},
},
args: args{
path: "Makefile",
},
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
source := &Source{
Paths: tt.fields.Paths,
IgnorePaths: tt.fields.IgnorePaths,
}
if got := source.AcceptPath(tt.args.path); got != tt.want {
t.Errorf("AcceptPath() = %v, want %v", got, tt.want)
}
})
}
}
13 changes: 13 additions & 0 deletions util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package resource

import "path/filepath"

func matchPath(patterns []string, path string) bool {
for _, pattern := range patterns {
ok, _ := filepath.Match(pattern, path)
if ok {
return true
}
}
return false
}

0 comments on commit 8a865c6

Please sign in to comment.