2016-11-04 01:16:01 +03:00
// Copyright 2015 The Gogs Authors. All rights reserved.
2022-11-27 21:20:29 +03:00
// SPDX-License-Identifier: MIT
2016-11-04 01:16:01 +03:00
package git
2017-01-06 04:51:15 +03:00
import (
"bytes"
"sort"
2019-06-08 17:31:11 +03:00
"strings"
2017-01-06 04:51:15 +03:00
)
2016-11-04 01:16:01 +03:00
2022-01-20 20:46:10 +03:00
const (
beginpgp = "\n-----BEGIN PGP SIGNATURE-----\n"
endpgp = "\n-----END PGP SIGNATURE-----"
)
2020-12-17 17:00:47 +03:00
2016-11-04 01:16:01 +03:00
// Tag represents a Git tag.
type Tag struct {
2020-12-17 17:00:47 +03:00
Name string
ID SHA1
Object SHA1 // The id of this commit object
Type string
Tagger * Signature
Message string
Signature * CommitGPGSignature
2016-11-04 01:16:01 +03:00
}
2016-12-22 12:30:52 +03:00
// Commit return the commit of the tag reference
2022-01-12 23:37:46 +03:00
func ( tag * Tag ) Commit ( gitRepo * Repository ) ( * Commit , error ) {
return gitRepo . getCommit ( tag . Object )
2016-11-04 01:16:01 +03:00
}
// Parse commit information from the (uncompressed) raw
// data from the commit object.
// \n\n separate headers from message
func parseTagData ( data [ ] byte ) ( * Tag , error ) {
tag := new ( Tag )
2021-05-12 08:11:42 +03:00
tag . Tagger = & Signature { }
2016-11-04 01:16:01 +03:00
// we now have the contents of the commit object. Let's investigate...
nextline := 0
l :
for {
eol := bytes . IndexByte ( data [ nextline : ] , '\n' )
switch {
case eol > 0 :
line := data [ nextline : nextline + eol ]
spacepos := bytes . IndexByte ( line , ' ' )
reftype := line [ : spacepos ]
switch string ( reftype ) {
case "object" :
id , err := NewIDFromString ( string ( line [ spacepos + 1 : ] ) )
if err != nil {
return nil , err
}
tag . Object = id
case "type" :
// A commit can have one or more parents
tag . Type = string ( line [ spacepos + 1 : ] )
case "tagger" :
sig , err := newSignatureFromCommitline ( line [ spacepos + 1 : ] )
if err != nil {
return nil , err
}
tag . Tagger = sig
}
nextline += eol + 1
case eol == 0 :
2020-12-22 23:44:25 +03:00
tag . Message = string ( data [ nextline + 1 : ] )
2016-11-04 01:16:01 +03:00
break l
default :
break l
}
}
2020-12-17 17:00:47 +03:00
idx := strings . LastIndex ( tag . Message , beginpgp )
if idx > 0 {
endSigIdx := strings . Index ( tag . Message [ idx : ] , endpgp )
if endSigIdx > 0 {
tag . Signature = & CommitGPGSignature {
Signature : tag . Message [ idx + 1 : idx + endSigIdx + len ( endpgp ) ] ,
Payload : string ( data [ : bytes . LastIndex ( data , [ ] byte ( beginpgp ) ) + 1 ] ) ,
}
tag . Message = tag . Message [ : idx + 1 ]
}
}
2016-11-04 01:16:01 +03:00
return tag , nil
}
2017-01-06 04:51:15 +03:00
type tagSorter [ ] * Tag
func ( ts tagSorter ) Len ( ) int {
return len ( [ ] * Tag ( ts ) )
}
func ( ts tagSorter ) Less ( i , j int ) bool {
return [ ] * Tag ( ts ) [ i ] . Tagger . When . After ( [ ] * Tag ( ts ) [ j ] . Tagger . When )
}
func ( ts tagSorter ) Swap ( i , j int ) {
[ ] * Tag ( ts ) [ i ] , [ ] * Tag ( ts ) [ j ] = [ ] * Tag ( ts ) [ j ] , [ ] * Tag ( ts ) [ i ]
}
// sortTagsByTime
func sortTagsByTime ( tags [ ] * Tag ) {
sorter := tagSorter ( tags )
sort . Sort ( sorter )
}