@ -51,6 +51,26 @@ func (r *Release) AfterSet(colName string, _ xorm.Cell) {
}
}
}
}
func ( r * Release ) loadAttributes ( e Engine ) ( err error ) {
if r . Publisher == nil {
r . Publisher , err = getUserByID ( e , r . PublisherID )
if err != nil {
if IsErrUserNotExist ( err ) {
r . PublisherID = - 1
r . Publisher = NewGhostUser ( )
} else {
return fmt . Errorf ( "getUserByID.(Publisher) [%d]: %v" , r . PublisherID , err )
}
}
}
return nil
}
func ( r * Release ) LoadAttributes ( ) error {
return r . loadAttributes ( x )
}
// IsReleaseExist returns true if release with given tag name already exists.
// IsReleaseExist returns true if release with given tag name already exists.
func IsReleaseExist ( repoID int64 , tagName string ) ( bool , error ) {
func IsReleaseExist ( repoID int64 , tagName string ) ( bool , error ) {
if len ( tagName ) == 0 {
if len ( tagName ) == 0 {
@ -60,31 +80,31 @@ func IsReleaseExist(repoID int64, tagName string) (bool, error) {
return x . Get ( & Release { RepoID : repoID , LowerTagName : strings . ToLower ( tagName ) } )
return x . Get ( & Release { RepoID : repoID , LowerTagName : strings . ToLower ( tagName ) } )
}
}
func createTag ( gitRepo * git . Repository , rel * Release ) error {
func createTag ( gitRepo * git . Repository , r * Release ) error {
// Only actual create when publish.
// Only actual create when publish.
if ! rel . IsDraft {
if ! r . IsDraft {
if ! gitRepo . IsTagExist ( rel . TagName ) {
if ! gitRepo . IsTagExist ( r . TagName ) {
commit , err := gitRepo . GetBranchCommit ( rel . Target )
commit , err := gitRepo . GetBranchCommit ( r . Target )
if err != nil {
if err != nil {
return fmt . Errorf ( "GetBranchCommit: %v" , err )
return fmt . Errorf ( "GetBranchCommit: %v" , err )
}
}
// Trim '--' prefix to prevent command line argument vulnerability.
// Trim '--' prefix to prevent command line argument vulnerability.
rel . TagName = strings . TrimPrefix ( rel . TagName , "--" )
r . TagName = strings . TrimPrefix ( r . TagName , "--" )
if err = gitRepo . CreateTag ( rel . TagName , commit . ID . String ( ) ) ; err != nil {
if err = gitRepo . CreateTag ( r . TagName , commit . ID . String ( ) ) ; err != nil {
if strings . Contains ( err . Error ( ) , "is not a valid tag name" ) {
if strings . Contains ( err . Error ( ) , "is not a valid tag name" ) {
return ErrInvalidTagName { rel . TagName }
return ErrInvalidTagName { r . TagName }
}
}
return err
return err
}
}
} else {
} else {
commit , err := gitRepo . GetTagCommit ( rel . TagName )
commit , err := gitRepo . GetTagCommit ( r . TagName )
if err != nil {
if err != nil {
return fmt . Errorf ( "GetTagCommit: %v" , err )
return fmt . Errorf ( "GetTagCommit: %v" , err )
}
}
rel . Sha1 = commit . ID . String ( )
r . Sha1 = commit . ID . String ( )
rel . NumCommits , err = commit . CommitsCount ( )
r . NumCommits , err = commit . CommitsCount ( )
if err != nil {
if err != nil {
return fmt . Errorf ( "CommitsCount: %v" , err )
return fmt . Errorf ( "CommitsCount: %v" , err )
}
}
@ -94,19 +114,19 @@ func createTag(gitRepo *git.Repository, rel *Release) error {
}
}
// CreateRelease creates a new release of repository.
// CreateRelease creates a new release of repository.
func CreateRelease ( gitRepo * git . Repository , rel * Release ) error {
func CreateRelease ( gitRepo * git . Repository , r * Release ) error {
isExist , err := IsReleaseExist ( rel . RepoID , rel . TagName )
isExist , err := IsReleaseExist ( r . RepoID , r . TagName )
if err != nil {
if err != nil {
return err
return err
} else if isExist {
} else if isExist {
return ErrReleaseAlreadyExist { rel . TagName }
return ErrReleaseAlreadyExist { r . TagName }
}
}
if err = createTag ( gitRepo , rel ) ; err != nil {
if err = createTag ( gitRepo , r ) ; err != nil {
return err
return err
}
}
rel . LowerTagName = strings . ToLower ( rel . TagName )
r . LowerTagName = strings . ToLower ( r . TagName )
_ , err = x . InsertOne ( rel )
_ , err = x . InsertOne ( r )
return err
return err
}
}
@ -119,53 +139,68 @@ func GetRelease(repoID int64, tagName string) (*Release, error) {
return nil , ErrReleaseNotExist { 0 , tagName }
return nil , ErrReleaseNotExist { 0 , tagName }
}
}
rel := & Release { RepoID : repoID , LowerTagName : strings . ToLower ( tagName ) }
r := & Release { RepoID : repoID , LowerTagName : strings . ToLower ( tagName ) }
_ , err = x . Get ( rel )
if _ , err = x . Get ( r ) ; err != nil {
return rel , err
return nil , fmt . Errorf ( "Get: %v" , err )
}
return r , r . LoadAttributes ( )
}
}
// GetReleaseByID returns release with given ID.
// GetReleaseByID returns release with given ID.
func GetReleaseByID ( id int64 ) ( * Release , error ) {
func GetReleaseByID ( id int64 ) ( * Release , error ) {
rel := new ( Release )
r := new ( Release )
has , err := x . Id ( id ) . Get ( rel )
has , err := x . Id ( id ) . Get ( r )
if err != nil {
if err != nil {
return nil , err
return nil , err
} else if ! has {
} else if ! has {
return nil , ErrReleaseNotExist { id , "" }
return nil , ErrReleaseNotExist { id , "" }
}
}
return rel , nil
return r , r . LoadAttributes ( )
}
// GetPublishedReleasesByRepoID returns a list of published releases of repository.
// If matches is not empty, only published releases in matches will be returned.
// In any case, drafts won't be returned by this function.
func GetPublishedReleasesByRepoID ( repoID int64 , matches ... string ) ( [ ] * Release , error ) {
sess := x . Where ( "repo_id = ?" , repoID ) . And ( "is_draft = ?" , false ) . Desc ( "created_unix" )
if len ( matches ) > 0 {
sess . In ( "tag_name" , matches )
}
releases := make ( [ ] * Release , 0 , 5 )
return releases , sess . Find ( & releases , new ( Release ) )
}
}
// GetReleasesByRepoID returns a list of releases of repository.
// GetDraftReleasesByRepoID returns all draft releases of repository.
func GetReleasesByRepoID ( repoID int64 ) ( rels [ ] * Release , err error ) {
func GetDraft ReleasesByRepoID ( repoID int64 ) ( [ ] * Release , error ) {
err = x . Desc ( "created_unix" ) . Find ( & rels , Release { RepoID : repoID } )
releases := make ( [ ] * Release , 0 )
return rels , err
return release s , x . Wh ere ( " repo_id = ?" , repoID ) . And ( "is_draft = ?" , true ) . Find ( & releases )
}
}
type ReleaseSorter struct {
type ReleaseSorter struct {
rels [ ] * Release
release s [ ] * Release
}
}
func ( rs * ReleaseSorter ) Len ( ) int {
func ( rs * ReleaseSorter ) Len ( ) int {
return len ( rs . rels )
return len ( rs . release s )
}
}
func ( rs * ReleaseSorter ) Less ( i , j int ) bool {
func ( rs * ReleaseSorter ) Less ( i , j int ) bool {
diffNum := rs . rels [ i ] . NumCommits - rs . rels [ j ] . NumCommits
diffNum := rs . release s [ i ] . NumCommits - rs . release s [ j ] . NumCommits
if diffNum != 0 {
if diffNum != 0 {
return diffNum > 0
return diffNum > 0
}
}
return rs . rels [ i ] . Created . After ( rs . rels [ j ] . Created )
return rs . release s [ i ] . Created . After ( rs . release s [ j ] . Created )
}
}
func ( rs * ReleaseSorter ) Swap ( i , j int ) {
func ( rs * ReleaseSorter ) Swap ( i , j int ) {
rs . rels [ i ] , rs . rels [ j ] = rs . rels [ j ] , rs . rels [ i ]
rs . release s [ i ] , rs . release s [ j ] = rs . release s [ j ] , rs . release s [ i ]
}
}
// SortReleases sorts releases by number of commits and created time.
// SortReleases sorts releases by number of commits and created time.
func SortReleases ( rels [ ] * Release ) {
func SortReleases ( rels [ ] * Release ) {
sorter := & ReleaseSorter { rels : rels }
sorter := & ReleaseSorter { release s : rels }
sort . Sort ( sorter )
sort . Sort ( sorter )
}
}