From 9e8ffa14cb980221c35bb1431e97849a51e09dd7 Mon Sep 17 00:00:00 2001 From: Unknwon Date: Thu, 16 Mar 2017 17:33:04 -0400 Subject: [PATCH] webhook: add file status to push event (#3897) --- gogs.go | 2 +- models/action.go | 26 +++++++-- models/pull.go | 21 +++++--- routers/repo/webhook.go | 11 +++- templates/.VERSION | 2 +- vendor/github.com/gogits/git-module/commit.go | 54 +++++++++++++++++++ vendor/github.com/gogits/git-module/git.go | 2 +- .../github.com/gogits/go-gogs-client/gogs.go | 2 +- .../gogits/go-gogs-client/repo_hook.go | 7 ++- vendor/vendor.json | 12 ++--- 10 files changed, 116 insertions(+), 23 deletions(-) diff --git a/gogs.go b/gogs.go index 281ad982..04029391 100644 --- a/gogs.go +++ b/gogs.go @@ -16,7 +16,7 @@ import ( "github.com/gogits/gogs/modules/setting" ) -const APP_VER = "0.10.18.0313" +const APP_VER = "0.10.19.0316" func init() { setting.AppVer = APP_VER diff --git a/models/action.go b/models/action.go index b2ddf12f..1613df5e 100644 --- a/models/action.go +++ b/models/action.go @@ -251,20 +251,30 @@ func NewPushCommits() *PushCommits { } } -func (pc *PushCommits) ToApiPayloadCommits(repoLink string) []*api.PayloadCommit { +func (pc *PushCommits) ToApiPayloadCommits(repoPath, repoLink string) ([]*api.PayloadCommit, error) { commits := make([]*api.PayloadCommit, len(pc.Commits)) for i, commit := range pc.Commits { authorUsername := "" author, err := GetUserByEmail(commit.AuthorEmail) if err == nil { authorUsername = author.Name + } else if !errors.IsUserNotExist(err) { + return nil, fmt.Errorf("GetUserByEmail: %v", err) } + committerUsername := "" committer, err := GetUserByEmail(commit.CommitterEmail) if err == nil { - // TODO: check errors other than email not found. committerUsername = committer.Name + } else if !errors.IsUserNotExist(err) { + return nil, fmt.Errorf("GetUserByEmail: %v", err) } + + fileStatus, err := git.GetCommitFileStatus(repoPath, commit.Sha1) + if err != nil { + return nil, fmt.Errorf("FileStatus [commit_sha1: %s]: %v", commit.Sha1, err) + } + commits[i] = &api.PayloadCommit{ ID: commit.Sha1, Message: commit.Message, @@ -279,10 +289,13 @@ func (pc *PushCommits) ToApiPayloadCommits(repoLink string) []*api.PayloadCommit Email: commit.CommitterEmail, UserName: committerUsername, }, + Added: fileStatus.Added, + Removed: fileStatus.Removed, + Modified: fileStatus.Modified, Timestamp: commit.Timestamp, } } - return commits + return commits, nil } // AvatarLink tries to match user in database with e-mail @@ -546,12 +559,17 @@ func CommitRepoAction(opts CommitRepoActionOptions) error { } } + commits, err := opts.Commits.ToApiPayloadCommits(repo.RepoPath(), repo.HTMLURL()) + if err != nil { + return fmt.Errorf("ToApiPayloadCommits: %v", err) + } + if err = PrepareWebhooks(repo, HOOK_EVENT_PUSH, &api.PushPayload{ Ref: opts.RefFullName, Before: opts.OldCommitID, After: opts.NewCommitID, CompareURL: compareURL, - Commits: opts.Commits.ToApiPayloadCommits(repo.HTMLURL()), + Commits: commits, Repo: apiRepo, Pusher: apiPusher, Sender: apiPusher, diff --git a/models/pull.go b/models/pull.go index f36a0e18..454a2a18 100644 --- a/models/pull.go +++ b/models/pull.go @@ -278,12 +278,12 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository) (err error } if err = MergePullRequestAction(doer, pr.Issue.Repo, pr.Issue); err != nil { - log.Error(4, "MergePullRequestAction [%d]: %v", pr.ID, err) + log.Error(2, "MergePullRequestAction [%d]: %v", pr.ID, err) } // Reload pull request information. if err = pr.LoadAttributes(); err != nil { - log.Error(4, "LoadAttributes: %v", err) + log.Error(2, "LoadAttributes: %v", err) return nil } if err = PrepareWebhooks(pr.Issue.Repo, HOOK_EVENT_PULL_REQUEST, &api.PullRequestPayload{ @@ -293,13 +293,13 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository) (err error Repository: pr.Issue.Repo.APIFormat(nil), Sender: doer.APIFormat(), }); err != nil { - log.Error(4, "PrepareWebhooks: %v", err) + log.Error(2, "PrepareWebhooks: %v", err) return nil } l, err := headGitRepo.CommitsBetweenIDs(pr.MergedCommitID, pr.MergeBase) if err != nil { - log.Error(4, "CommitsBetweenIDs: %v", err) + log.Error(2, "CommitsBetweenIDs: %v", err) return nil } @@ -309,23 +309,30 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository) (err error // to avoid strange diff commits produced. mergeCommit, err := baseGitRepo.GetBranchCommit(pr.BaseBranch) if err != nil { - log.Error(4, "GetBranchCommit: %v", err) + log.Error(2, "GetBranchCommit: %v", err) return nil } l.PushFront(mergeCommit) + commits, err := ListToPushCommits(l).ToApiPayloadCommits(pr.BaseRepo.RepoPath(), pr.BaseRepo.HTMLURL()) + if err != nil { + log.Error(2, "ToApiPayloadCommits: %v", err) + return nil + } + p := &api.PushPayload{ Ref: git.BRANCH_PREFIX + pr.BaseBranch, Before: pr.MergeBase, After: pr.MergedCommitID, CompareURL: setting.AppUrl + pr.BaseRepo.ComposeCompareURL(pr.MergeBase, pr.MergedCommitID), - Commits: ListToPushCommits(l).ToApiPayloadCommits(pr.BaseRepo.HTMLURL()), + Commits: commits, Repo: pr.BaseRepo.APIFormat(nil), Pusher: pr.HeadRepo.MustOwner().APIFormat(), Sender: doer.APIFormat(), } if err = PrepareWebhooks(pr.BaseRepo, HOOK_EVENT_PUSH, p); err != nil { - return fmt.Errorf("PrepareWebhooks: %v", err) + log.Error(2, "PrepareWebhooks: %v", err) + return nil } return nil } diff --git a/routers/repo/webhook.go b/routers/repo/webhook.go index 73bd8786..ce142295 100644 --- a/routers/repo/webhook.go +++ b/routers/repo/webhook.go @@ -484,6 +484,13 @@ func TestWebhook(ctx *context.Context) { } } + fileStatus, err := commit.FileStatus() + if err != nil { + ctx.Flash.Error("FileStatus: " + err.Error()) + ctx.Status(500) + return + } + apiUser := ctx.User.APIFormat() p := &api.PushPayload{ Ref: git.BRANCH_PREFIX + ctx.Repo.Repository.DefaultBranch, @@ -504,6 +511,9 @@ func TestWebhook(ctx *context.Context) { Email: commit.Committer.Email, UserName: committerUsername, }, + Added: fileStatus.Added, + Removed: fileStatus.Removed, + Modified: fileStatus.Modified, }, }, Repo: ctx.Repo.Repository.APIFormat(nil), @@ -514,7 +524,6 @@ func TestWebhook(ctx *context.Context) { ctx.Flash.Error("TestWebhook: " + err.Error()) ctx.Status(500) } else { - go models.HookQueue.Add(ctx.Repo.Repository.ID) ctx.Flash.Info(ctx.Tr("repo.settings.webhook.test_delivery_success")) ctx.Status(200) } diff --git a/templates/.VERSION b/templates/.VERSION index 63677d3a..c4d428b7 100644 --- a/templates/.VERSION +++ b/templates/.VERSION @@ -1 +1 @@ -0.10.18.0313 \ No newline at end of file +0.10.19.0316 \ No newline at end of file diff --git a/vendor/github.com/gogits/git-module/commit.go b/vendor/github.com/gogits/git-module/commit.go index b68a6b97..6cc6b5fd 100644 --- a/vendor/github.com/gogits/git-module/commit.go +++ b/vendor/github.com/gogits/git-module/commit.go @@ -6,8 +6,10 @@ package git import ( "bufio" + "bytes" "container/list" "fmt" + "io" "net/http" "strconv" "strings" @@ -252,3 +254,55 @@ func (c *Commit) GetSubModule(entryname string) (*SubModule, error) { } return nil, nil } + +// CommitFileStatus represents status of files in a commit. +type CommitFileStatus struct { + Added []string + Removed []string + Modified []string +} + +func NewCommitFileStatus() *CommitFileStatus { + return &CommitFileStatus{ + []string{}, []string{}, []string{}, + } +} + +// GetCommitFileStatus returns file status of commit in given repository. +func GetCommitFileStatus(repoPath, commitID string) (*CommitFileStatus, error) { + stdout, w := io.Pipe() + defer stdout.Close() + + stderr := new(bytes.Buffer) + + fileStatus := NewCommitFileStatus() + go func() { + scanner := bufio.NewScanner(stdout) + for scanner.Scan() { + fields := strings.Fields(scanner.Text()) + if len(fields) < 2 { + continue + } + + switch fields[0][0] { + case 'A': + fileStatus.Added = append(fileStatus.Added, fields[1]) + case 'D': + fileStatus.Removed = append(fileStatus.Removed, fields[1]) + case 'M': + fileStatus.Modified = append(fileStatus.Modified, fields[1]) + } + } + }() + + if err := NewCommand("log", "-1", "--name-status", "--pretty=format:''", commitID).RunInDirPipeline(repoPath, w, stderr); err != nil { + return nil, concatenateError(err, stderr.String()) + } + + return fileStatus, nil +} + +// FileStatus returns file status of commit. +func (c *Commit) FileStatus() (*CommitFileStatus, error) { + return GetCommitFileStatus(c.repo.Path, c.ID.String()) +} diff --git a/vendor/github.com/gogits/git-module/git.go b/vendor/github.com/gogits/git-module/git.go index 28426acd..2ba3b1a5 100644 --- a/vendor/github.com/gogits/git-module/git.go +++ b/vendor/github.com/gogits/git-module/git.go @@ -10,7 +10,7 @@ import ( "time" ) -const _VERSION = "0.5.0" +const _VERSION = "0.5.1" func Version() string { return _VERSION diff --git a/vendor/github.com/gogits/go-gogs-client/gogs.go b/vendor/github.com/gogits/go-gogs-client/gogs.go index e691dd64..2869e6c2 100644 --- a/vendor/github.com/gogits/go-gogs-client/gogs.go +++ b/vendor/github.com/gogits/go-gogs-client/gogs.go @@ -14,7 +14,7 @@ import ( ) func Version() string { - return "0.12.10" + return "0.12.11" } // Client represents a Gogs API client. diff --git a/vendor/github.com/gogits/go-gogs-client/repo_hook.go b/vendor/github.com/gogits/go-gogs-client/repo_hook.go index 1ea75468..3d06b9fc 100644 --- a/vendor/github.com/gogits/go-gogs-client/repo_hook.go +++ b/vendor/github.com/gogits/go-gogs-client/repo_hook.go @@ -86,7 +86,12 @@ type PayloadCommit struct { URL string `json:"url"` Author *PayloadUser `json:"author"` Committer *PayloadUser `json:"committer"` - Timestamp time.Time `json:"timestamp"` + + Added []string `json:"added"` + Removed []string `json:"removed"` + Modified []string `json:"modified"` + + Timestamp time.Time `json:"timestamp"` } var ( diff --git a/vendor/vendor.json b/vendor/vendor.json index 331a5826..0ba62ca1 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -159,16 +159,16 @@ "revisionTime": "2016-08-10T03:50:02Z" }, { - "checksumSHA1": "W2THy51ey2gNT9PbBS98GG4o3fQ=", + "checksumSHA1": "zkRQagaPCQPU9o+8kGZYIQoysu4=", "path": "github.com/gogits/git-module", - "revision": "b6678775980f8bcd0bbf400a88c176210c8a22e6", - "revisionTime": "2017-03-12T06:43:33Z" + "revision": "f9c2e671705cc0bb8281a932efe9371404c956b0", + "revisionTime": "2017-03-16T21:31:27Z" }, { - "checksumSHA1": "1p1/OSDPORWbSBCD791BbGh2vVc=", + "checksumSHA1": "D2kVXl0QpIw6t3891Sl7IM9wL+w=", "path": "github.com/gogits/go-gogs-client", - "revision": "08824b5ad7408bc38f2b9287c94be2f059c9966a", - "revisionTime": "2017-03-11T23:40:19Z" + "revision": "6422399bb531fae9500b29b5d8bfe23aa0ce6beb", + "revisionTime": "2017-03-16T21:31:09Z" }, { "checksumSHA1": "p4yoFWgDiTfpu1JYgh26t6+VDTk=",