2014-04-14 09:57:25 +04:00
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package models
import (
"errors"
2014-06-13 01:47:23 +04:00
"sort"
2014-04-14 09:57:25 +04:00
"strings"
"time"
2014-07-26 10:28:04 +04:00
"github.com/gogits/gogs/modules/git"
2014-04-14 09:57:25 +04:00
)
var (
ErrReleaseAlreadyExist = errors . New ( "Release already exist" )
2014-06-13 01:47:23 +04:00
ErrReleaseNotExist = errors . New ( "Release does not exist" )
2014-04-14 09:57:25 +04:00
)
// Release represents a release of repository.
type Release struct {
Id int64
RepoId int64
PublisherId int64
Publisher * User ` xorm:"-" `
TagName string
LowerTagName string
2014-06-12 17:10:39 +04:00
Target string
2014-06-13 01:47:23 +04:00
Title string
2014-06-12 17:10:39 +04:00
Sha1 string ` xorm:"VARCHAR(40)" `
2014-04-14 09:57:25 +04:00
NumCommits int
NumCommitsBehind int ` xorm:"-" `
Note string ` xorm:"TEXT" `
2014-06-13 01:47:23 +04:00
IsDraft bool ` xorm:"NOT NULL DEFAULT false" `
2014-04-14 09:57:25 +04:00
IsPrerelease bool
2014-06-13 01:47:23 +04:00
Created time . Time ` xorm:"CREATED" `
2014-04-14 09:57:25 +04:00
}
// IsReleaseExist returns true if release with given tag name already exists.
func IsReleaseExist ( repoId int64 , tagName string ) ( bool , error ) {
if len ( tagName ) == 0 {
return false , nil
}
2014-06-21 08:51:41 +04:00
return x . Get ( & Release { RepoId : repoId , LowerTagName : strings . ToLower ( tagName ) } )
2014-04-14 09:57:25 +04:00
}
2014-06-13 01:47:23 +04:00
func createTag ( gitRepo * git . Repository , rel * Release ) error {
// Only actual create when publish.
if ! rel . IsDraft {
if ! gitRepo . IsTagExist ( rel . TagName ) {
commit , err := gitRepo . GetCommitOfBranch ( rel . Target )
if err != nil {
return err
}
if err = gitRepo . CreateTag ( rel . TagName , commit . Id . String ( ) ) ; err != nil {
return err
}
} else {
commit , err := gitRepo . GetCommitOfTag ( rel . TagName )
if err != nil {
return err
}
rel . NumCommits , err = commit . CommitsCount ( )
if err != nil {
return err
}
}
}
return nil
}
2014-04-14 09:57:25 +04:00
// CreateRelease creates a new release of repository.
2014-05-10 07:14:24 +04:00
func CreateRelease ( gitRepo * git . Repository , rel * Release ) error {
2014-04-14 09:57:25 +04:00
isExist , err := IsReleaseExist ( rel . RepoId , rel . TagName )
if err != nil {
return err
} else if isExist {
return ErrReleaseAlreadyExist
}
2014-06-13 01:47:23 +04:00
if err = createTag ( gitRepo , rel ) ; err != nil {
return err
}
rel . LowerTagName = strings . ToLower ( rel . TagName )
2014-06-21 08:51:41 +04:00
_ , err = x . InsertOne ( rel )
2014-06-13 01:47:23 +04:00
return err
}
2014-06-12 17:10:39 +04:00
2014-06-13 01:47:23 +04:00
// GetRelease returns release by given ID.
func GetRelease ( repoId int64 , tagName string ) ( * Release , error ) {
isExist , err := IsReleaseExist ( repoId , tagName )
if err != nil {
return nil , err
} else if ! isExist {
return nil , ErrReleaseNotExist
}
2014-04-14 09:57:25 +04:00
2014-06-13 01:47:23 +04:00
rel := & Release { RepoId : repoId , LowerTagName : strings . ToLower ( tagName ) }
2014-06-21 08:51:41 +04:00
_ , err = x . Get ( rel )
2014-06-13 01:47:23 +04:00
return rel , err
}
// GetReleasesByRepoId returns a list of releases of repository.
func GetReleasesByRepoId ( repoId int64 ) ( rels [ ] * Release , err error ) {
2014-06-21 08:51:41 +04:00
err = x . Desc ( "created" ) . Find ( & rels , Release { RepoId : repoId } )
2014-06-13 01:47:23 +04:00
return rels , err
}
type ReleaseSorter struct {
rels [ ] * Release
}
func ( rs * ReleaseSorter ) Len ( ) int {
return len ( rs . rels )
}
func ( rs * ReleaseSorter ) Less ( i , j int ) bool {
diffNum := rs . rels [ i ] . NumCommits - rs . rels [ j ] . NumCommits
if diffNum != 0 {
return diffNum > 0
2014-04-14 09:57:25 +04:00
}
2014-06-13 01:47:23 +04:00
return rs . rels [ i ] . Created . After ( rs . rels [ j ] . Created )
}
2014-04-14 09:57:25 +04:00
2014-06-13 01:47:23 +04:00
func ( rs * ReleaseSorter ) Swap ( i , j int ) {
rs . rels [ i ] , rs . rels [ j ] = rs . rels [ j ] , rs . rels [ i ]
}
// SortReleases sorts releases by number of commits and created time.
func SortReleases ( rels [ ] * Release ) {
sorter := & ReleaseSorter { rels : rels }
sort . Sort ( sorter )
}
// UpdateRelease updates information of a release.
func UpdateRelease ( gitRepo * git . Repository , rel * Release ) ( err error ) {
if err = createTag ( gitRepo , rel ) ; err != nil {
return err
}
2014-06-21 08:51:41 +04:00
_ , err = x . Id ( rel . Id ) . AllCols ( ) . Update ( rel )
2014-04-14 09:57:25 +04:00
return err
}