diff --git a/src/common/tagging/external/tag_group.go b/src/common/tagging/external/tag_group.go index 207d4a4f1..bad4003ef 100644 --- a/src/common/tagging/external/tag_group.go +++ b/src/common/tagging/external/tag_group.go @@ -186,6 +186,7 @@ func (t *TagGroup) CalculateTagValue(block structure.IBlock, tag Tag) (tags.ITag retTag.Key = tag.GetKey() retTag.Value = evaluateTemplateVariable(tag.defaultValue) blockTags := append(block.GetExistingTags(), block.GetNewTags()...) + gitModifiersCounts := make(map[string]int) if len(tag.matches) > 0 { for _, matchEntry := range tag.matches { for matchValue, matchObj := range matchEntry { @@ -206,20 +207,26 @@ func (t *TagGroup) CalculateTagValue(block structure.IBlock, tag Tag) (tags.ITag break } } - case []string: - for _, blockTag := range blockTags { - blockTagKey, blockTagValue := blockTag.GetKey(), blockTag.GetValue() - if blockTagKey == tagName { - if blockTagKey == tags.GitModifiersTagKey { - for _, val := range strings.Split(blockTagValue, "/") { - if utils.InSlice(tagMatchV, val) { - foundTag = true - break + case []string, []interface{}: + if tagMatchTypeSwitch, ok := tagMatchV.([]interface{}); ok { + tagMatchStrings := make([]string, len(tagMatchTypeSwitch)) + for i := range tagMatchTypeSwitch { + tagMatchStrings[i] = tagMatchTypeSwitch[i].(string) + } + + for _, blockTag := range blockTags { + blockTagKey, blockTagValue := blockTag.GetKey(), blockTag.GetValue() + if blockTagKey == tagName { + if blockTagKey == tags.GitModifiersTagKey { + for _, val := range strings.Split(blockTagValue, "/") { + if utils.InSlice(tagMatchStrings, val) { + gitModifiersCounts[matchValue] += 1 + } } + } else if utils.InSlice(tagMatchStrings, blockTagValue) { + foundTag = true + break } - } else if utils.InSlice(tagMatchV, blockTagValue) { - foundTag = true - break } } } @@ -233,6 +240,15 @@ func (t *TagGroup) CalculateTagValue(block structure.IBlock, tag Tag) (tags.ITag } } } + if len(gitModifiersCounts) == 1 { + for k, _ := range gitModifiersCounts { + retTag.Value = evaluateTemplateVariable(k) + break + } + } else if len(gitModifiersCounts) > 1 { + // TODO use the CODEOWNERS file to resolve the conflict + logger.Info(fmt.Sprintf("Git-modifiers conflict found, fallback to default value %s\n", retTag.Value)) + } return retTag, nil } else if tag.defaultValue != "" { return retTag, nil diff --git a/src/common/tagging/external/tag_group_test.go b/src/common/tagging/external/tag_group_test.go index b00efdf0e..9de121f58 100644 --- a/src/common/tagging/external/tag_group_test.go +++ b/src/common/tagging/external/tag_group_test.go @@ -209,6 +209,89 @@ func TestExternalTagGroup(t *testing.T) { } } }) + + t.Run("test tagGroup conflicted git_modifiers", func(t *testing.T) { + confPath, _ := filepath.Abs("../../../../tests/external_tags/external_tag_group.yml") + tagGroup := TagGroup{} + tagGroup.InitTagGroup("", nil, nil) + tagGroup.InitExternalTagGroups(confPath) + block := &MockTestBlock{ + Block: structure.Block{ + FilePath: "", + IsTaggable: true, + ExitingTags: []tags.ITag{ + &tags.Tag{ + Key: "git_modifiers", + Value: "tronxd/nofar/rotemavni", + }, + &tags.Tag{ + Key: "git_repo", + Value: "yor", + }, + &tags.Tag{ + Key: "git_commit", + Value: "00193660c248483862c06e2ae96111adfcb683af", + }, + &tags.Tag{ + Key: "yor_trace", + Value: "123", + }, + }, + }, + } + err := tagGroup.CreateTagsForBlock(block) + if err != nil { + logger.Warning(err.Error()) + t.Fail() + } + for _, newTag := range block.NewTags { + if newTag.GetKey() == "team" { + assert.Equal(t, "interfaces", newTag.GetValue()) + } + } + }) + + t.Run("test tagGroup non conflicted git_modifiers", func(t *testing.T) { + confPath, _ := filepath.Abs("../../../../tests/external_tags/external_tag_group.yml") + tagGroup := TagGroup{} + tagGroup.InitTagGroup("", nil, nil) + tagGroup.InitExternalTagGroups(confPath) + block := &MockTestBlock{ + Block: structure.Block{ + FilePath: "", + IsTaggable: true, + ExitingTags: []tags.ITag{ + &tags.Tag{ + Key: "git_modifiers", + Value: "nofar", + }, + &tags.Tag{ + Key: "git_repo", + Value: "yor", + }, + &tags.Tag{ + Key: "git_commit", + Value: "00193660c248483862c06e2ae96111adfcb683af", + }, + &tags.Tag{ + Key: "yor_trace", + Value: "123", + }, + }, + }, + } + err := tagGroup.CreateTagsForBlock(block) + if err != nil { + logger.Warning(err.Error()) + t.Fail() + } + for _, newTag := range block.NewTags { + if newTag.GetKey() == "team" { + assert.Equal(t, "platform", newTag.GetValue()) + } + } + }) + } type MockTestBlock struct { diff --git a/src/common/utils/utils.go b/src/common/utils/utils.go index fc64dfcad..81002a1be 100644 --- a/src/common/utils/utils.go +++ b/src/common/utils/utils.go @@ -166,3 +166,15 @@ func GetEnv(key, fallback string) string { } return fallback } + +func MaxMapCountKey(m map[string]int) string { + var maxKey string + var maxCount = -1 + for key, count := range m { + if count > maxCount { + maxKey = key + maxCount = count + } + } + return maxKey +}