diff options
Diffstat (limited to 'internal/gitutil/tag.go')
-rw-r--r-- | internal/gitutil/tag.go | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/internal/gitutil/tag.go b/internal/gitutil/tag.go new file mode 100644 index 00000000..86efd6cd --- /dev/null +++ b/internal/gitutil/tag.go @@ -0,0 +1,95 @@ +// Copyright 2020 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package gitutil + +import ( + "github.com/pkg/errors" +) + +// TagsPage contains a list of tags and pagination information. +type TagsPage struct { + // List of tags in the current page. + Tags []string + // Whether the results include the latest tag. + HasLatest bool + // When results do not include the latest tag, an indicator of 'after' to go back. + PreviousAfter string + // Whether there are more tags in the next page. + HasNext bool +} + +func (moduler) ListTagsAfter(repoPath, after string, limit int) (*TagsPage, error) { + all, err := Module.RepoTags(repoPath) + if err != nil { + return nil, errors.Wrap(err, "get tags") + } + total := len(all) + + if limit < 0 { + limit = 0 + } + + // Returns everything when no filter and no limit + if after == "" && limit == 0 { + return &TagsPage{ + Tags: all, + HasLatest: true, + }, nil + } + + // No filter but has a limit, returns first X tags + if after == "" && limit > 0 { + endIdx := limit + if limit > total { + endIdx = total + } + return &TagsPage{ + Tags: all[:endIdx], + HasLatest: true, + HasNext: limit < total, + }, nil + } + + // Loop over all tags see if we can find the filter + previousAfter := "" + found := false + tags := make([]string, 0, len(all)) + for i := range all { + if all[i] != after { + continue + } + + found = true + if limit > 0 && i-limit >= 0 { + previousAfter = all[i-limit] + } + + // In case filter is the oldest one + if i+1 < total { + tags = all[i+1:] + } + break + } + + if !found { + tags = all + } + + // If all tags after match is equal to the limit, it reaches the oldest tag as well. + if limit == 0 || len(tags) <= limit { + return &TagsPage{ + Tags: tags, + HasLatest: !found, + PreviousAfter: previousAfter, + }, nil + } + + return &TagsPage{ + Tags: tags[:limit], + HasLatest: !found, + PreviousAfter: previousAfter, + HasNext: true, + }, nil +} |