diff --git a/parser/rule_parser.go b/parser/rule_parser.go index d65bb18e..4eabba65 100644 --- a/parser/rule_parser.go +++ b/parser/rule_parser.go @@ -7,13 +7,12 @@ import ( "regexp" "strings" - "gopkg.in/yaml.v2" - "github.com/go-logr/logr" "github.com/konveyor/analyzer-lsp/engine" "github.com/konveyor/analyzer-lsp/engine/labels" "github.com/konveyor/analyzer-lsp/output/v1/konveyor" "github.com/konveyor/analyzer-lsp/provider" + "gopkg.in/yaml.v2" ) const ( @@ -555,6 +554,7 @@ func (r *RuleParser) getConditions(conditionsInterface []interface{}) ([]engine. conditions := []engine.ConditionEntry{} providers := map[string]provider.InternalProviderClient{} chainNameToIndex := map[string]int{} + asFound := []string{} for _, conditionInterface := range conditionsInterface { // get map from interface conditionMap, ok := conditionInterface.(map[interface{}]interface{}) @@ -684,7 +684,16 @@ func (r *RuleParser) getConditions(conditionsInterface []interface{}) ([]engine. } providers[providerKey] = provider } - if ce.As != "" { + if ce.From != "" && ce.As != "" && ce.From == ce.As { + return nil, nil, fmt.Errorf("condition cannot have the same value for fields 'from' and 'as'") + } else if ce.As != "" { + for _, as := range asFound { + if as == ce.As { + return nil, nil, fmt.Errorf("condition cannot have multiple 'as' fields with the same name") + } + } + asFound = append(asFound, ce.As) + index, ok := chainNameToIndex[ce.As] if !ok { //prepend diff --git a/parser/rule_parser_test.go b/parser/rule_parser_test.go index 92e73dde..c91920d0 100644 --- a/parser/rule_parser_test.go +++ b/parser/rule_parser_test.go @@ -745,6 +745,84 @@ func TestLoadRules(t *testing.T) { }, }, }, + { + Name: "no two conditions should have the same 'as' field within the same block", + testFileName: "rule-chain-same-as.yaml", + ShouldErr: true, + ErrorMessage: "condition cannot have multiple 'as' fields with the same name", + providerNameClient: map[string]provider.InternalProviderClient{ + "builtin": testProvider{ + caps: []provider.Capability{{ + Name: "filecontent", + }}, + }, + }, + ExpectedProvider: map[string]provider.InternalProviderClient{ + "builtin": testProvider{ + caps: []provider.Capability{{ + Name: "filecontent", + }}, + }, + }, + ExpectedRuleSet: map[string]engine.RuleSet{ + "konveyor-analysis": { + Rules: []engine.Rule{ + { + RuleMeta: engine.RuleMeta{ + RuleID: "chaining-rule", + Description: "", + Category: &konveyor.Potential, + }, + Perform: engine.Perform{ + Message: engine.Message{ + Text: &allGoFiles, + Links: []konveyor.Link{}, + }, + }, + }, + }, + }, + }, + }, + { + Name: "a condition should not have the same 'as' and 'from' fields", + testFileName: "rule-chain-same-as-from.yaml", + ShouldErr: true, + ErrorMessage: "condition cannot have the same value for fields 'from' and 'as'", + providerNameClient: map[string]provider.InternalProviderClient{ + "builtin": testProvider{ + caps: []provider.Capability{{ + Name: "filecontent", + }}, + }, + }, + ExpectedProvider: map[string]provider.InternalProviderClient{ + "builtin": testProvider{ + caps: []provider.Capability{{ + Name: "filecontent", + }}, + }, + }, + ExpectedRuleSet: map[string]engine.RuleSet{ + "konveyor-analysis": { + Rules: []engine.Rule{ + { + RuleMeta: engine.RuleMeta{ + RuleID: "chaining-rule", + Description: "", + Category: &konveyor.Potential, + }, + Perform: engine.Perform{ + Message: engine.Message{ + Text: &allGoFiles, + Links: []konveyor.Link{}, + }, + }, + }, + }, + }, + }, + }, } for _, tc := range testCases { diff --git a/parser/testdata/rule-chain-same-as-from.yaml b/parser/testdata/rule-chain-same-as-from.yaml new file mode 100644 index 00000000..3457d970 --- /dev/null +++ b/parser/testdata/rule-chain-same-as-from.yaml @@ -0,0 +1,8 @@ +- message: "all go files" + ruleID: chaining-rule + when: + and: + - builtin.filecontent: + pattern: spring\.datasource + as: file + from: file diff --git a/parser/testdata/rule-chain-same-as.yaml b/parser/testdata/rule-chain-same-as.yaml new file mode 100644 index 00000000..c4b1742a --- /dev/null +++ b/parser/testdata/rule-chain-same-as.yaml @@ -0,0 +1,10 @@ +- message: "all go files" + ruleID: chaining-rule + when: + and: + - builtin.filecontent: + pattern: spring\.datasource + as: file + - builtin.filecontent: + pattern: value + as: file diff --git a/parser/testdata/rule-chain.yaml b/parser/testdata/rule-chain.yaml index c62b0f2f..cb662efb 100644 --- a/parser/testdata/rule-chain.yaml +++ b/parser/testdata/rule-chain.yaml @@ -8,4 +8,4 @@ ignore: true not: true - builtin.file: "*.json" - as: go-files \ No newline at end of file + as: go-files-2 \ No newline at end of file