2014-04-27 11:05:13 +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.
2014-04-11 06:27:13 +04:00
package models
import (
"container/list"
2014-06-24 00:22:34 +04:00
"fmt"
2014-04-11 06:27:13 +04:00
"os/exec"
"strings"
2016-02-18 06:47:06 +03:00
git "github.com/gogits/git-module"
2015-12-10 04:46:05 +03:00
2016-11-03 15:29:56 +03:00
"github.com/go-gitea/gitea/modules/log"
2014-04-11 06:27:13 +04:00
)
2014-06-28 19:56:41 +04:00
type UpdateTask struct {
2015-10-24 10:36:47 +03:00
ID int64 ` xorm:"pk autoincr" `
UUID string ` xorm:"index" `
2014-06-28 19:56:41 +04:00
RefName string
2015-10-24 10:36:47 +03:00
OldCommitID string
NewCommitID string
2014-06-28 19:56:41 +04:00
}
func AddUpdateTask ( task * UpdateTask ) error {
_ , err := x . Insert ( task )
return err
}
2015-11-05 05:57:10 +03:00
// GetUpdateTaskByUUID returns update task by given UUID.
2015-10-24 10:36:47 +03:00
func GetUpdateTaskByUUID ( uuid string ) ( * UpdateTask , error ) {
2014-06-28 19:56:41 +04:00
task := & UpdateTask {
2015-10-24 10:36:47 +03:00
UUID : uuid ,
2014-06-28 19:56:41 +04:00
}
2015-10-24 10:36:47 +03:00
has , err := x . Get ( task )
2014-06-28 19:56:41 +04:00
if err != nil {
return nil , err
2015-10-24 10:36:47 +03:00
} else if ! has {
2015-11-05 05:57:10 +03:00
return nil , ErrUpdateTaskNotExist { uuid }
2014-06-28 19:56:41 +04:00
}
2015-10-24 10:36:47 +03:00
return task , nil
2014-06-28 19:56:41 +04:00
}
2015-10-24 10:36:47 +03:00
func DeleteUpdateTaskByUUID ( uuid string ) error {
_ , err := x . Delete ( & UpdateTask { UUID : uuid } )
2014-06-28 19:56:41 +04:00
return err
}
2016-08-12 12:29:29 +03:00
// CommitToPushCommit transforms a git.Commit to PushCommit type.
func CommitToPushCommit ( commit * git . Commit ) * PushCommit {
return & PushCommit {
Sha1 : commit . ID . String ( ) ,
Message : commit . Message ( ) ,
AuthorEmail : commit . Author . Email ,
AuthorName : commit . Author . Name ,
CommitterEmail : commit . Committer . Email ,
CommitterName : commit . Committer . Name ,
Timestamp : commit . Author . When ,
}
}
2015-12-10 04:46:05 +03:00
func ListToPushCommits ( l * list . List ) * PushCommits {
commits := make ( [ ] * PushCommit , 0 )
var actEmail string
for e := l . Front ( ) ; e != nil ; e = e . Next ( ) {
commit := e . Value . ( * git . Commit )
if actEmail == "" {
actEmail = commit . Committer . Email
}
2016-08-12 12:29:29 +03:00
commits = append ( commits , CommitToPushCommit ( commit ) )
2015-12-10 04:46:05 +03:00
}
return & PushCommits { l . Len ( ) , commits , "" , nil }
}
2016-02-18 06:47:06 +03:00
type PushUpdateOptions struct {
PusherID int64
PusherName string
RepoUserName string
RepoName string
2016-08-17 09:06:38 +03:00
RefFullName string
OldCommitID string
NewCommitID string
2016-02-18 06:47:06 +03:00
}
// PushUpdate must be called for any push actions in order to
// generates necessary push action history feeds.
func PushUpdate ( opts PushUpdateOptions ) ( err error ) {
2016-08-17 09:06:38 +03:00
isNewRef := opts . OldCommitID == git . EMPTY_SHA
isDelRef := opts . NewCommitID == git . EMPTY_SHA
2016-02-18 06:47:06 +03:00
if isNewRef && isDelRef {
2016-08-17 09:06:38 +03:00
return fmt . Errorf ( "Old and new revisions are both %s" , git . EMPTY_SHA )
2014-04-11 06:27:13 +04:00
}
2016-02-18 06:47:06 +03:00
repoPath := RepoPath ( opts . RepoUserName , opts . RepoName )
2014-04-11 06:27:13 +04:00
gitUpdate := exec . Command ( "git" , "update-server-info" )
2016-02-18 06:47:06 +03:00
gitUpdate . Dir = repoPath
if err = gitUpdate . Run ( ) ; err != nil {
return fmt . Errorf ( "Fail to call 'git update-server-info': %v" , err )
}
2014-04-11 06:27:13 +04:00
2016-02-18 06:47:06 +03:00
if isDelRef {
log . GitLogger . Info ( "Reference '%s' has been deleted from '%s/%s' by %d" ,
2016-08-17 09:06:38 +03:00
opts . RefFullName , opts . RepoUserName , opts . RepoName , opts . PusherName )
2014-06-24 00:22:34 +04:00
return nil
2014-05-03 07:12:15 +04:00
}
2016-02-18 06:47:06 +03:00
gitRepo , err := git . OpenRepository ( repoPath )
2014-04-11 06:27:13 +04:00
if err != nil {
2016-02-18 06:47:06 +03:00
return fmt . Errorf ( "OpenRepository: %v" , err )
2014-04-11 06:27:13 +04:00
}
2016-08-17 09:06:38 +03:00
owner , err := GetUserByName ( opts . RepoUserName )
2014-05-03 09:37:49 +04:00
if err != nil {
2016-02-18 06:47:06 +03:00
return fmt . Errorf ( "GetUserByName: %v" , err )
2014-05-03 09:37:49 +04:00
}
2016-08-17 09:06:38 +03:00
repo , err := GetRepositoryByName ( owner . ID , opts . RepoName )
2014-04-11 06:27:13 +04:00
if err != nil {
2016-02-18 06:47:06 +03:00
return fmt . Errorf ( "GetRepositoryByName: %v" , err )
2014-04-11 06:27:13 +04:00
}
2014-07-26 08:24:27 +04:00
// Push tags.
2016-08-17 09:06:38 +03:00
if strings . HasPrefix ( opts . RefFullName , git . TAG_PREFIX ) {
if err := CommitRepoAction ( CommitRepoActionOptions {
PusherName : opts . PusherName ,
RepoOwnerID : owner . ID ,
RepoName : repo . Name ,
RefFullName : opts . RefFullName ,
OldCommitID : opts . OldCommitID ,
NewCommitID : opts . NewCommitID ,
Commits : & PushCommits { } ,
} ) ; err != nil {
2016-02-18 06:47:06 +03:00
return fmt . Errorf ( "CommitRepoAction (tag): %v" , err )
2014-06-28 10:55:33 +04:00
}
2016-08-17 09:06:38 +03:00
return nil
2014-06-28 10:55:33 +04:00
}
2016-02-18 06:47:06 +03:00
newCommit , err := gitRepo . GetCommit ( opts . NewCommitID )
2014-06-28 19:56:41 +04:00
if err != nil {
2016-02-18 06:47:06 +03:00
return fmt . Errorf ( "gitRepo.GetCommit: %v" , err )
2014-06-28 19:56:41 +04:00
}
2014-10-11 05:40:51 +04:00
// Push new branch.
2014-06-28 19:56:41 +04:00
var l * list . List
2016-02-18 06:47:06 +03:00
if isNewRef {
2015-12-11 00:27:47 +03:00
l , err = newCommit . CommitsBeforeLimit ( 10 )
2014-06-28 19:56:41 +04:00
if err != nil {
2016-02-18 06:47:06 +03:00
return fmt . Errorf ( "newCommit.CommitsBeforeLimit: %v" , err )
2014-06-28 19:56:41 +04:00
}
} else {
2016-02-18 06:47:06 +03:00
l , err = newCommit . CommitsBeforeUntil ( opts . OldCommitID )
2014-06-28 19:56:41 +04:00
if err != nil {
2016-02-18 06:47:06 +03:00
return fmt . Errorf ( "newCommit.CommitsBeforeUntil: %v" , err )
2014-06-28 19:56:41 +04:00
}
}
2016-08-17 09:06:38 +03:00
if err := CommitRepoAction ( CommitRepoActionOptions {
PusherName : opts . PusherName ,
RepoOwnerID : owner . ID ,
RepoName : repo . Name ,
RefFullName : opts . RefFullName ,
OldCommitID : opts . OldCommitID ,
NewCommitID : opts . NewCommitID ,
Commits : ListToPushCommits ( l ) ,
} ) ; err != nil {
2016-02-18 06:47:06 +03:00
return fmt . Errorf ( "CommitRepoAction (branch): %v" , err )
2014-04-11 06:27:13 +04:00
}
2014-06-24 00:22:34 +04:00
return nil
2014-04-11 06:27:13 +04:00
}