tag.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. package gitutil
  2. import (
  3. "github.com/pkg/errors"
  4. )
  5. // TagsPage contains a list of tags and pagination information.
  6. type TagsPage struct {
  7. // List of tags in the current page.
  8. Tags []string
  9. // Whether the results include the latest tag.
  10. HasLatest bool
  11. // When results do not include the latest tag, an indicator of 'after' to go back.
  12. PreviousAfter string
  13. // Whether there are more tags in the next page.
  14. HasNext bool
  15. }
  16. func (module) ListTagsAfter(repoPath, after string, limit int) (*TagsPage, error) {
  17. all, err := Module.RepoTags(repoPath)
  18. if err != nil {
  19. return nil, errors.Wrap(err, "get tags")
  20. }
  21. total := len(all)
  22. if limit < 0 {
  23. limit = 0
  24. }
  25. // Returns everything when no filter and no limit
  26. if after == "" && limit == 0 {
  27. return &TagsPage{
  28. Tags: all,
  29. HasLatest: true,
  30. }, nil
  31. }
  32. // No filter but has a limit, returns first X tags
  33. if after == "" && limit > 0 {
  34. endIdx := limit
  35. if limit > total {
  36. endIdx = total
  37. }
  38. return &TagsPage{
  39. Tags: all[:endIdx],
  40. HasLatest: true,
  41. HasNext: limit < total,
  42. }, nil
  43. }
  44. // Loop over all tags see if we can find the filter
  45. previousAfter := ""
  46. found := false
  47. tags := make([]string, 0, len(all))
  48. for i := range all {
  49. if all[i] != after {
  50. continue
  51. }
  52. found = true
  53. if limit > 0 && i-limit >= 0 {
  54. previousAfter = all[i-limit]
  55. }
  56. // In case filter is the oldest one
  57. if i+1 < total {
  58. tags = all[i+1:]
  59. }
  60. break
  61. }
  62. if !found {
  63. tags = all
  64. }
  65. // If all tags after match is equal to the limit, it reaches the oldest tag as well.
  66. if limit == 0 || len(tags) <= limit {
  67. return &TagsPage{
  68. Tags: tags,
  69. HasLatest: !found,
  70. PreviousAfter: previousAfter,
  71. }, nil
  72. }
  73. return &TagsPage{
  74. Tags: tags[:limit],
  75. HasLatest: !found,
  76. PreviousAfter: previousAfter,
  77. HasNext: true,
  78. }, nil
  79. }