aboutsummaryrefslogtreecommitdiff
path: root/internal/gitutil/tag.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/gitutil/tag.go')
-rw-r--r--internal/gitutil/tag.go95
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
+}