in internal/cssc/cssc.go [184:284]
func ApplyFilterAndGetFilteredList(ctx context.Context, acrClient api.AcrCLIClientInterface, filter Filter) ([]FilteredRepository, []FilteredRepository, error) {
var filteredRepos []FilteredRepository
var artifactsNotFound []FilteredRepository
// Default is incremental tag regex, only if tag convention is specified as floating, use floating tag regex
patchTagRegex := incrementalTagRegex
if filter.TagConvention == Floating {
patchTagRegex = floatingTagRegex
}
uniqueFilteredRepos := make(map[string]bool)
for _, filterRepo := range filter.Repositories {
// Create a tag map for each repository, where the key will be the base tag and the value will be the list of tags matching the tag convention from the filter
tagMap := make(map[string][]string)
if filterRepo.Enabled != nil && !*filterRepo.Enabled {
continue
}
if filterRepo.Repository == "" || filterRepo.Tags == nil || len(filterRepo.Tags) == 0 {
continue
}
tagList, err := tag.ListTags(ctx, acrClient, filterRepo.Repository)
if err != nil {
var listTagsErr *tag.ListTagsError
if errors.As(err, &listTagsErr) {
for _, tag := range filterRepo.Tags {
artifactsNotFound = append(artifactsNotFound, FilteredRepository{
Repository: filterRepo.Repository,
Tag: tag,
})
}
continue
}
return nil, nil, errors.Wrap(err, "Some unexpected error occurred while listing tags for repository-"+filterRepo.Repository)
}
if len(filterRepo.Tags) == 1 && filterRepo.Tags[0] == "*" { // If the repo has * as tags defined in the filter, then all tags are considered for that repo
for _, tag := range tagList {
matches := patchTagRegex.FindStringSubmatch(*tag.Name)
if matches != nil {
baseTag := matches[1]
tagMap[baseTag] = append(tagMap[baseTag], *tag.Name)
} else if !endsWithIncrementalOrFloatingPattern(*tag.Name) {
tagMap[*tag.Name] = append(tagMap[*tag.Name], *tag.Name)
}
}
} else {
for _, ftag := range filterRepo.Tags { // If the repo has specific tags defined in the filter, then only those tags are considered
// If tag from filter is not found in the tag list obtained for the repository, then add it to artifactsNotFound and continue with the next tag
if !containsTag(tagList, ftag) {
artifactsNotFound = append(artifactsNotFound, FilteredRepository{
Repository: filterRepo.Repository,
Tag: ftag,
})
continue
}
// This is needed to evaluate all versions of patch tags when original tag is specified in the filter
var re *regexp.Regexp
if filter.TagConvention == Floating {
re = regexp.MustCompile(`^` + ftag + `(-patched\d*)?$`)
} else {
re = regexp.MustCompile(`^` + ftag + `(-[1-9]\d{0,2})?$`)
}
for _, tag := range tagList {
if re.MatchString(*tag.Name) {
matches := patchTagRegex.FindStringSubmatch(*tag.Name)
if matches != nil {
baseTag := matches[1]
tagMap[baseTag] = append(tagMap[baseTag], *tag.Name)
} else if !endsWithIncrementalOrFloatingPattern(*tag.Name) {
tagMap[*tag.Name] = append(tagMap[*tag.Name], *tag.Name)
}
}
}
}
}
// Iterate over the tagMap to generate the FilteredRepository list
for baseTag, tags := range tagMap {
sort.Slice(tags, func(i, j int) bool {
return compareTags(tags[i], tags[j])
})
latestTag := tags[len(tags)-1]
if latestTag == baseTag {
latestTag = "N/A"
}
key := fmt.Sprintf("%s-%s-%s", filterRepo.Repository, baseTag, latestTag)
if !uniqueFilteredRepos[key] {
uniqueFilteredRepos[key] = true
filteredRepos = append(filteredRepos, FilteredRepository{
Repository: filterRepo.Repository,
Tag: baseTag,
PatchTag: latestTag,
})
}
}
}
return filteredRepos, artifactsNotFound, nil
}