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.4KB

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