From 70eeddb7194380f2953a46b0e561e7b652e07f60 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Thu, 5 Sep 2019 09:29:20 +0200 Subject: [PATCH] types: use a global When type Currently we are using different `When` types for every service and convert between them. This is a good approach if we want to keep isolated all the services (like if we were using different repos for every service instead of the current monorepo). But currently, since When is identical between all the services, simplify this by using a common When type. --- cmd/agola/cmd/projectvariablecreate.go | 36 +---- cmd/agola/cmd/projectvariableupdate.go | 2 +- internal/config/config.go | 30 ++-- internal/config/config_test.go | 2 +- internal/runconfig/runconfig.go | 4 +- internal/runconfig/runconfig_test.go | 12 +- internal/services/gateway/action/run.go | 27 ++-- internal/services/gateway/api/variable.go | 70 +-------- services/configstore/types/types.go | 86 +---------- services/configstore/types/types_test.go | 180 +++++++++++----------- services/gateway/api/types/variable.go | 8 +- services/gateway/api/types/when.go | 38 ----- services/types/when.go | 101 ++++++++++++ 13 files changed, 238 insertions(+), 358 deletions(-) delete mode 100644 services/gateway/api/types/when.go create mode 100644 services/types/when.go diff --git a/cmd/agola/cmd/projectvariablecreate.go b/cmd/agola/cmd/projectvariablecreate.go index 666c050..ed69b3a 100644 --- a/cmd/agola/cmd/projectvariablecreate.go +++ b/cmd/agola/cmd/projectvariablecreate.go @@ -20,7 +20,6 @@ import ( "os" config "agola.io/agola/internal/config" - cstypes "agola.io/agola/services/configstore/types" gwapitypes "agola.io/agola/services/gateway/api/types" gwclient "agola.io/agola/services/gateway/client" @@ -123,7 +122,7 @@ func variableCreate(cmd *cobra.Command, ownertype string, args []string) error { rvalues = append(rvalues, gwapitypes.VariableValueRequest{ SecretName: value.SecretName, SecretVar: value.SecretVar, - When: fromCsWhen(value.When.ToCSWhen()), + When: value.When.ToWhen(), }) } req := &gwapitypes.CreateVariableRequest{ @@ -150,36 +149,3 @@ func variableCreate(cmd *cobra.Command, ownertype string, args []string) error { return nil } - -func fromCsWhenCondition(apiwc cstypes.WhenCondition) gwapitypes.WhenCondition { - return gwapitypes.WhenCondition{ - Type: gwapitypes.WhenConditionType(apiwc.Type), - Match: apiwc.Match, - } -} - -func fromCsWhenConditions(apiwcs *cstypes.WhenConditions) *gwapitypes.WhenConditions { - if apiwcs == nil { - return nil - } - wcs := &gwapitypes.WhenConditions{ - Include: make([]gwapitypes.WhenCondition, len(apiwcs.Include)), - Exclude: make([]gwapitypes.WhenCondition, len(apiwcs.Exclude)), - } - for i, include := range apiwcs.Include { - wcs.Include[i] = fromCsWhenCondition(include) - } - for i, exclude := range apiwcs.Exclude { - wcs.Exclude[i] = fromCsWhenCondition(exclude) - } - - return wcs -} - -func fromCsWhen(apiwhen *cstypes.When) *gwapitypes.When { - return &gwapitypes.When{ - Branch: fromCsWhenConditions(apiwhen.Branch), - Tag: fromCsWhenConditions(apiwhen.Tag), - Ref: fromCsWhenConditions(apiwhen.Ref), - } -} diff --git a/cmd/agola/cmd/projectvariableupdate.go b/cmd/agola/cmd/projectvariableupdate.go index fb2b6ca..c9d3f93 100644 --- a/cmd/agola/cmd/projectvariableupdate.go +++ b/cmd/agola/cmd/projectvariableupdate.go @@ -94,7 +94,7 @@ func variableUpdate(cmd *cobra.Command, ownertype string, args []string) error { rvalues = append(rvalues, gwapitypes.VariableValueRequest{ SecretName: value.SecretName, SecretVar: value.SecretVar, - When: fromCsWhen(value.When.ToCSWhen()), + When: value.When.ToWhen(), }) } req := &gwapitypes.UpdateVariableRequest{ diff --git a/internal/config/config.go b/internal/config/config.go index 3bb34b2..d9012c6 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -21,7 +21,6 @@ import ( "strings" "agola.io/agola/internal/util" - cstypes "agola.io/agola/services/configstore/types" "agola.io/agola/services/types" "github.com/ghodss/yaml" @@ -446,7 +445,7 @@ func (val *Value) UnmarshalJSON(b []byte) error { return nil } -type When cstypes.When +type When types.When type when struct { Branch interface{} `json:"branch"` @@ -454,15 +453,8 @@ type when struct { Ref interface{} `json:"ref"` } -func (w *When) ToCSWhen() *cstypes.When { - if w == nil { - return nil - } - return &cstypes.When{ - Branch: w.Branch, - Tag: w.Tag, - Ref: w.Ref, - } +func (w *When) ToWhen() *types.When { + return (*types.When)(w) } func (w *When) UnmarshalJSON(b []byte) error { @@ -497,8 +489,8 @@ func (w *When) UnmarshalJSON(b []byte) error { return nil } -func parseWhenConditions(wi interface{}) (*cstypes.WhenConditions, error) { - w := &cstypes.WhenConditions{} +func parseWhenConditions(wi interface{}) (*types.WhenConditions, error) { + w := &types.WhenConditions{} var err error include := []string{} @@ -546,12 +538,12 @@ func parseWhenConditions(wi interface{}) (*cstypes.WhenConditions, error) { return w, nil } -func parseWhenConditionSlice(conds []string) ([]cstypes.WhenCondition, error) { +func parseWhenConditionSlice(conds []string) ([]types.WhenCondition, error) { if len(conds) == 0 { return nil, nil } - wcs := []cstypes.WhenCondition{} + wcs := []types.WhenCondition{} for _, cond := range conds { wc, err := parseWhenCondition(cond) if err != nil { @@ -563,7 +555,7 @@ func parseWhenConditionSlice(conds []string) ([]cstypes.WhenCondition, error) { return wcs, nil } -func parseWhenCondition(s string) (*cstypes.WhenCondition, error) { +func parseWhenCondition(s string) (*types.WhenCondition, error) { isRegExp := false if len(s) > 2 { for _, d := range regExpDelimiters { @@ -575,15 +567,15 @@ func parseWhenCondition(s string) (*cstypes.WhenCondition, error) { } } - wc := &cstypes.WhenCondition{Match: s} + wc := &types.WhenCondition{Match: s} if isRegExp { if _, err := regexp.Compile(s); err != nil { return nil, errors.Errorf("wrong regular expression: %w", err) } - wc.Type = cstypes.WhenConditionTypeRegExp + wc.Type = types.WhenConditionTypeRegExp } else { - wc.Type = cstypes.WhenConditionTypeSimple + wc.Type = types.WhenConditionTypeSimple } return wc, nil } diff --git a/internal/config/config_test.go b/internal/config/config_test.go index a06f4e0..82554e3 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -19,7 +19,7 @@ import ( "testing" "agola.io/agola/internal/util" - "agola.io/agola/services/configstore/types" + "agola.io/agola/services/types" "github.com/google/go-cmp/cmp" errors "golang.org/x/xerrors" diff --git a/internal/runconfig/runconfig.go b/internal/runconfig/runconfig.go index 46fc709..9a6957d 100644 --- a/internal/runconfig/runconfig.go +++ b/internal/runconfig/runconfig.go @@ -20,8 +20,8 @@ import ( "agola.io/agola/internal/config" "agola.io/agola/internal/util" - cstypes "agola.io/agola/services/configstore/types" rstypes "agola.io/agola/services/runservice/types" + "agola.io/agola/services/types" errors "golang.org/x/xerrors" ) @@ -183,7 +183,7 @@ func GenRunConfigTasks(uuid util.UUIDGenerator, c *config.Config, runName string rcts := map[string]*rstypes.RunConfigTask{} for _, ct := range cr.Tasks { - include := cstypes.MatchWhen(ct.When.ToCSWhen(), branch, tag, ref) + include := types.MatchWhen(ct.When.ToWhen(), branch, tag, ref) steps := make(rstypes.Steps, len(ct.Steps)) for i, cpts := range ct.Steps { diff --git a/internal/runconfig/runconfig_test.go b/internal/runconfig/runconfig_test.go index 725be67..92f7bd4 100644 --- a/internal/runconfig/runconfig_test.go +++ b/internal/runconfig/runconfig_test.go @@ -21,8 +21,8 @@ import ( "agola.io/agola/internal/config" "agola.io/agola/internal/util" - cstypes "agola.io/agola/services/configstore/types" rstypes "agola.io/agola/services/runservice/types" + "agola.io/agola/services/types" "github.com/google/go-cmp/cmp" errors "golang.org/x/xerrors" @@ -763,11 +763,11 @@ func TestGenRunConfig(t *testing.T) { IgnoreFailure: false, Approval: false, When: &config.When{ - Branch: &cstypes.WhenConditions{Include: []cstypes.WhenCondition{{Match: "master"}}}, - Tag: &cstypes.WhenConditions{Include: []cstypes.WhenCondition{{Match: "v1.x"}, {Match: "v2.x"}}}, - Ref: &cstypes.WhenConditions{ - Include: []cstypes.WhenCondition{{Match: "master"}}, - Exclude: []cstypes.WhenCondition{{Match: "branch01", Type: cstypes.WhenConditionTypeRegExp}, {Match: "branch02"}}, + Branch: &types.WhenConditions{Include: []types.WhenCondition{{Match: "master"}}}, + Tag: &types.WhenConditions{Include: []types.WhenCondition{{Match: "v1.x"}, {Match: "v2.x"}}}, + Ref: &types.WhenConditions{ + Include: []types.WhenCondition{{Match: "master"}}, + Exclude: []types.WhenCondition{{Match: "branch01", Type: types.WhenConditionTypeRegExp}, {Match: "branch02"}}, }, }, }, diff --git a/internal/services/gateway/action/run.go b/internal/services/gateway/action/run.go index b9ccf84..38ddddb 100644 --- a/internal/services/gateway/action/run.go +++ b/internal/services/gateway/action/run.go @@ -24,11 +24,12 @@ import ( gitsource "agola.io/agola/internal/gitsources" "agola.io/agola/internal/runconfig" "agola.io/agola/internal/services/common" - "agola.io/agola/internal/services/types" + itypes "agola.io/agola/internal/services/types" "agola.io/agola/internal/util" cstypes "agola.io/agola/services/configstore/types" rsapitypes "agola.io/agola/services/runservice/api/types" rstypes "agola.io/agola/services/runservice/types" + "agola.io/agola/services/types" errors "golang.org/x/xerrors" ) @@ -290,9 +291,9 @@ func (h *ActionHandler) RunTaskAction(ctx context.Context, req *RunTaskActionsRe } type CreateRunRequest struct { - RunType types.RunType - RefType types.RunRefType - RunCreationTrigger types.RunCreationTriggerType + RunType itypes.RunType + RefType itypes.RunRefType + RunCreationTrigger itypes.RunCreationTriggerType Project *cstypes.Project User *cstypes.User @@ -341,7 +342,7 @@ func (h *ActionHandler) CreateRuns(ctx context.Context, req *CreateRunRequest) e var groupType common.GroupType var group string - if req.RunType == types.RunTypeProject { + if req.RunType == itypes.RunTypeProject { baseGroupType = common.GroupTypeProject baseGroupID = req.Project.ID } else { @@ -350,13 +351,13 @@ func (h *ActionHandler) CreateRuns(ctx context.Context, req *CreateRunRequest) e } switch req.RefType { - case types.RunRefTypeBranch: + case itypes.RunRefTypeBranch: groupType = common.GroupTypeBranch group = req.Branch - case types.RunRefTypeTag: + case itypes.RunRefTypeTag: groupType = common.GroupTypeTag group = req.Tag - case types.RunRefTypePullRequest: + case itypes.RunRefTypePullRequest: groupType = common.GroupTypePullRequest group = req.PullRequestID } @@ -394,7 +395,7 @@ func (h *ActionHandler) CreateRuns(ctx context.Context, req *CreateRunRequest) e } var variables map[string]string - if req.RunType == types.RunTypeProject { + if req.RunType == itypes.RunTypeProject { var err error variables, err = h.genRunVariables(ctx, req) if err != nil { @@ -417,7 +418,7 @@ func (h *ActionHandler) CreateRuns(ctx context.Context, req *CreateRunRequest) e AnnotationCompareLink: req.CompareLink, } - if req.RunType == types.RunTypeProject { + if req.RunType == itypes.RunTypeProject { annotations[AnnotationProjectID] = req.Project.ID } else { annotations[AnnotationUserID] = req.User.ID @@ -438,7 +439,7 @@ func (h *ActionHandler) CreateRuns(ctx context.Context, req *CreateRunRequest) e // Since user belong to the same group (the user uuid) we needed another way to differentiate the cache. We'll use the user uuid + the user run repo uuid var cacheGroup string - if req.RunType == types.RunTypeUser { + if req.RunType == itypes.RunTypeUser { cacheGroup = req.User.ID + "-" + req.UserRunRepoUUID } @@ -482,7 +483,7 @@ func (h *ActionHandler) CreateRuns(ctx context.Context, req *CreateRunRequest) e } for _, run := range config.Runs { - if match := cstypes.MatchWhen(run.When.ToCSWhen(), req.Branch, req.Tag, req.Ref); !match { + if match := types.MatchWhen(run.When.ToWhen(), req.Branch, req.Tag, req.Ref); !match { h.log.Debugf("skipping run since when condition doesn't match") continue } @@ -549,7 +550,7 @@ func (h *ActionHandler) genRunVariables(ctx context.Context, req *CreateRunReque // find the value match var varval cstypes.VariableValue for _, varval = range pvar.Values { - match := cstypes.MatchWhen(varval.When, req.Branch, req.Tag, req.Ref) + match := types.MatchWhen(varval.When, req.Branch, req.Tag, req.Ref) if !match { continue } diff --git a/internal/services/gateway/api/variable.go b/internal/services/gateway/api/variable.go index 1fb09e6..9a80f47 100644 --- a/internal/services/gateway/api/variable.go +++ b/internal/services/gateway/api/variable.go @@ -41,7 +41,7 @@ func createVariableResponse(v *csapitypes.Variable, secrets []*csapitypes.Secret nv.Values[i] = gwapitypes.VariableValue{ SecretName: varvalue.SecretName, SecretVar: varvalue.SecretVar, - When: fromCsWhen(varvalue.When), + When: varvalue.When, } // get matching secret for var value secret := common.GetVarValueMatchingSecret(varvalue, v.ParentPath, secrets) @@ -221,74 +221,8 @@ func fromApiVariableValues(apivalues []gwapitypes.VariableValueRequest) []cstype values[i] = cstypes.VariableValue{ SecretName: v.SecretName, SecretVar: v.SecretVar, - When: fromApiWhen(v.When), + When: v.When, } } return values } - -func fromApiWhenCondition(apiwc gwapitypes.WhenCondition) cstypes.WhenCondition { - return cstypes.WhenCondition{ - Type: cstypes.WhenConditionType(apiwc.Type), - Match: apiwc.Match, - } -} - -func fromApiWhenConditions(apiwcs *gwapitypes.WhenConditions) *cstypes.WhenConditions { - if apiwcs == nil { - return nil - } - wcs := &cstypes.WhenConditions{ - Include: make([]cstypes.WhenCondition, len(apiwcs.Include)), - Exclude: make([]cstypes.WhenCondition, len(apiwcs.Exclude)), - } - for i, include := range apiwcs.Include { - wcs.Include[i] = fromApiWhenCondition(include) - } - for i, exclude := range apiwcs.Exclude { - wcs.Exclude[i] = fromApiWhenCondition(exclude) - } - - return wcs -} - -func fromApiWhen(apiwhen *gwapitypes.When) *cstypes.When { - return &cstypes.When{ - Branch: fromApiWhenConditions(apiwhen.Branch), - Tag: fromApiWhenConditions(apiwhen.Tag), - Ref: fromApiWhenConditions(apiwhen.Ref), - } -} - -func fromCsWhenCondition(apiwc cstypes.WhenCondition) gwapitypes.WhenCondition { - return gwapitypes.WhenCondition{ - Type: gwapitypes.WhenConditionType(apiwc.Type), - Match: apiwc.Match, - } -} - -func fromCsWhenConditions(apiwcs *cstypes.WhenConditions) *gwapitypes.WhenConditions { - if apiwcs == nil { - return nil - } - wcs := &gwapitypes.WhenConditions{ - Include: make([]gwapitypes.WhenCondition, len(apiwcs.Include)), - Exclude: make([]gwapitypes.WhenCondition, len(apiwcs.Exclude)), - } - for i, include := range apiwcs.Include { - wcs.Include[i] = fromCsWhenCondition(include) - } - for i, exclude := range apiwcs.Exclude { - wcs.Exclude[i] = fromCsWhenCondition(exclude) - } - - return wcs -} - -func fromCsWhen(apiwhen *cstypes.When) *gwapitypes.When { - return &gwapitypes.When{ - Branch: fromCsWhenConditions(apiwhen.Branch), - Tag: fromCsWhenConditions(apiwhen.Tag), - Ref: fromCsWhenConditions(apiwhen.Ref), - } -} diff --git a/services/configstore/types/types.go b/services/configstore/types/types.go index 83be6ef..15a840f 100644 --- a/services/configstore/types/types.go +++ b/services/configstore/types/types.go @@ -17,9 +17,9 @@ package types import ( "encoding/json" "fmt" - "regexp" "time" + "agola.io/agola/services/types" "agola.io/agola/util" ) @@ -353,87 +353,5 @@ type VariableValue struct { SecretName string `json:"secret_name,omitempty"` SecretVar string `json:"secret_var,omitempty"` - When *When `json:"when,omitempty"` -} - -type When struct { - Branch *WhenConditions `json:"branch,omitempty"` - Tag *WhenConditions `json:"tag,omitempty"` - Ref *WhenConditions `json:"ref,omitempty"` -} - -type WhenConditions struct { - Include []WhenCondition `json:"include,omitempty"` - Exclude []WhenCondition `json:"exclude,omitempty"` -} - -type WhenConditionType string - -const ( - WhenConditionTypeSimple WhenConditionType = "simple" - WhenConditionTypeRegExp WhenConditionType = "regexp" -) - -type WhenCondition struct { - Type WhenConditionType `json:"type,omitempty"` - Match string `json:"match,omitempty"` -} - -func MatchWhen(when *When, branch, tag, ref string) bool { - include := true - if when != nil { - include = false - // test only if branch is not empty, if empty mean that we are not in a branch - if when.Branch != nil && branch != "" { - // first check includes and override with excludes - if matchCondition(when.Branch.Include, branch) { - include = true - } - if matchCondition(when.Branch.Exclude, branch) { - include = false - } - } - // test only if tag is not empty, if empty mean that we are not in a tag - if when.Tag != nil && tag != "" { - // first check includes and override with excludes - if matchCondition(when.Tag.Include, tag) { - include = true - } - if matchCondition(when.Tag.Exclude, tag) { - include = false - } - } - // we assume that ref always have a value - if when.Ref != nil { - // first check includes and override with excludes - if matchCondition(when.Ref.Include, ref) { - include = true - } - if matchCondition(when.Ref.Exclude, ref) { - include = false - } - } - } - - return include -} - -func matchCondition(conds []WhenCondition, s string) bool { - for _, cond := range conds { - switch cond.Type { - case WhenConditionTypeSimple: - if cond.Match == s { - return true - } - case WhenConditionTypeRegExp: - re, err := regexp.Compile(cond.Match) - if err != nil { - panic(err) - } - if re.MatchString(s) { - return true - } - } - } - return false + When *types.When `json:"when,omitempty"` } diff --git a/services/configstore/types/types_test.go b/services/configstore/types/types_test.go index 4bee482..bd7c9ff 100644 --- a/services/configstore/types/types_test.go +++ b/services/configstore/types/types_test.go @@ -16,12 +16,14 @@ package types import ( "testing" + + "agola.io/agola/services/types" ) func TestMatchWhen(t *testing.T) { tests := []struct { name string - when *When + when *types.When branch string tag string ref string @@ -34,10 +36,10 @@ func TestMatchWhen(t *testing.T) { }, { name: "test branch when include with empty match value, should not match", - when: &When{ - Branch: &WhenConditions{ - Include: []WhenCondition{ - {Type: WhenConditionTypeSimple}, + when: &types.When{ + Branch: &types.WhenConditions{ + Include: []types.WhenCondition{ + {Type: types.WhenConditionTypeSimple}, }, }, }, @@ -46,10 +48,10 @@ func TestMatchWhen(t *testing.T) { }, { name: "test branch when include regexp with empty match value, should match", - when: &When{ - Branch: &WhenConditions{ - Include: []WhenCondition{ - {Type: WhenConditionTypeRegExp}, + when: &types.When{ + Branch: &types.WhenConditions{ + Include: []types.WhenCondition{ + {Type: types.WhenConditionTypeRegExp}, }, }, }, @@ -58,10 +60,10 @@ func TestMatchWhen(t *testing.T) { }, { name: "test branch when include with empty match value and empty provided branch, should not match", - when: &When{ - Branch: &WhenConditions{ - Include: []WhenCondition{ - {Type: WhenConditionTypeSimple}, + when: &types.When{ + Branch: &types.WhenConditions{ + Include: []types.WhenCondition{ + {Type: types.WhenConditionTypeSimple}, }, }, }, @@ -70,10 +72,10 @@ func TestMatchWhen(t *testing.T) { }, { name: "test branch when include regexp with empty match value and empty provided branch, should not match", - when: &When{ - Branch: &WhenConditions{ - Include: []WhenCondition{ - {Type: WhenConditionTypeRegExp}, + when: &types.When{ + Branch: &types.WhenConditions{ + Include: []types.WhenCondition{ + {Type: types.WhenConditionTypeRegExp}, }, }, }, @@ -82,10 +84,10 @@ func TestMatchWhen(t *testing.T) { }, { name: "test branch when include, should match", - when: &When{ - Branch: &WhenConditions{ - Include: []WhenCondition{ - {Type: WhenConditionTypeSimple, Match: "master"}, + when: &types.When{ + Branch: &types.WhenConditions{ + Include: []types.WhenCondition{ + {Type: types.WhenConditionTypeSimple, Match: "master"}, }, }, }, @@ -94,10 +96,10 @@ func TestMatchWhen(t *testing.T) { }, { name: "test branch when include, should not match", - when: &When{ - Branch: &WhenConditions{ - Include: []WhenCondition{ - {Type: WhenConditionTypeSimple, Match: "master"}, + when: &types.When{ + Branch: &types.WhenConditions{ + Include: []types.WhenCondition{ + {Type: types.WhenConditionTypeSimple, Match: "master"}, }, }, }, @@ -106,15 +108,15 @@ func TestMatchWhen(t *testing.T) { }, { name: "test tag, ref when include, should not match since when is not nil and we have provided a branch and not a tag", - when: &When{ - Tag: &WhenConditions{ - Include: []WhenCondition{ - {Type: WhenConditionTypeSimple, Match: "master"}, + when: &types.When{ + Tag: &types.WhenConditions{ + Include: []types.WhenCondition{ + {Type: types.WhenConditionTypeSimple, Match: "master"}, }, }, - Ref: &WhenConditions{ - Include: []WhenCondition{ - {Type: WhenConditionTypeSimple, Match: "master"}, + Ref: &types.WhenConditions{ + Include: []types.WhenCondition{ + {Type: types.WhenConditionTypeSimple, Match: "master"}, }, }, }, @@ -123,10 +125,10 @@ func TestMatchWhen(t *testing.T) { }, { name: "test branch when include regexp, should match", - when: &When{ - Branch: &WhenConditions{ - Include: []WhenCondition{ - {Type: WhenConditionTypeRegExp, Match: "master"}, + when: &types.When{ + Branch: &types.WhenConditions{ + Include: []types.WhenCondition{ + {Type: types.WhenConditionTypeRegExp, Match: "master"}, }, }, }, @@ -135,10 +137,10 @@ func TestMatchWhen(t *testing.T) { }, { name: "test branch when include, should not match", - when: &When{ - Branch: &WhenConditions{ - Include: []WhenCondition{ - {Type: WhenConditionTypeRegExp, Match: "master"}, + when: &types.When{ + Branch: &types.WhenConditions{ + Include: []types.WhenCondition{ + {Type: types.WhenConditionTypeRegExp, Match: "master"}, }, }, }, @@ -147,10 +149,10 @@ func TestMatchWhen(t *testing.T) { }, { name: "test branch when include regexp, should match", - when: &When{ - Branch: &WhenConditions{ - Include: []WhenCondition{ - {Type: WhenConditionTypeRegExp, Match: "m.*"}, + when: &types.When{ + Branch: &types.WhenConditions{ + Include: []types.WhenCondition{ + {Type: types.WhenConditionTypeRegExp, Match: "m.*"}, }, }, }, @@ -159,10 +161,10 @@ func TestMatchWhen(t *testing.T) { }, { name: "test branch when include, should not match", - when: &When{ - Branch: &WhenConditions{ - Include: []WhenCondition{ - {Type: WhenConditionTypeRegExp, Match: "m.*"}, + when: &types.When{ + Branch: &types.WhenConditions{ + Include: []types.WhenCondition{ + {Type: types.WhenConditionTypeRegExp, Match: "m.*"}, }, }, }, @@ -171,13 +173,13 @@ func TestMatchWhen(t *testing.T) { }, { name: "test branch when include regexp, exclude simple, should match", - when: &When{ - Branch: &WhenConditions{ - Include: []WhenCondition{ - {Type: WhenConditionTypeRegExp, Match: "m.*"}, + when: &types.When{ + Branch: &types.WhenConditions{ + Include: []types.WhenCondition{ + {Type: types.WhenConditionTypeRegExp, Match: "m.*"}, }, - Exclude: []WhenCondition{ - {Type: WhenConditionTypeSimple, Match: "maste"}, + Exclude: []types.WhenCondition{ + {Type: types.WhenConditionTypeSimple, Match: "maste"}, }, }, }, @@ -186,13 +188,13 @@ func TestMatchWhen(t *testing.T) { }, { name: "test branch when include regexp, exclude simple, should not match", - when: &When{ - Branch: &WhenConditions{ - Include: []WhenCondition{ - {Type: WhenConditionTypeRegExp, Match: "m.*"}, + when: &types.When{ + Branch: &types.WhenConditions{ + Include: []types.WhenCondition{ + {Type: types.WhenConditionTypeRegExp, Match: "m.*"}, }, - Exclude: []WhenCondition{ - {Type: WhenConditionTypeSimple, Match: "master"}, + Exclude: []types.WhenCondition{ + {Type: types.WhenConditionTypeSimple, Match: "master"}, }, }, }, @@ -201,13 +203,13 @@ func TestMatchWhen(t *testing.T) { }, { name: "test branch when include regexp, exclude regexp, should match", - when: &When{ - Branch: &WhenConditions{ - Include: []WhenCondition{ - {Type: WhenConditionTypeRegExp, Match: "m.*"}, + when: &types.When{ + Branch: &types.WhenConditions{ + Include: []types.WhenCondition{ + {Type: types.WhenConditionTypeRegExp, Match: "m.*"}, }, - Exclude: []WhenCondition{ - {Type: WhenConditionTypeRegExp, Match: "mb.*"}, + Exclude: []types.WhenCondition{ + {Type: types.WhenConditionTypeRegExp, Match: "mb.*"}, }, }, }, @@ -216,13 +218,13 @@ func TestMatchWhen(t *testing.T) { }, { name: "test branch when include regexp, exclude regexp, should not match", - when: &When{ - Branch: &WhenConditions{ - Include: []WhenCondition{ - {Type: WhenConditionTypeRegExp, Match: "m.*"}, + when: &types.When{ + Branch: &types.WhenConditions{ + Include: []types.WhenCondition{ + {Type: types.WhenConditionTypeRegExp, Match: "m.*"}, }, - Exclude: []WhenCondition{ - {Type: WhenConditionTypeRegExp, Match: "ma.*"}, + Exclude: []types.WhenCondition{ + {Type: types.WhenConditionTypeRegExp, Match: "ma.*"}, }, }, }, @@ -231,15 +233,15 @@ func TestMatchWhen(t *testing.T) { }, { name: "test branch when multiple include regexp, multiple exclude regexp, should match", - when: &When{ - Branch: &WhenConditions{ - Include: []WhenCondition{ - {Type: WhenConditionTypeRegExp, Match: "m.*"}, - {Type: WhenConditionTypeRegExp, Match: "b.*"}, + when: &types.When{ + Branch: &types.WhenConditions{ + Include: []types.WhenCondition{ + {Type: types.WhenConditionTypeRegExp, Match: "m.*"}, + {Type: types.WhenConditionTypeRegExp, Match: "b.*"}, }, - Exclude: []WhenCondition{ - {Type: WhenConditionTypeRegExp, Match: "b.*"}, - {Type: WhenConditionTypeRegExp, Match: "c.*"}, + Exclude: []types.WhenCondition{ + {Type: types.WhenConditionTypeRegExp, Match: "b.*"}, + {Type: types.WhenConditionTypeRegExp, Match: "c.*"}, }, }, }, @@ -248,15 +250,15 @@ func TestMatchWhen(t *testing.T) { }, { name: "test branch when multiple include regexp, multiple exclude regexp, should not match", - when: &When{ - Branch: &WhenConditions{ - Include: []WhenCondition{ - {Type: WhenConditionTypeRegExp, Match: "m.*"}, - {Type: WhenConditionTypeRegExp, Match: "b.*"}, + when: &types.When{ + Branch: &types.WhenConditions{ + Include: []types.WhenCondition{ + {Type: types.WhenConditionTypeRegExp, Match: "m.*"}, + {Type: types.WhenConditionTypeRegExp, Match: "b.*"}, }, - Exclude: []WhenCondition{ - {Type: WhenConditionTypeRegExp, Match: "b.*"}, - {Type: WhenConditionTypeRegExp, Match: "ma.*"}, + Exclude: []types.WhenCondition{ + {Type: types.WhenConditionTypeRegExp, Match: "b.*"}, + {Type: types.WhenConditionTypeRegExp, Match: "ma.*"}, }, }, }, @@ -267,7 +269,7 @@ func TestMatchWhen(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - out := MatchWhen(tt.when, tt.branch, tt.tag, tt.ref) + out := types.MatchWhen(tt.when, tt.branch, tt.tag, tt.ref) if tt.out != out { t.Fatalf("expected match: %t, got: %t", tt.out, out) } diff --git a/services/gateway/api/types/variable.go b/services/gateway/api/types/variable.go index 718d5fe..aeef7a8 100644 --- a/services/gateway/api/types/variable.go +++ b/services/gateway/api/types/variable.go @@ -14,11 +14,15 @@ package types +import ( + "agola.io/agola/services/types" +) + type VariableValueRequest struct { SecretName string `json:"secret_name"` SecretVar string `json:"secret_var"` - When *When `json:"when"` + When *types.When `json:"when"` } type VariableValue struct { @@ -26,7 +30,7 @@ type VariableValue struct { SecretVar string `json:"secret_var"` MatchingSecretParentPath string `json:"matching_secret_parent_path"` - When *When `json:"when"` + When *types.When `json:"when"` } type VariableResponse struct { diff --git a/services/gateway/api/types/when.go b/services/gateway/api/types/when.go deleted file mode 100644 index a9d2c5a..0000000 --- a/services/gateway/api/types/when.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2019 Sorint.lab -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied -// See the License for the specific language governing permissions and -// limitations under the License. - -package types - -type When struct { - Branch *WhenConditions `json:"branch,omitempty"` - Tag *WhenConditions `json:"tag,omitempty"` - Ref *WhenConditions `json:"ref,omitempty"` -} - -type WhenConditions struct { - Include []WhenCondition `json:"include,omitempty"` - Exclude []WhenCondition `json:"exclude,omitempty"` -} - -type WhenConditionType string - -const ( - WhenConditionTypeSimple WhenConditionType = "simple" - WhenConditionTypeRegExp WhenConditionType = "regexp" -) - -type WhenCondition struct { - Type WhenConditionType `json:"type,omitempty"` - Match string `json:"match,omitempty"` -} diff --git a/services/types/when.go b/services/types/when.go new file mode 100644 index 0000000..4f87da9 --- /dev/null +++ b/services/types/when.go @@ -0,0 +1,101 @@ +// Copyright 2019 Sorint.lab +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "regexp" +) + +type When struct { + Branch *WhenConditions `json:"branch,omitempty"` + Tag *WhenConditions `json:"tag,omitempty"` + Ref *WhenConditions `json:"ref,omitempty"` +} + +type WhenConditions struct { + Include []WhenCondition `json:"include,omitempty"` + Exclude []WhenCondition `json:"exclude,omitempty"` +} + +type WhenConditionType string + +const ( + WhenConditionTypeSimple WhenConditionType = "simple" + WhenConditionTypeRegExp WhenConditionType = "regexp" +) + +type WhenCondition struct { + Type WhenConditionType `json:"type,omitempty"` + Match string `json:"match,omitempty"` +} + +func MatchWhen(when *When, branch, tag, ref string) bool { + include := true + if when != nil { + include = false + // test only if branch is not empty, if empty mean that we are not in a branch + if when.Branch != nil && branch != "" { + // first check includes and override with excludes + if matchCondition(when.Branch.Include, branch) { + include = true + } + if matchCondition(when.Branch.Exclude, branch) { + include = false + } + } + // test only if tag is not empty, if empty mean that we are not in a tag + if when.Tag != nil && tag != "" { + // first check includes and override with excludes + if matchCondition(when.Tag.Include, tag) { + include = true + } + if matchCondition(when.Tag.Exclude, tag) { + include = false + } + } + // we assume that ref always have a value + if when.Ref != nil { + // first check includes and override with excludes + if matchCondition(when.Ref.Include, ref) { + include = true + } + if matchCondition(when.Ref.Exclude, ref) { + include = false + } + } + } + + return include +} + +func matchCondition(conds []WhenCondition, s string) bool { + for _, cond := range conds { + switch cond.Type { + case WhenConditionTypeSimple: + if cond.Match == s { + return true + } + case WhenConditionTypeRegExp: + re, err := regexp.Compile(cond.Match) + if err != nil { + panic(err) + } + if re.MatchString(s) { + return true + } + } + } + return false +}