tag.go 2.0 KB

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