gogs/internal/gitutil/tag.go

96 lines
2.0 KiB
Go

// 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 (module) 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
}