You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

tag.go 2.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // Copyright 2015 The Gogs Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package git
  4. import (
  5. "bytes"
  6. "sort"
  7. "strings"
  8. "code.gitea.io/gitea/modules/util"
  9. )
  10. const (
  11. beginpgp = "\n-----BEGIN PGP SIGNATURE-----\n"
  12. endpgp = "\n-----END PGP SIGNATURE-----"
  13. )
  14. // Tag represents a Git tag.
  15. type Tag struct {
  16. Name string
  17. ID ObjectID
  18. Object ObjectID // The id of this commit object
  19. Type string
  20. Tagger *Signature
  21. Message string
  22. Signature *CommitGPGSignature
  23. }
  24. // Commit return the commit of the tag reference
  25. func (tag *Tag) Commit(gitRepo *Repository) (*Commit, error) {
  26. return gitRepo.getCommit(tag.Object)
  27. }
  28. // Parse commit information from the (uncompressed) raw
  29. // data from the commit object.
  30. // \n\n separate headers from message
  31. func parseTagData(objectFormat ObjectFormat, data []byte) (*Tag, error) {
  32. tag := new(Tag)
  33. tag.ID = objectFormat.EmptyObjectID()
  34. tag.Object = objectFormat.EmptyObjectID()
  35. tag.Tagger = &Signature{}
  36. // we now have the contents of the commit object. Let's investigate...
  37. nextline := 0
  38. l:
  39. for {
  40. eol := bytes.IndexByte(data[nextline:], '\n')
  41. switch {
  42. case eol > 0:
  43. line := data[nextline : nextline+eol]
  44. spacepos := bytes.IndexByte(line, ' ')
  45. reftype := line[:spacepos]
  46. switch string(reftype) {
  47. case "object":
  48. id, err := NewIDFromString(string(line[spacepos+1:]))
  49. if err != nil {
  50. return nil, err
  51. }
  52. tag.Object = id
  53. case "type":
  54. // A commit can have one or more parents
  55. tag.Type = string(line[spacepos+1:])
  56. case "tagger":
  57. tag.Tagger = parseSignatureFromCommitLine(util.UnsafeBytesToString(line[spacepos+1:]))
  58. }
  59. nextline += eol + 1
  60. case eol == 0:
  61. tag.Message = string(data[nextline+1:])
  62. break l
  63. default:
  64. break l
  65. }
  66. }
  67. idx := strings.LastIndex(tag.Message, beginpgp)
  68. if idx > 0 {
  69. endSigIdx := strings.Index(tag.Message[idx:], endpgp)
  70. if endSigIdx > 0 {
  71. tag.Signature = &CommitGPGSignature{
  72. Signature: tag.Message[idx+1 : idx+endSigIdx+len(endpgp)],
  73. Payload: string(data[:bytes.LastIndex(data, []byte(beginpgp))+1]),
  74. }
  75. tag.Message = tag.Message[:idx+1]
  76. }
  77. }
  78. return tag, nil
  79. }
  80. type tagSorter []*Tag
  81. func (ts tagSorter) Len() int {
  82. return len([]*Tag(ts))
  83. }
  84. func (ts tagSorter) Less(i, j int) bool {
  85. return []*Tag(ts)[i].Tagger.When.After([]*Tag(ts)[j].Tagger.When)
  86. }
  87. func (ts tagSorter) Swap(i, j int) {
  88. []*Tag(ts)[i], []*Tag(ts)[j] = []*Tag(ts)[j], []*Tag(ts)[i]
  89. }
  90. // sortTagsByTime
  91. func sortTagsByTime(tags []*Tag) {
  92. sorter := tagSorter(tags)
  93. sort.Sort(sorter)
  94. }