2014-04-02 20:43:31 +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 repo
import (
2014-07-26 10:28:04 +04:00
"github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/auth"
2014-04-14 09:57:25 +04:00
"github.com/gogits/gogs/modules/base"
2014-07-26 10:28:04 +04:00
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware"
2014-04-02 20:43:31 +04:00
)
2014-06-23 07:11:12 +04:00
const (
RELEASES base . TplName = "repo/release/list"
RELEASE_NEW base . TplName = "repo/release/new"
RELEASE_EDIT base . TplName = "repo/release/edit"
)
2014-07-26 10:28:04 +04:00
func Releases ( ctx * middleware . Context ) {
2014-12-11 00:37:54 +03:00
ctx . Data [ "Title" ] = ctx . Tr ( "repo.release.releases" )
2014-07-26 10:28:04 +04:00
ctx . Data [ "IsRepoToolbarReleases" ] = true
ctx . Data [ "IsRepoReleaseNew" ] = false
2014-11-07 06:06:41 +03:00
2014-07-26 10:28:04 +04:00
rawTags , err := ctx . Repo . GitRepo . GetTags ( )
if err != nil {
2014-11-07 06:06:41 +03:00
ctx . Handle ( 500 , "GetTags" , err )
2014-07-26 10:28:04 +04:00
return
}
rels , err := models . GetReleasesByRepoId ( ctx . Repo . Repository . Id )
if err != nil {
2014-11-07 06:06:41 +03:00
ctx . Handle ( 500 , "GetReleasesByRepoId" , err )
return
}
2014-07-26 10:28:04 +04:00
// Temproray cache commits count of used branches to speed up.
countCache := make ( map [ string ] int )
tags := make ( [ ] * models . Release , len ( rawTags ) )
for i , rawTag := range rawTags {
2014-12-11 00:37:54 +03:00
for j , rel := range rels {
if rel == nil || ( rel . IsDraft && ! ctx . Repo . IsOwner ) {
2014-07-26 10:28:04 +04:00
continue
}
if rel . TagName == rawTag {
rel . Publisher , err = models . GetUserById ( rel . PublisherId )
if err != nil {
ctx . Handle ( 500 , "GetUserById" , err )
return
}
2014-12-11 00:37:54 +03:00
// FIXME: duplicated code.
2014-07-26 10:28:04 +04:00
// Get corresponding target if it's not the current branch.
if ctx . Repo . BranchName != rel . Target {
// Get count if not exists.
if _ , ok := countCache [ rel . Target ] ; ! ok {
2014-11-07 06:06:41 +03:00
commit , err := ctx . Repo . GitRepo . GetCommitOfBranch ( ctx . Repo . BranchName )
2014-07-26 10:28:04 +04:00
if err != nil {
2014-11-07 06:06:41 +03:00
ctx . Handle ( 500 , "GetCommitOfBranch" , err )
2014-07-26 10:28:04 +04:00
return
}
2014-11-07 06:06:41 +03:00
countCache [ ctx . Repo . BranchName ] , err = commit . CommitsCount ( )
2014-07-26 10:28:04 +04:00
if err != nil {
ctx . Handle ( 500 , "CommitsCount2" , err )
return
}
}
2014-11-07 06:06:41 +03:00
rel . NumCommitsBehind = countCache [ ctx . Repo . BranchName ] - rel . NumCommits
2014-07-26 10:28:04 +04:00
} else {
2014-12-11 00:37:54 +03:00
rel . NumCommitsBehind = ctx . Repo . CommitsCount - rel . NumCommits
2014-07-26 10:28:04 +04:00
}
rel . Note = base . RenderMarkdownString ( rel . Note , ctx . Repo . RepoLink )
tags [ i ] = rel
2014-12-11 00:37:54 +03:00
rels [ j ] = nil // Mark as used.
2014-07-26 10:28:04 +04:00
break
}
}
if tags [ i ] == nil {
commit , err := ctx . Repo . GitRepo . GetCommitOfTag ( rawTag )
if err != nil {
ctx . Handle ( 500 , "GetCommitOfTag2" , err )
return
}
tags [ i ] = & models . Release {
Title : rawTag ,
TagName : rawTag ,
Sha1 : commit . Id . String ( ) ,
}
tags [ i ] . NumCommits , err = ctx . Repo . GitRepo . CommitsCount ( commit . Id . String ( ) )
if err != nil {
ctx . Handle ( 500 , "CommitsCount" , err )
return
}
2014-12-11 00:37:54 +03:00
tags [ i ] . NumCommitsBehind = ctx . Repo . CommitsCount - tags [ i ] . NumCommits
}
}
for _ , rel := range rels {
if rel == nil {
continue
}
rel . Publisher , err = models . GetUserById ( rel . PublisherId )
if err != nil {
ctx . Handle ( 500 , "GetUserById" , err )
return
}
// FIXME: duplicated code.
// Get corresponding target if it's not the current branch.
if ctx . Repo . BranchName != rel . Target {
// Get count if not exists.
if _ , ok := countCache [ rel . Target ] ; ! ok {
commit , err := ctx . Repo . GitRepo . GetCommitOfBranch ( ctx . Repo . BranchName )
if err != nil {
ctx . Handle ( 500 , "GetCommitOfBranch" , err )
return
}
countCache [ ctx . Repo . BranchName ] , err = commit . CommitsCount ( )
if err != nil {
ctx . Handle ( 500 , "CommitsCount2" , err )
return
}
}
rel . NumCommitsBehind = countCache [ ctx . Repo . BranchName ] - rel . NumCommits
} else {
rel . NumCommitsBehind = ctx . Repo . CommitsCount - rel . NumCommits
2014-07-26 10:28:04 +04:00
}
2014-12-11 00:37:54 +03:00
rel . Note = base . RenderMarkdownString ( rel . Note , ctx . Repo . RepoLink )
tags = append ( tags , rel )
2014-07-26 10:28:04 +04:00
}
models . SortReleases ( tags )
ctx . Data [ "Releases" ] = tags
ctx . HTML ( 200 , RELEASES )
}
func NewRelease ( ctx * middleware . Context ) {
if ! ctx . Repo . IsOwner {
ctx . Handle ( 403 , "release.ReleasesNew" , nil )
return
}
2014-12-11 00:37:54 +03:00
ctx . Data [ "Title" ] = ctx . Tr ( "repo.release.new_release" )
ctx . Data [ "tag_target" ] = ctx . Repo . Repository . DefaultBranch
2014-07-26 10:28:04 +04:00
ctx . Data [ "IsRepoToolbarReleases" ] = true
ctx . Data [ "IsRepoReleaseNew" ] = true
ctx . HTML ( 200 , RELEASE_NEW )
}
func NewReleasePost ( ctx * middleware . Context , form auth . NewReleaseForm ) {
if ! ctx . Repo . IsOwner {
ctx . Handle ( 403 , "release.ReleasesNew" , nil )
return
}
2014-12-11 00:37:54 +03:00
ctx . Data [ "Title" ] = ctx . Tr ( "repo.release.new_release" )
2014-07-26 10:28:04 +04:00
ctx . Data [ "IsRepoToolbarReleases" ] = true
ctx . Data [ "IsRepoReleaseNew" ] = true
if ctx . HasError ( ) {
ctx . HTML ( 200 , RELEASE_NEW )
return
}
2014-11-07 06:06:41 +03:00
if ! ctx . Repo . GitRepo . IsBranchExist ( form . Target ) {
ctx . RenderWithErr ( ctx . Tr ( "form.target_branch_not_exist" ) , RELEASE_NEW , & form )
return
}
commit , err := ctx . Repo . GitRepo . GetCommitOfBranch ( form . Target )
2014-07-26 10:28:04 +04:00
if err != nil {
2014-11-07 06:06:41 +03:00
ctx . Handle ( 500 , "GetCommitOfBranch" , err )
2014-07-26 10:28:04 +04:00
return
}
2014-11-07 06:06:41 +03:00
commitsCount , err := commit . CommitsCount ( )
if err != nil {
ctx . Handle ( 500 , "CommitsCount" , err )
2014-07-26 10:28:04 +04:00
return
}
rel := & models . Release {
RepoId : ctx . Repo . Repository . Id ,
PublisherId : ctx . User . Id ,
Title : form . Title ,
TagName : form . TagName ,
Target : form . Target ,
2014-11-07 06:06:41 +03:00
Sha1 : commit . Id . String ( ) ,
2014-07-26 10:28:04 +04:00
NumCommits : commitsCount ,
Note : form . Content ,
IsDraft : len ( form . Draft ) > 0 ,
IsPrerelease : form . Prerelease ,
}
if err = models . CreateRelease ( ctx . Repo . GitRepo , rel ) ; err != nil {
if err == models . ErrReleaseAlreadyExist {
2014-12-11 00:37:54 +03:00
ctx . RenderWithErr ( ctx . Tr ( "repo.release.tag_name_already_exist" ) , RELEASE_NEW , & form )
2014-07-26 10:28:04 +04:00
} else {
2014-12-11 00:37:54 +03:00
ctx . Handle ( 500 , "CreateRelease" , err )
2014-07-26 10:28:04 +04:00
}
return
}
log . Trace ( "%s Release created: %s/%s:%s" , ctx . Req . RequestURI , ctx . User . LowerName , ctx . Repo . Repository . Name , form . TagName )
ctx . Redirect ( ctx . Repo . RepoLink + "/releases" )
}
func EditRelease ( ctx * middleware . Context ) {
if ! ctx . Repo . IsOwner {
ctx . Handle ( 403 , "release.ReleasesEdit" , nil )
return
}
tagName := ctx . Params ( ":tagname" )
rel , err := models . GetRelease ( ctx . Repo . Repository . Id , tagName )
if err != nil {
if err == models . ErrReleaseNotExist {
2014-12-11 00:37:54 +03:00
ctx . Handle ( 404 , "GetRelease" , err )
2014-07-26 10:28:04 +04:00
} else {
2014-12-11 00:37:54 +03:00
ctx . Handle ( 500 , "GetRelease" , err )
2014-07-26 10:28:04 +04:00
}
return
}
ctx . Data [ "Release" ] = rel
2014-12-11 00:37:54 +03:00
ctx . Data [ "Title" ] = ctx . Tr ( "repo.release.edit_release" )
2014-07-26 10:28:04 +04:00
ctx . Data [ "IsRepoToolbarReleases" ] = true
ctx . HTML ( 200 , RELEASE_EDIT )
}
func EditReleasePost ( ctx * middleware . Context , form auth . EditReleaseForm ) {
if ! ctx . Repo . IsOwner {
ctx . Handle ( 403 , "release.EditReleasePost" , nil )
return
}
tagName := ctx . Params ( ":tagname" )
rel , err := models . GetRelease ( ctx . Repo . Repository . Id , tagName )
if err != nil {
if err == models . ErrReleaseNotExist {
2014-12-11 00:37:54 +03:00
ctx . Handle ( 404 , "GetRelease" , err )
2014-07-26 10:28:04 +04:00
} else {
2014-12-11 00:37:54 +03:00
ctx . Handle ( 500 , "GetRelease" , err )
2014-07-26 10:28:04 +04:00
}
return
}
ctx . Data [ "Release" ] = rel
if ctx . HasError ( ) {
ctx . HTML ( 200 , RELEASE_EDIT )
return
}
2014-12-11 00:37:54 +03:00
ctx . Data [ "Title" ] = ctx . Tr ( "repo.release.edit_release" )
2014-07-26 10:28:04 +04:00
ctx . Data [ "IsRepoToolbarReleases" ] = true
rel . Title = form . Title
rel . Note = form . Content
rel . IsDraft = len ( form . Draft ) > 0
rel . IsPrerelease = form . Prerelease
if err = models . UpdateRelease ( ctx . Repo . GitRepo , rel ) ; err != nil {
2014-12-11 00:37:54 +03:00
ctx . Handle ( 500 , "UpdateRelease" , err )
2014-07-26 10:28:04 +04:00
return
}
ctx . Redirect ( ctx . Repo . RepoLink + "/releases" )
}